Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Feb 15, 2012, 11:51:58 PM (12 years ago)
Author:
jo
Message:

Merging presentation2011 branch to trunk. Please check for possible bugs.

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/orxonox/controllers/ArtificialController.cc

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