Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 16, 2011, 4:08:23 PM (13 years ago)
Author:
willis
Message:

moved formationflight to Masterable.* from Artificialcontroller, added formationflight to HumanPlayer

Location:
code/branches/formation/src/orxonox/controllers
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • code/branches/formation/src/orxonox/controllers/ArtificialController.cc

    r8908 r8939  
    3030
    3131#include <vector>
    32 #include <climits>
     32
    3333
    3434#include "util/Math.h"
     
    4141#include "gametypes/TeamDeathmatch.h"
    4242#include "gametypes/Dynamicmatch.h"
    43 #include "controllers/WaypointPatrolController.h"
    44 #include "controllers/NewHumanController.h"
    45 #include "controllers/DroneController.h"
     43
    4644
    4745namespace orxonox
    4846{
    49     SetConsoleCommand("ArtificialController", "formationflight",  &ArtificialController::formationflight);
    50     SetConsoleCommand("ArtificialController", "masteraction",     &ArtificialController::masteraction);
    51     SetConsoleCommand("ArtificialController", "followme",         &ArtificialController::followme);
    52     SetConsoleCommand("ArtificialController", "passivebehaviour", &ArtificialController::passivebehaviour);
    53     SetConsoleCommand("ArtificialController", "formationsize",    &ArtificialController::formationsize);
    5447
    55     static const unsigned int STANDARD_MAX_FORMATION_SIZE = 7;
    56     static const int RADIUS_TO_SEARCH_FOR_MASTERS = 5000;
    57     static const int FORMATION_LENGTH =  130;
    58     static const int FORMATION_WIDTH =  110;
    59     static const int FREEDOM_COUNT = 4; //seconds the slaves in a formation will be set free when master attacks an enemy
    60     static const float SPEED_MASTER = 0.6f;
    61     static const float ROTATEFACTOR_MASTER = 0.2f;
    62     static const float SPEED_FREE = 0.8f;
    63     static const float ROTATEFACTOR_FREE = 0.8f;
    64 
    65 
    66     ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator)
     48    ArtificialController::ArtificialController(BaseObject* creator) : Masterable(creator)
    6749    {
    68         RegisterObject(ArtificialController);
    69 
    70         this->target_ = 0;
    71         this->formationFlight_ = false;
    72         this->passive_ = false;
    73         this->maxFormationSize_ = STANDARD_MAX_FORMATION_SIZE;
    74         this->myMaster_ = 0;
    75         this->freedomCount_ = 0;
    76         this->team_ = -1;
    77         this->state_ = FREE;
    78         this->specificMasterAction_ = NONE;
    79         this->specificMasterActionHoldCount_  = 0;
    80         this->bShooting_ = false;
    81         this->bHasTargetPosition_ = false;
    82         this->bHasTargetOrientation_=false;
    83         this->speedCounter_ = 0.2f;
    84         this->targetPosition_ = Vector3::ZERO;
    85 
    86         this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this));
     50         
    8751    }
    8852
    8953    ArtificialController::~ArtificialController()
    9054    {
    91         if (this->isInitialized())
    92         {
    93             this->removeFromFormation();
    94 
    95             for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it; ++it)
    96             {
    97                 if (*it != this)
    98                 {
    99                     if (it->myMaster_ == this)
    100                     {
    101                         orxout(internal_error) << this << " is still master in " << (*it) << endl;
    102                         it->myMaster_ = 0;
    103                     }
    104 
    105                     while (true)
    106                     {
    107                         std::vector<ArtificialController*>::iterator it2 = std::find(it->slaves_.begin(), it->slaves_.end(), this);
    108                         if (it2 != it->slaves_.end())
    109                         {
    110                             orxout(internal_error) << this << " is still slave in " << (*it) << endl;
    111                             it->slaves_.erase(it2);
    112                         }
    113                         else
    114                             break;
    115                     }
    116                 }
    117             }
    118         }
     55       
    11956    }
    12057
    121     void ArtificialController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
    122     {
    123         SUPER(ArtificialController, XMLPort, xmlelement, mode);
    124 
    125         XMLPortParam(ArtificialController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(-1);
    126         XMLPortParam(ArtificialController, "formationFlight", setFormationFlight, getFormationFlight, xmlelement, mode).defaultValues(false);
    127         XMLPortParam(ArtificialController, "formationSize", setFormationSize, getFormationSize, xmlelement, mode).defaultValues(STANDARD_MAX_FORMATION_SIZE);
    128         XMLPortParam(ArtificialController, "passive", setPassive, getPassive, xmlelement, mode).defaultValues(false);
    129     }
    130 
    131 // Documentation only here to get a faster overview for creating a useful documentation...
    132 
    133     /**
    134         @brief Activates / deactivates formationflight behaviour
    135         @param form activate formflight if form is true
    136     */
    137     void ArtificialController::formationflight(const bool form)
    138     {
    139         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
    140         {
    141             Controller* controller = 0;
    142 
    143             if (it->getController())
    144                 controller = it->getController();
    145             else if (it->getXMLController())
    146                 controller = it->getXMLController();
    147 
    148             if (!controller)
    149                 continue;
    150 
    151             ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
    152 
    153             if (aiController)
    154             {
    155                 aiController->formationFlight_ = form;
    156                 if (!form)
    157                 {
    158                     aiController->removeFromFormation();
    159                 }
    160             }
    161         }
    162     }
    163 
    164     /**
    165         @brief Get all masters to do a "specific master action"
    166         @param action which action to perform (integer, so it can be called with a console command (tmp solution))
    167     */
    168     void ArtificialController::masteraction(const int action)
    169     {
    170         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
    171         {
    172             Controller* controller = 0;
    173 
    174             if (it->getController())
    175                 controller = it->getController();
    176             else if (it->getXMLController())
    177                 controller = it->getXMLController();
    178 
    179             if (!controller)
    180                 continue;
    181 
    182             ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
    183 
    184             if(aiController && aiController->state_ == MASTER)
    185             {
    186                 if (action == 1)
    187                     aiController->spinInit();
    188                 if (action == 2)
    189                     aiController->turn180Init();
    190             }
    191         }
    192     }
    193 
    194     /**
    195         @brief A human player gets followed by its nearest master. Initiated by console command, so far intended for demonstration puproses (possible future pickup).
    196     */
    197     void ArtificialController::followme()
    198     {
    199 
    200         Pawn *humanPawn = NULL;
    201         NewHumanController *currentHumanController = NULL;
    202         std::vector<ArtificialController*> allMasters;
    203 
    204         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
    205         {
    206             Controller* controller = 0;
    207 
    208             if (it->getController())
    209                 controller = it->getController();
    210             else if (it->getXMLController())
    211                 controller = it->getXMLController();
    212 
    213             if (!controller)
    214                 continue;
    215 
    216             currentHumanController = orxonox_cast<NewHumanController*>(controller);
    217 
    218             if(currentHumanController) humanPawn = *it;
    219 
    220             ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
    221 
    222             if(aiController && aiController->state_ == MASTER)
    223                 allMasters.push_back(aiController);
    224 
    225         }
    226 
    227         if((humanPawn != NULL) && (allMasters.size() != 0))
    228         {
    229                 float posHuman = humanPawn->getPosition().length();
    230                 float distance = 0.0f;
    231                 float minDistance = FLT_MAX;
    232                 int index = 0;
    233                 int i = 0;
    234 
    235                 for(std::vector<ArtificialController*>::iterator it = allMasters.begin(); it != allMasters.end(); it++, i++)
    236                     {
    237                         if (!ArtificialController::sameTeam((*it)->getControllableEntity(), humanPawn, (*it)->getGametype())) continue;
    238                         distance = posHuman - (*it)->getControllableEntity()->getPosition().length();
    239                         if(distance < minDistance) index = i;
    240                     }
    241                 allMasters[index]->followInit(humanPawn);
    242             }
    243 
    244     }
    245 
    246     /**
    247         @brief Sets shooting behaviour of pawns.
    248         @param passive if true, bots won't shoot.
    249     */
    250     void ArtificialController::passivebehaviour(const bool passive)
    251     {
    252         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
    253         {
    254             Controller* controller = 0;
    255 
    256             if (it->getController())
    257                 controller = it->getController();
    258             else if (it->getXMLController())
    259                 controller = it->getXMLController();
    260 
    261             if (!controller)
    262                 continue;
    263 
    264             ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
    265 
    266             if(aiController)
    267             {
    268                 aiController->passive_ = passive;
    269             }
    270         }
    271     }
    272 
    273 
    274     /**
    275         @brief Sets maximal formation size
    276         @param size maximal formation size.
    277     */
    278     void ArtificialController::formationsize(const int size)
    279     {
    280         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
    281         {
    282             Controller* controller = 0;
    283 
    284             if (it->getController())
    285                 controller = it->getController();
    286             else if (it->getXMLController())
    287                 controller = it->getXMLController();
    288 
    289             if (!controller)
    290                 continue;
    291 
    292             ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
    293 
    294             if(aiController)
    295             {
    296                 aiController->maxFormationSize_ = size;
    297             }
    298         }
    299     }
    30058
    30159    /**
     
    30866    }
    30967
    310     void ArtificialController::removeFromFormation()
    311     {
    312         if (this->state_ == SLAVE || this->myMaster_) // slaves can also be temporary free, so check if myMaster_ is set
    313             this->unregisterSlave();
    314         else if (this->state_ == MASTER)
    315             this->setNewMasterWithinFormation();
    316     }
    317 
    318     void ArtificialController::moveToPosition(const Vector3& target)
    319     {
    320         if (!this->getControllableEntity())
    321             return;
    322 
    323         // Slave uses special movement if its master is in FOLLOW mode
    324         if(this->state_ == SLAVE && this->myMaster_ && this->myMaster_->specificMasterAction_ == FOLLOW)
    325         {
    326 //             this->followForSlaves(target);
    327 //             return;
    328         }
    329 
    330         Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
    331         float distance = (target - this->getControllableEntity()->getPosition()).length();
    332 
    333 
    334         if(this->state_ == FREE)
    335         {
    336             if (this->target_ || distance > 10)
    337             {
    338                 // Multiply with ROTATEFACTOR_FREE to make them a bit slower
    339                 this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x);
    340                 this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y);
    341             }
    342 
    343             if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
    344             {
    345               this->getControllableEntity()->moveFrontBack(-0.05f); // They don't brake with full power to give the player a chance
    346             } else this->getControllableEntity()->moveFrontBack(SPEED_FREE);
    347         }
    348 
    349 
    350 
    351         if(this->state_ == MASTER)
    352         {
    353             if (this->target_ || distance > 10)
    354             {
    355                 this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x);
    356                 this->getControllableEntity()->rotatePitch(ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y);
    357             }
    358 
    359             if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
    360             {
    361                 this->getControllableEntity()->moveFrontBack(-0.05f);
    362             } else this->getControllableEntity()->moveFrontBack(SPEED_MASTER);
    363         }
    364 
    365 
    366 
    367         if(this->state_ == SLAVE)
    368         {
    369 
    370            this->getControllableEntity()->rotateYaw(-2.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x);
    371            this->getControllableEntity()->rotatePitch(2.0f * ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y);
    372 
    373             if (distance < 300)
    374             {
    375                  if (bHasTargetOrientation_)
    376                     {
    377                         copyTargetOrientation();
    378                     }
    379                 if (distance < 40)
    380                 {
    381                     this->getControllableEntity()->moveFrontBack(0.8f*SPEED_MASTER);
    382                    
    383                 } else this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER);
    384 
    385             } else {
    386                 this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER + distance/300.0f);
    387             }
    388         }
    389 
    390         if (distance < 10)
    391         {
    392             this->positionReached();
    393             bHasTargetOrientation_=false;
    394         }
    395     }
    396 
    397     void ArtificialController::moveToTargetPosition()
    398     {
    399         this->moveToPosition(this->targetPosition_);
    400     }
    401 
    402     void ArtificialController::copyOrientation(const Quaternion& orient)
    403     {
    404         //roll angle in radian, difference between master and slave
    405         float diff=orient.getRoll().valueRadians()-(this->getControllableEntity()->getOrientation().getRoll().valueRadians());
    406         if ((diff<math::twoPi && diff>math::pi) || diff>(math::pi)*3)
    407         {
    408                 diff=diff-math::twoPi;
    409         }
    410         this->getControllableEntity()->rotateRoll(1.0f*ROTATEFACTOR_MASTER*diff);
    411     }
    412 
    413     void ArtificialController::copyTargetOrientation()
    414     {
    415         if (bHasTargetOrientation_)
    416         {
    417                 copyOrientation(targetOrientation_);
    418         }
    419     }
    420 
    421     /**
    422         @brief Unregisters a slave from its master. Initiated by a slave.
    423     */
    424     void ArtificialController::unregisterSlave()
    425     {
    426         if (this->myMaster_)
    427         {
    428             std::vector<ArtificialController*>::iterator it = std::find(this->myMaster_->slaves_.begin(), this->myMaster_->slaves_.end(), this);
    429             if (it != this->myMaster_->slaves_.end())
    430                 this->myMaster_->slaves_.erase(it);
    431         }
    432 
    433         this->myMaster_ = 0;
    434         this->state_ = FREE;
    435     }
    436 
    437     void ArtificialController::searchNewMaster()
    438     {
    439 
    440         if (!this->getControllableEntity())
    441             return;
    442 
    443         this->targetPosition_ = this->getControllableEntity()->getPosition();
    444         this->forgetTarget();
    445         int teamSize = 0;
    446         //go through all pawns
    447         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
    448         {
    449             //same team?
    450             if (!ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
    451                 continue;
    452 
    453             //has it an ArtificialController?
    454             Controller* controller = 0;
    455 
    456             if (it->getController())
    457                 controller = it->getController();
    458             else if (it->getXMLController())
    459                 controller = it->getXMLController();
    460 
    461             if (!controller)
    462                 continue;
    463 
    464             //is pawn oneself?
    465             if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity())
    466                 continue;
    467 
    468             teamSize++;
    469 
    470             ArtificialController *newMaster = orxonox_cast<ArtificialController*>(controller);
    471 
    472             //is it a master?
    473             if (!newMaster || newMaster->state_ != MASTER)
    474                 continue;
    475 
    476             float distance = (it->getPosition() - this->getControllableEntity()->getPosition()).length();
    477 
    478             // is pawn in range?
    479             if (distance < RADIUS_TO_SEARCH_FOR_MASTERS)
    480             {
    481                 if(newMaster->slaves_.size() > this->maxFormationSize_) continue;
    482 
    483                 for(std::vector<ArtificialController*>::iterator itSlave = this->slaves_.begin(); itSlave != this->slaves_.end(); itSlave++)
    484                 {
    485                     (*itSlave)->myMaster_ = newMaster;
    486                     newMaster->slaves_.push_back(*itSlave);
    487                 }
    488                 this->slaves_.clear();
    489                 this->state_ = SLAVE;
    490 
    491                 this->myMaster_ = newMaster;
    492                 newMaster->slaves_.push_back(this);
    493 
    494                 break;
    495             }
    496         }
    497 
    498         if (this->state_ != SLAVE  && teamSize != 0)
    499         {
    500             this->state_ = MASTER;
    501             this->myMaster_ = 0;
    502         }
    503     }
    504  /**
    505         @brief Commands the slaves of a master into a formation. Sufficiently fast not to be called within tick. Initiated by a master.
    506     */
    507 
    508 void ArtificialController::commandSlaves()
    509     {
    510         if(this->state_ != MASTER) return;
    511 
    512         Quaternion orient = this->getControllableEntity()->getOrientation();
    513         Vector3 dest = this->getControllableEntity()->getPosition();
    514 
    515         // 1 slave: follow
    516         if (this->slaves_.size() == 1)
    517         {
    518             dest += 4*orient*WorldEntity::BACK;
    519             this->slaves_.front()->setTargetPosition(dest);
    520         }
    521         else
    522         // formation:
    523         {
    524             dest += 1.0f*orient*WorldEntity::BACK;
    525             Vector3 pos = Vector3::ZERO;
    526             bool left=true;
    527             int i = 1;
    528            
    529             for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
    530             {
    531                 pos = Vector3::ZERO;
    532                 if (left)
    533                 {
    534                     pos+=dest+i*FORMATION_WIDTH*(orient*WorldEntity::LEFT);
    535                 } else
    536                 {
    537                     pos+=dest+i*FORMATION_WIDTH*(orient*WorldEntity::RIGHT);
    538                     i++;
    539                     dest+=FORMATION_LENGTH*(orient*WorldEntity::BACK);
    540                 }               
    541                 (*it)->setTargetOrientation(orient);
    542                 (*it)->setTargetPosition(pos);
    543                 left=!left;
    544             }
    545         }
    546     }
    547 
    548     /**
    549         @brief Sets a new master within the formation. Called by a master.
    550     */
    551     void ArtificialController::setNewMasterWithinFormation()
    552     {
    553         if(this->state_ != MASTER) return;
    554 
    555         if (!this->slaves_.empty())
    556         {
    557             ArtificialController *newMaster = this->slaves_.back();
    558             this->slaves_.pop_back();
    559 
    560             newMaster->state_ = MASTER;
    561             newMaster->slaves_ = this->slaves_;
    562             newMaster->myMaster_ = 0;
    563 
    564             for(std::vector<ArtificialController*>::iterator it = newMaster->slaves_.begin(); it != newMaster->slaves_.end(); it++)
    565             {
    566                 (*it)->myMaster_ = newMaster;
    567             }
    568         }
    569 
    570         this->slaves_.clear();
    571         this->specificMasterAction_ = NONE;
    572         this->state_ = FREE;
    573     }
    574 
    575     /**
    576         @brief Frees all slaves form a master. Initiated by a master.
    577     */
    578     void ArtificialController::freeSlaves()
    579     {
    580         if(this->state_ != MASTER) return;
    581 
    582         for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
    583         {
    584             (*it)->state_ = FREE;
    585             (*it)->myMaster_ = 0;
    586         }
    587         this->slaves_.clear();
    588     }
    589 
    590     /**
    591         @brief Master sets its slaves free for @ref FREEDOM_COUNT seconds.
    592     */
    593     void ArtificialController::forceFreeSlaves()
    594     {
    595         if(this->state_ != MASTER) return;
    596 
    597         for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
    598         {
    599             (*it)->state_ = FREE;
    600             (*it)->forceFreedom();
    601             (*it)->targetPosition_ = this->targetPosition_;
    602             (*it)->bShooting_ = true;
    603 //             (*it)->getControllableEntity()->fire(0);// fire once for fun
    604         }
    605     }
    606 
    607     void ArtificialController::loseMasterState()
    608     {
    609         this->freeSlaves();
    610         this->state_ = FREE;
    611     }
    612 
    613 
    614     void ArtificialController::forceFreedom()
    615     {
    616         this->freedomCount_ = FREEDOM_COUNT;
    617     }
    618 
    619     /**
    620         @brief Checks wether caller has been forced free, decrements time to stay forced free.
    621         @return true if forced free.
    622     */
    623     bool ArtificialController::forcedFree()
    624     {
    625         if(this->freedomCount_ > 0)
    626         {
    627             this->freedomCount_--;
    628             return true;
    629         } else return false;
    630     }
    631 
    632     /**
    633         @brief Used to continue a "specific master action" for a certain time and resuming normal behaviour after.
    634     */
    635     void ArtificialController::specificMasterActionHold()
    636     {
    637         if(this->state_ != MASTER) return;
    638 
    639         if (specificMasterActionHoldCount_ == 0)
    640          {
    641             this->specificMasterAction_ = NONE;
    642             this->searchNewTarget();
    643          }
    644         else specificMasterActionHoldCount_--;
    645     }
    646 
    647     /**
    648         @brief Master initializes a 180 degree turn. Leads to a "specific master action".
    649     */
    650     void ArtificialController::turn180Init()
    651     {
    652         if(this->state_ != MASTER) return;
    653 
    654         Quaternion orient = this->getControllableEntity()->getOrientation();
    655 
    656         this->setTargetPosition(this->getControllableEntity()->getPosition() + 1000.0f*orient*WorldEntity::BACK);
    657 
    658         this->specificMasterActionHoldCount_ = 4;
    659 
    660         this->specificMasterAction_ = TURN180;
    661     }
    662 
    663     /**
    664         @brief Execute the 180 degree turn. Called within tick.
    665     */
    666     void ArtificialController::turn180()
    667     {
    668             Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->targetPosition_);
    669 
    670             this->getControllableEntity()->rotateYaw(-2.0f * sgn(coord.x) * coord.x*coord.x);
    671             this->getControllableEntity()->rotatePitch(2.0f * sgn(coord.y) * coord.y*coord.y);
    672 
    673             this->getControllableEntity()->moveFrontBack(SPEED_MASTER);
    674     }
    675 
    676     /**
    677         @brief Master initializes a spin around its looking direction axis. Leads to a "specific master action".
    678     */
    679     void ArtificialController::spinInit()
    680     {
    681         if(this->state_ != MASTER) return;
    682         this->specificMasterAction_ = SPIN;
    683         this->specificMasterActionHoldCount_ = 10;
    684     }
    685 
    686     /**
    687         @brief Execute the spin. Called within tick.
    688     */
    689     void ArtificialController::spin()
    690     {
    691             this->moveToTargetPosition();
    692             this->getControllableEntity()->rotateRoll(0.8f);
    693     }
    694 
    695     /**
    696         @brief Master begins to follow a pawn. Is a "specific master action".
    697         @param pawn pawn to follow.
    698         @param always follows pawn forever if true (false if omitted).
    699         @param secondsToFollow seconds to follow the pawn if always is false. Will follow pawn 100 seconds if omitted (set in header).
    700     */
    701     void ArtificialController::followInit(Pawn* pawn, const bool always, const int secondsToFollow)
    702     {
    703         if (pawn == NULL || this->state_ != MASTER)
    704             return;
    705         this->specificMasterAction_  =  FOLLOW;
    706 
    707         this->setTarget(pawn);
    708         if (!always)
    709             this->specificMasterActionHoldCount_ = secondsToFollow;
    710         else
    711             this->specificMasterActionHoldCount_ = INT_MAX; //for now...
    712 
    713     }
    714 
    715 
    716     /**
    717         @brief Master begins to follow a randomly chosen human player of the same team. Is a "specific master action".
    718     */
    719     void ArtificialController::followRandomHumanInit()
    720     {
    721 
    722         Pawn *humanPawn = NULL;
    723         NewHumanController *currentHumanController = NULL;
    724 
    725         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
    726         {
    727             if (!it->getController())
    728                 continue;
    729 
    730             currentHumanController = orxonox_cast<NewHumanController*>(it->getController());
    731             if(currentHumanController)
    732             {
    733                 if (!ArtificialController::sameTeam(this->getControllableEntity(), *it, this->getGametype())) continue;
    734                 humanPawn = *it;
    735                 break;
    736             }
    737         }
    738 
    739         if((humanPawn != NULL))
    740                 this->followInit(humanPawn);
    741     }
    742 
    743     /**
    744         @brief Master follows target with adjusted speed. Called within tick.
    745     */
    746     void ArtificialController::follow()
    747     {
    748         if (this->target_)
    749             this->moveToPosition(this->target_->getPosition());
    750         else
    751             this->specificMasterActionHoldCount_ = 0;
    752 /*
    753         if (!this->getControllableEntity())
    754             return;
    755 
    756         float distance = (this->target_->getPosition() - this->getControllableEntity()->getPosition()).length();
    757 
    758         Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->target_->getPosition());
    759 
    760 
    761         this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
    762         this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
    763 
    764         float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->target_->getVelocity().squaredLength();
    765 
    766 orxout() << "~follow distance: " << distance << "SpeedCounter: " << this->speedCounter_ << "~speedDiv: " << speedDiv << endl;
    767         if (distance < 800)
    768         {
    769             if (distance < 200)
    770             {
    771                 this->speedCounter_ -= 0.5f;
    772                 if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f;
    773                 this->getControllableEntity()->moveFrontBack(speedCounter_);
    774             } else {
    775                 if(speedDiv < 0)
    776                     this->speedCounter_ +=  0.01f;
    777                 else
    778                     this->speedCounter_ -= 0.05f;
    779                 this->getControllableEntity()->moveFrontBack(speedCounter_);
    780             }
    781 
    782         } else {
    783             this->speedCounter_ += 0.05f;
    784             this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f);
    785         }
    786 //         if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0;
    787 
    788 */
    789     }
    790 
    791 
    792     /**
    793         @brief Slave moving behaviour when master is following a pawn, gets redirected from moveToPosition(const Vector3& target)). Called within tick.
    794     */
    795     void ArtificialController::followForSlaves(const Vector3& target)
    796     {
    797 
    798 /*
    799         if (!this->getControllableEntity() && !this->myMaster_ && this->myMaster_->state_ != FOLLOW && !this->myMaster_->target_)
    800             return;
    801 
    802         float distance = (target - this->getControllableEntity()->getPosition()).length();
    803 
    804         Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
    805 
    806 
    807         this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
    808         this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
    809 
    810 
    811         float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->myMaster_->target_->getVelocity().squaredLength();
    812 
    813 
    814          if (distance < 800)
    815         {
    816             if (distance < 200)
    817             {
    818                 this->speedCounter_ -= 5.0f;
    819                 if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f;
    820                 this->getControllableEntity()->moveFrontBack(speedCounter_);
    821             } else {
    822                 if(speedDiv < 0)
    823                     this->speedCounter_ +=  0.01f;
    824                 else
    825                     this->speedCounter_ -= 0.05f;
    826                 this->getControllableEntity()->moveFrontBack(speedCounter_);
    827             }
    828 
    829         } else {
    830             this->speedCounter_ += 0.05f;
    831             this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f);
    832         }
    833 //         if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0;
    834 */
    835     }
    836 
    837 
    838     void ArtificialController::setTargetPosition(const Vector3& target)
    839     {
    840         this->targetPosition_ = target;
    841         this->bHasTargetPosition_ = true;
    842     }
    843 
    844     void ArtificialController::searchRandomTargetPosition()
    845     {
    846         this->targetPosition_ = Vector3(rnd(-2000,2000), rnd(-2000,2000), rnd(-2000,2000));
    847         this->bHasTargetPosition_ = true;
    848     }
    849 
    850     void ArtificialController::setTargetOrientation(const Quaternion& orient)
    851     {
    852         this->targetOrientation_=orient;       
    853         this->bHasTargetOrientation_=true;
    854     }
    855 
    856     void ArtificialController::setTargetOrientation(Pawn* target)
    857     {
    858         if (target)
    859             setTargetOrientation(target->getOrientation());
    860     }
    861 
    862     void ArtificialController::setTarget(Pawn* target)
    863     {
    864         this->target_ = target;
    865 
    866         if (target)
    867             this->targetPosition_ = target->getPosition();
    868     }
    869 
    870     void ArtificialController::searchNewTarget()
    871     {
    872         if (!this->getControllableEntity())
    873             return;
    874 
    875         this->targetPosition_ = this->getControllableEntity()->getPosition();
    876         this->forgetTarget();
    877 
    878         for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
    879         {
    880             if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
    881                 continue;
    882 
    883             /* So AI won't choose invisible Spaceships as target */
    884             if (!it->getRadarVisibility())
    885                 continue;
    886 
    887             if (static_cast<ControllableEntity*>(*it) != this->getControllableEntity())
    888             {
    889                 float speed = this->getControllableEntity()->getVelocity().length();
    890                 Vector3 distanceCurrent = this->targetPosition_ - this->getControllableEntity()->getPosition();
    891                 Vector3 distanceNew = it->getPosition() - this->getControllableEntity()->getPosition();
    892                 if (!this->target_ || it->getPosition().squaredDistance(this->getControllableEntity()->getPosition()) * (1.5f + acos((this->getControllableEntity()->getOrientation() * WorldEntity::FRONT).dotProduct(distanceNew) / speed / distanceNew.length()) / math::twoPi)
    893                         < this->targetPosition_.squaredDistance(this->getControllableEntity()->getPosition()) * (1.5f + acos((this->getControllableEntity()->getOrientation() * WorldEntity::FRONT).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / math::twoPi) + rnd(-250, 250))
    894                 {
    895                     this->target_ = (*it);
    896                     this->targetPosition_ = it->getPosition();
    897                 }
    898             }
    899         }
    900     }
    901 
    902     void ArtificialController::forgetTarget()
    903     {
    904         this->target_ = 0;
    905         this->bShooting_ = false;
    906     }
    90768
    90869    void ArtificialController::aimAtTarget()
     
    945106            this->targetDied();
    946107    }
    947 
    948     void ArtificialController::targetDied()
    949     {
    950         this->forgetTarget();
    951         this->searchRandomTargetPosition();
    952     }
    953 
    954     bool ArtificialController::sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
    955     {
    956         if (entity1 == entity2)
    957             return true;
    958 
    959         int team1 = -1;
    960         int team2 = -1;
    961 
    962         Controller* controller = 0;
    963         if (entity1->getController())
    964             controller = entity1->getController();
    965         else
    966             controller = entity1->getXMLController();
    967         if (controller)
    968         {
    969             ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
    970             if (ac)
    971                 team1 = ac->getTeam();
    972         }
    973 
    974         if (entity2->getController())
    975             controller = entity2->getController();
    976         else
    977             controller = entity2->getXMLController();
    978         if (controller)
    979         {
    980             ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
    981             if (ac)
    982                 team2 = ac->getTeam();
    983         }
    984 
    985         TeamDeathmatch* tdm = orxonox_cast<TeamDeathmatch*>(gametype);
    986         if (tdm)
    987         {
    988             if (entity1->getPlayer())
    989                 team1 = tdm->getTeam(entity1->getPlayer());
    990 
    991             if (entity2->getPlayer())
    992                 team2 = tdm->getTeam(entity2->getPlayer());
    993         }
    994 
    995         TeamBaseMatchBase* base = 0;
    996         base = orxonox_cast<TeamBaseMatchBase*>(entity1);
    997         if (base)
    998         {
    999             switch (base->getState())
    1000             {
    1001                 case BaseState::ControlTeam1:
    1002                     team1 = 0;
    1003                     break;
    1004                 case BaseState::ControlTeam2:
    1005                     team1 = 1;
    1006                     break;
    1007                 case BaseState::Uncontrolled:
    1008                 default:
    1009                     team1 = -1;
    1010             }
    1011         }
    1012         base = orxonox_cast<TeamBaseMatchBase*>(entity2);
    1013         if (base)
    1014         {
    1015             switch (base->getState())
    1016             {
    1017                 case BaseState::ControlTeam1:
    1018                     team2 = 0;
    1019                     break;
    1020                 case BaseState::ControlTeam2:
    1021                     team2 = 1;
    1022                     break;
    1023                 case BaseState::Uncontrolled:
    1024                 default:
    1025                     team2 = -1;
    1026             }
    1027         }
    1028 
    1029         DroneController* droneController = 0;
    1030         droneController = orxonox_cast<DroneController*>(entity1->getController());
    1031         if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)
    1032             return true;
    1033         droneController = orxonox_cast<DroneController*>(entity2->getController());
    1034         if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)
    1035             return true;
    1036         DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController());
    1037         DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController());
    1038         if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner())
    1039             return true;
    1040 
    1041         Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype);
    1042         if (dynamic)
    1043         {
    1044             if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;}
    1045 
    1046             if (entity1->getPlayer())
    1047                 team1 = dynamic->getParty(entity1->getPlayer());
    1048 
    1049             if (entity2->getPlayer())
    1050                 team2 = dynamic->getParty(entity2->getPlayer());
    1051 
    1052             if (team1 ==-1 ||team2 ==-1 ) {return false;}
    1053             else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;}
    1054             else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;}
    1055             else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;}
    1056             else return true;
    1057         }
    1058 
    1059         return (team1 == team2 && team1 != -1);
    1060     }
     108 
    1061109}
  • code/branches/formation/src/orxonox/controllers/ArtificialController.h

    r8908 r8939  
    3737#include "Controller.h"
    3838#include "controllers/NewHumanController.h"
     39#include "controllers/Masterable.h"
    3940
    4041namespace orxonox
    4142{
    42     class _OrxonoxExport ArtificialController : public Controller
     43    class _OrxonoxExport ArtificialController : public Masterable
    4344    {
    4445        public:
     
    4647            virtual ~ArtificialController();
    4748
    48             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
    49 
    5049            void abandonTarget(Pawn* target);
    5150
    52             inline void setTeam(int team)
    53                 { this->team_ = team; }
    54             inline int getTeam() const
    55                 { return this->team_; }
    56 
    57             inline void setFormationFlight(bool formation)
    58                 { this->formationFlight_ = formation; }
    59             inline bool getFormationFlight() const
    60                 { return this->formationFlight_; }
    61 
    62             inline void setFormationSize(int size)
    63                 { this->maxFormationSize_ = size; }
    64             inline int getFormationSize() const
    65                 { return this->maxFormationSize_; }
    66 
    67             inline void setPassive(bool passive)
    68                 { this->passive_ = passive; }
    69             inline bool getPassive() const
    70                 { return this->passive_; }
    71 
    7251            virtual void changedControllableEntity();
    73 
    74             static void formationflight(const bool form);
    75             static void masteraction(const int action);
    76             static void followme();
    77             static void passivebehaviour(const bool passive);
    78             static void formationsize(const int size);
     52           
    7953
    8054        protected:
    81 
    82             int team_;
    83             bool formationFlight_;
    84             bool passive_;
    85             unsigned int maxFormationSize_;
    86             int freedomCount_;
    87             enum State {SLAVE, MASTER, FREE};
    88             State state_;
    89             std::vector<ArtificialController*> slaves_;
    90             ArtificialController *myMaster_;
    91             enum SpecificMasterAction {NONE, HOLD, SPIN, TURN180, FOLLOW};
    92             SpecificMasterAction specificMasterAction_;
    93             int specificMasterActionHoldCount_;
    94             float speedCounter_; //for speed adjustment when following
    95 
    96             void moveToPosition(const Vector3& target);
    97             void moveToTargetPosition();
    98             void copyOrientation(const Quaternion& orient);
    99             void copyTargetOrientation();
    100 
    101             virtual void positionReached() {}
    102 
    103             void removeFromFormation();
    104             void unregisterSlave();
    105             void searchNewMaster();
    106             void commandSlaves();
    107             void setNewMasterWithinFormation();
    108 
    109             void freeSlaves();
    110             void forceFreeSlaves();
    111             void loseMasterState();
    112             void forceFreedom();
    113             bool forcedFree();
    114 
    115             void specificMasterActionHold();
    116             void turn180Init();
    117             void turn180();
    118             void spinInit();
    119             void spin();
    120             void followInit(Pawn* pawn, const bool always = false, const int secondsToFollow = 100);
    121             void followRandomHumanInit();
    122             void follow();
    123             void followForSlaves(const Vector3& target);
    124 
    125             void setTargetPosition(const Vector3& target);
    126             void searchRandomTargetPosition();
    127 
    128             void setTargetOrientation(const Quaternion& orient);
    129             void setTargetOrientation(Pawn* target);
    130 
    131             void setTarget(Pawn* target);
    132             void searchNewTarget();
    133             void forgetTarget();
     55           
    13456            void aimAtTarget();
    13557
    13658            bool isCloseAtTarget(float distance) const;
    13759            bool isLookingAtTarget(float angle) const;
    138 
    139             void targetDied();
    140 
    141             static bool sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype); // hack
    142 
    143             bool bHasTargetPosition_;
    144             Vector3 targetPosition_;
    145 
    146             bool bHasTargetOrientation_;
    147             Quaternion targetOrientation_;
    148 
    149             WeakPtr<Pawn> target_;
    150             bool bShooting_;
    15160
    15261        private:
  • code/branches/formation/src/orxonox/controllers/CMakeLists.txt

    r7163 r8939  
    99  WaypointPatrolController.cc
    1010  DroneController.cc
     11  Masterable.cc
    1112)
  • code/branches/formation/src/orxonox/controllers/HumanController.cc

    r8858 r8939  
    5050    SetConsoleCommand("HumanController", "rotatePitch",            &HumanController::rotatePitch   ).addShortcut().setAsInputCommand();
    5151    SetConsoleCommand("HumanController", "rotateRoll",             &HumanController::rotateRoll    ).addShortcut().setAsInputCommand();
     52    SetConsoleCommand("HumanController", "toggleFormationFlight",  &HumanController::toggleFormationFlight).addShortcut().setAsInputCommand();
    5253    SetConsoleCommand("HumanController", __CC_fire_name,           &HumanController::fire          ).addShortcut().keybindMode(KeybindMode::OnHold);
    5354    SetConsoleCommand("HumanController", "reload",                 &HumanController::reload        ).addShortcut();
     
    6970    /*static*/ const float HumanController::BOOSTING_TIME = 0.1f;
    7071
    71     HumanController::HumanController(BaseObject* creator) : Controller(creator)
     72    HumanController::HumanController(BaseObject* creator) : Masterable(creator)
    7273    {
    7374        RegisterObject(HumanController);
     
    8081        this->boostingTimeout_.setTimer(HumanController::BOOSTING_TIME, false, createExecutor(createFunctor(&HumanController::terminateBoosting, this)));
    8182        this->boostingTimeout_.stopTimer();
     83        this->state_=MASTER;
    8284    }
    8385
     
    8587    {
    8688        HumanController::localController_s = 0;
     89        if (this->state_==MASTER)
     90            freeSlaves();
    8791    }
    8892
     
    9498            if (!camera)
    9599                orxout(internal_warning) << "HumanController, Warning: Using a ControllableEntity without Camera" << endl;
     100        }
     101
     102        // commandslaves when Master of a formation
     103        if (this->state_==MASTER)
     104        {
     105            this->commandSlaves();
    96106        }
    97107    }
     
    262272    }
    263273
     274    void HumanController::toggleFormationFlight()
     275    {
     276        if (HumanController::localController_s)
     277        {
     278            if (HumanController::localController_s->state_==MASTER)
     279            {
     280                HumanController::localController_s->freeSlaves();
     281                HumanController::localController_s->state_=FREE;
     282            } else //SLAVE or FREE
     283            {
     284                HumanController::localController_s->takeLeadOfFormation();
     285                //HumanController::localController_s->state_=MASTER;
     286            }
     287        }
     288
     289    }
     290
    264291    void HumanController::addBots(unsigned int amount)
    265292    {
  • code/branches/formation/src/orxonox/controllers/HumanController.h

    r8706 r8939  
    3434#include "tools/Timer.h"
    3535#include "tools/interfaces/Tickable.h"
    36 #include "Controller.h"
     36#include "Masterable.h"
    3737
    3838// tolua_begin
     
    4141    class _OrxonoxExport HumanController
    4242// tolua_end
    43         : public Controller, public Tickable
     43        : public Masterable, public Tickable
    4444    { // tolua_export
    4545        public:
     
    8585            static void myposition();
    8686
     87            static void toggleFormationFlight();
     88
    8789            static void addBots(unsigned int amount);
    8890            static void killBots(unsigned int amount = 0);
Note: See TracChangeset for help on using the changeset viewer.