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:
12 edited
2 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

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

    r8891 r9016  
    5959        if (this->state_ == FREE)
    6060        {
    61 
     61           
    6262            if (this->formationFlight_)
    6363            {
     64
     65                //changed order -> searchNewMaster MUSTN'T be called in SLAVE-state (bugfix for internal-error messages at quit)
     66                random = rnd(maxrand);
     67                if (random < 90 && (((!this->target_) || (random < 50 && this->target_)) && !this->forcedFree()))
     68                       this->searchNewMaster();
     69
    6470                // return to Master after being forced free
    6571                if (this->freedomCount_ == 1)
     
    6874                    this->freedomCount_ = 0;
    6975                }
    70 
    71                 random = rnd(maxrand);
    72                 if (random < 90 && (((!this->target_) || (random < 50 && this->target_)) && !this->forcedFree()))
    73                     this->searchNewMaster();
    74             }
    75 
     76            }
     77
     78            this->defaultBehaviour(maxrand);
     79
     80        }
     81
     82        if (this->state_ == SLAVE && this->formationMode_ == ATTACK)
     83        {
    7684            // search enemy
    7785            random = rnd(maxrand);
    78             if (random < (15 + botlevel_* 20) && (!this->target_))
     86            if (random < (botlevel_*100) && (!this->target_))
    7987                this->searchNewTarget();
    8088
    81             // forget enemy
    82             random = rnd(maxrand);
    83             if (random < ((1-botlevel_)*6) && (this->target_))
    84                 this->forgetTarget();
    85 
    8689            // next enemy
    8790            random = rnd(maxrand);
    88             if (random < (botlevel_*20) && (this->target_))
     91            if (random < (botlevel_*30) && (this->target_))
    8992                this->searchNewTarget();
    9093
    91             // fly somewhere
    92             random = rnd(maxrand);
    93             if (random < 50 && (!this->bHasTargetPosition_ && !this->target_))
    94                 this->searchRandomTargetPosition();
    95 
    96             // stop flying
    97             random = rnd(maxrand);
    98             if (random < 10 && (this->bHasTargetPosition_ && !this->target_))
    99                 this->bHasTargetPosition_ = false;
    100 
    101             // fly somewhere else
    102             random = rnd(maxrand);
    103             if (random < 30 && (this->bHasTargetPosition_ && !this->target_))
    104                 this->searchRandomTargetPosition();
    105 
    10694            // shoot
    10795            random = rnd(maxrand);
    108             if (!(this->passive_) && random < (75 + botlevel_*25) && (this->target_ && !this->bShooting_))
     96            if (!(this->passive_) && random < (botlevel_*100) && (this->target_ && !this->bShooting_))
    10997                this->bShooting_ = true;
    11098
    11199            // stop shooting
    112100            random = rnd(maxrand);
    113             if (random < ((1 - botlevel_)*25) && (this->bShooting_))
     101            if (random < (1-botlevel_)*50 && (this->bShooting_))
    114102                this->bShooting_ = false;
    115103
    116             // boost
    117             random = rnd(maxrand);
    118             if (random < botlevel_*100 )
    119                 this->boostControl();
    120 
    121             // update Checkpoints
    122             /*random = rnd(maxrand);
    123             if (this->defaultWaypoint_ && random > (maxrand-10))
    124                 this->manageWaypoints();
    125             else //if(random > maxrand-10) //CHECK USABILITY!!*/
    126             if (this->waypoints_.size() == 0 )
    127                 this->manageWaypoints();
    128 
    129         }
    130 
    131         if (this->state_ == SLAVE)
    132         {
    133 
    134104        }
    135105
    136106        if (this->state_ == MASTER)
    137107        {
    138 
    139 
    140108            this->commandSlaves();
    141109
     
    155123                   this->spinInit();
    156124
    157                 // follow a randomly chosen human - a specific Master Action
     125                /*// follow a randomly chosen human - a specific Master Action
    158126                random = rnd(1000.0f);
    159127                if (random < 1)
    160128                   this->followRandomHumanInit();
    161 
     129*/
    162130                 // lose master status (only if less than 4 slaves in formation)
    163131                random = rnd(maxrand);
     
    170138                    this->searchNewMaster();
    171139
    172                 // search enemy
    173                 random = rnd(maxrand);
    174                 if (random < (botlevel_)*25 && (!this->target_))
    175                     this->searchNewTarget();
    176 
    177                 // forget enemy
    178                 random = rnd(maxrand);
    179                 if (random < (1-botlevel_)*6 && (this->target_))
    180                     this->forgetTarget();
    181 
    182                 // next enemy
    183                 random = rnd(maxrand);
    184                 if (random < 10 && (this->target_))
    185                     this->searchNewTarget();
    186 
    187                 // fly somewhere
    188                 random = rnd(maxrand);
    189                 if (random < 50 && (!this->bHasTargetPosition_ && !this->target_))
    190                     this->searchRandomTargetPosition();
    191 
    192 
    193                 // fly somewhere else
    194                 random = rnd(maxrand);
    195                 if (random < 30 && (this->bHasTargetPosition_ && !this->target_))
    196                     this->searchRandomTargetPosition();
    197 
    198                 // shoot
    199                 random = rnd(maxrand);
    200                 if (!(this->passive_) && random < 25*(botlevel_)+1 && (this->target_ && !this->bShooting_))
    201                 {
    202                     this->bShooting_ = true;
    203                     this->forceFreeSlaves();
    204                 }
    205 
    206                 // stop shooting
    207                 random = rnd(maxrand);
    208                 if (random < ( (1- botlevel_)*25 ) && (this->bShooting_))
    209                     this->bShooting_ = false;
    210 
    211                 // boost
    212                 random = rnd(maxrand);
    213                 if (random < botlevel_*100 )
    214                     this->boostControl();
    215 
    216                 // update Checkpoints
    217                 /*random = rnd(maxrand);
    218                 if (this->defaultWaypoint_ && random > (maxrand-10))
    219                     this->manageWaypoints();
    220                 else //if(random > maxrand-10) //CHECK USABILITY!!*/
    221                 if (this->waypoints_.size() == 0 )
    222                     this->manageWaypoints();
     140                this->defaultBehaviour(maxrand);
     141
    223142            }
    224143        }
     
    234153        float maxrand = 100.0f / ACTION_INTERVAL;
    235154        ControllableEntity* controllable = this->getControllableEntity();
    236 
     155        //DOES: Either move to the waypoint or search for a Point of interest
    237156        if (controllable && this->mode_ == DEFAULT)// bot is ready to move to a target
    238157        {
     
    256175            }
    257176        }
    258         if(this->mode_ == DEFAULT)
    259             {
     177
     178        if (this->mode_ == DEFAULT)
     179        {
    260180            if (this->state_ == MASTER)
    261181            {
     
    270190                            this->aimAtTarget();
    271191                            random = rnd(maxrand);
    272                             if(this->botlevel_*100 > random && !this->isCloseAtTarget(20))
     192                            if(this->botlevel_*70 > random && !this->isCloseAtTarget(100))
    273193                                this->follow();  //If a bot is shooting a player, it shouldn't let him go away easily.
    274194                        }
     
    277197                    if (this->bHasTargetPosition_)
    278198                        this->moveToTargetPosition();
    279 
    280199                    this->doFire();
    281200                }
     
    290209            }
    291210
    292             if (this->state_ == SLAVE)
     211            if (this->state_ == SLAVE && this->formationMode_ != ATTACK)
    293212            {
    294213                if (this->bHasTargetPosition_)
     
    296215            }
    297216
    298             if (this->state_ == FREE)
     217            if (this->state_ == FREE || (this->state_==SLAVE && this->formationMode_ == ATTACK) )
    299218            {
    300219                if (this->target_)
     
    302221                    if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */
    303222                        this->forgetTarget();
    304                     else
    305                     {
    306                         this->aimAtTarget();
    307                         random = rnd(maxrand);
    308 
    309                         if(this->botlevel_*100 > random && !this->isCloseAtTarget(20))
    310                             this->follow();//If a bot is shooting a player, it shouldn't let him go away easily.
    311                      }
     223                    else this->aimAtTarget();
    312224                }
    313225
     
    315227                    this->moveToTargetPosition();
    316228
    317                 this->doFire();
    318             }
    319         }//END_OF DEFAULT MODE
     229                    this->doFire();
     230            }
     231        }
    320232        else if (this->mode_ == ROCKET)//Rockets do not belong to a group of bots -> bot states are not relevant.
    321233        {   //Vector-implementation: mode_.back() == ROCKET;
    322234            if(controllable)
    323             {
    324                 if(controllable->getRocket())//Check wether the bot is controlling the rocket and if the timeout is over.
     235            {//Check wether the bot is controlling the rocket and if the timeout is over.
     236                if(controllable->getIdentifier() == ClassByString("Rocket"))
     237
    325238                {
    326239                    this->follow();
     
    341254        SUPER(AIController, tick, dt);
    342255    }
     256//**********************************************NEW
     257    void AIController::defaultBehaviour(float maxrand)
     258    {       float random;
     259            // search enemy
     260            random = rnd(maxrand);
     261            if (random < (botlevel_* 100) && (!this->target_))
     262                this->searchNewTarget();
     263
     264            // forget enemy
     265            random = rnd(maxrand);
     266            if (random < ((1-botlevel_)*20) && (this->target_))
     267                this->forgetTarget();
     268
     269            // next enemy
     270            random = rnd(maxrand);
     271            if (random < (botlevel_*30) && (this->target_))
     272                this->searchNewTarget();
     273
     274            // fly somewhere
     275            random = rnd(maxrand);
     276            if (random < 50 && (!this->bHasTargetPosition_ && !this->target_))
     277                this->searchRandomTargetPosition();
     278
     279            // stop flying
     280            random = rnd(maxrand);
     281            if (random < 10 && (this->bHasTargetPosition_ && !this->target_))
     282                this->bHasTargetPosition_ = false;
     283
     284            // fly somewhere else
     285            random = rnd(maxrand);
     286            if (random < 30 && (this->bHasTargetPosition_ && !this->target_))
     287                this->searchRandomTargetPosition();
     288
     289            if (this->state_ == MASTER) // master: shoot
     290            {
     291                random = rnd(maxrand);
     292                if (!(this->passive_) && random < (100*botlevel_) && (this->target_ && !this->bShooting_))
     293                {
     294                    this->bShooting_ = true;
     295                    this->forceFreeSlaves();
     296                }
     297            }
     298            else
     299            {
     300                // shoot
     301                random = rnd(maxrand);
     302                if (!(this->passive_) && random < (botlevel_*100) && (this->target_ && !this->bShooting_))
     303                    this->bShooting_ = true;
     304            }
     305
     306            // stop shooting
     307            random = rnd(maxrand);
     308            if (random < ((1 - botlevel_)*50) && (this->bShooting_))
     309                this->bShooting_ = false;
     310
     311            // boost
     312            random = rnd(maxrand);
     313            if (random < botlevel_*50 )
     314                this->boostControl();
     315
     316            // update Checkpoints
     317            /*random = rnd(maxrand);
     318            if (this->defaultWaypoint_ && random > (maxrand-10))
     319                this->manageWaypoints();
     320            else //if(random > maxrand-10) //CHECK USABILITY!!*/
     321            if (this->waypoints_.size() == 0 )
     322                this->manageWaypoints();
     323    }
    343324
    344325}
  • code/trunk/src/orxonox/controllers/AIController.h

    r8729 r9016  
    4444            virtual ~AIController();
    4545
    46             virtual void tick(float dt);
     46            virtual void tick(float dt); //<! Carrying out the targets set in action().
    4747
    4848        protected:
    49             virtual void action();
     49            virtual void action(); //<! action() is called in regular intervals managing the bot's behaviour ~ setting targets.
     50            void defaultBehaviour(float maxrand); //<! Helper function for code reusage. Some concrete commands for a bot.
    5051
    5152        private:
    5253            static const float ACTION_INTERVAL;
    5354
    54             Timer actionTimer_;
     55            Timer actionTimer_; //<! Regularly calls action().
    5556    };
    5657}
  • 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}
  • code/trunk/src/orxonox/controllers/ArtificialController.h

    r8891 r9016  
    3131
    3232#include "OrxonoxPrereqs.h"
     33#include "controllers/FormationController.h"
    3334
    34 #include <map>
    35 
    36 #include "util/Math.h"
    37 #include "Controller.h"
    38 #include "controllers/NewHumanController.h"
    39 #include "weaponsystem/WeaponSystem.h"
    4035
    4136namespace orxonox
    4237{
    43     class _OrxonoxExport ArtificialController : public Controller
     38    class _OrxonoxExport ArtificialController : public FormationController
    4439    {
    4540        public:
     
    4742            virtual ~ArtificialController();
    4843
    49             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
    50 
    5144            void abandonTarget(Pawn* target);
    5245
    53             inline void setTeam(int team)
    54                 { this->team_ = team; }
    55             inline int getTeam() const
    56                 { return this->team_; }
    57 
    58             inline void setFormationFlight(bool formation)
    59                 { this->formationFlight_ = formation; }
    60             inline bool getFormationFlight() const
    61                 { return this->formationFlight_; }
    62 
    63             inline void setFormationSize(int size)
    64                 { this->maxFormationSize_ = size; }
    65             inline int getFormationSize() const
    66                 { return this->maxFormationSize_; }
    67 
    68             inline void setPassive(bool passive)
    69                 { this->passive_ = passive; }
    70             inline bool getPassive() const
    71                 { return this->passive_; }
    72 
    7346            virtual void changedControllableEntity();
    74 
    75             static void formationflight(const bool form);
    76             static void masteraction(const int action);
    77             static void followme();
    78             static void passivebehaviour(const bool passive);
    79             static void formationsize(const int size);
    8047
    8148            virtual void doFire();
     
    9562            void manageWaypoints();
    9663
     64           
     65
    9766        protected:
    98 
    99             int team_;
    100             bool formationFlight_;
    101             bool passive_;
    102             unsigned int maxFormationSize_;
    103             int freedomCount_;
    104             enum State {SLAVE, MASTER, FREE};
    105             State state_;
    106             std::vector<ArtificialController*> slaves_;
    107             ArtificialController *myMaster_;
    108             enum SpecificMasterAction {NONE, HOLD, SPIN, TURN180, FOLLOW};
    109             SpecificMasterAction specificMasterAction_;
    110             int specificMasterActionHoldCount_;
    111             float speedCounter_; //for speed adjustment when following
    112 
    113             void moveToPosition(const Vector3& target);
    114             void moveToTargetPosition();
    115             void absoluteMoveToPosition(const Vector3& target);
    116 
    117             virtual void positionReached() {}
    118 
    119             void removeFromFormation();
    120             void unregisterSlave();
    121             void searchNewMaster();
    122             void commandSlaves();
    123             void setNewMasterWithinFormation();
    124 
    125             void freeSlaves();
    126             void forceFreeSlaves();
    127             void loseMasterState();
    128             void forceFreedom();
    129             bool forcedFree();
    130 
    131             void specificMasterActionHold();
    132             void turn180Init();
    133             void turn180();
    134             void spinInit();
    135             void spin();
    136             void followInit(Pawn* pawn, const bool always = false, const int secondsToFollow = 100);
    137             void followRandomHumanInit();
    138             void follow();
    139             void followForSlaves(const Vector3& target);
    140 
    141             void setTargetPosition(const Vector3& target);
    142             void searchRandomTargetPosition();
    143 
    144             void setTarget(Pawn* target);
    145             void searchNewTarget();
    146             void forgetTarget();
     67           
    14768            void aimAtTarget();
    14869
    14970            bool isCloseAtTarget(float distance) const;
    15071            bool isLookingAtTarget(float angle) const;
    151 
    152             void targetDied();
    153 
    154             static bool sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype); // hack
    155             void boostControl(); //<! Sets and resets the boost parameter of the spaceship. Bots alternate between boosting and saving boost.
    156 
    157             bool bHasTargetPosition_;
    158             Vector3 targetPosition_;
    159             WeakPtr<Pawn> target_;
    160             bool bShooting_;
    16172
    16273            float botlevel_; //<! Makes the level of a bot configurable.
     
    16576            void setPreviousMode();
    16677
     78
    16779            //WEAPONSYSTEM DATA
    168             std::map<std::string, int> weaponModes_; //<! Links each "weapon" to it's weaponmode- managed by setupWeapons()
     80            std::map<std::string, int> weaponModes_; //<! Links each "weapon" to it's weaponmode - managed by setupWeapons()
    16981            //std::vector<int> projectiles_; //<! Displays amount of projectiles of each weapon. - managed by setupWeapons()
    17082            float timeout_; //<! Timeout for rocket usage. (If a rocket misses, a bot should stop using it.)
     
    17385            int getFiremode(std::string name);
    17486
     87
    17588            //WAYPOINT DATA
    17689            std::vector<WeakPtr<WorldEntity> > waypoints_;
     
    17891            float squaredaccuracy_;
    17992            WorldEntity* defaultWaypoint_;
     93
     94            void boostControl(); //<! Sets and resets the boost parameter of the spaceship. Bots alternate between boosting and saving boost.
     95
     96        private:
    18097    };
    18198}
  • code/trunk/src/orxonox/controllers/CMakeLists.txt

    r7163 r9016  
    99  WaypointPatrolController.cc
    1010  DroneController.cc
     11  FormationController.cc
    1112)
  • code/trunk/src/orxonox/controllers/HumanController.cc

    r8858 r9016  
    5050    SetConsoleCommand("HumanController", "rotatePitch",            &HumanController::rotatePitch   ).addShortcut().setAsInputCommand();
    5151    SetConsoleCommand("HumanController", "rotateRoll",             &HumanController::rotateRoll    ).addShortcut().setAsInputCommand();
     52    SetConsoleCommand("HumanController", "toggleFormationFlight",  &HumanController::toggleFormationFlight).addShortcut().keybindMode(KeybindMode::OnPress);
     53    SetConsoleCommand("HumanController", "FFChangeMode",  &HumanController::FFChangeMode).addShortcut().keybindMode(KeybindMode::OnPress);
    5254    SetConsoleCommand("HumanController", __CC_fire_name,           &HumanController::fire          ).addShortcut().keybindMode(KeybindMode::OnHold);
    5355    SetConsoleCommand("HumanController", "reload",                 &HumanController::reload        ).addShortcut();
     
    6971    /*static*/ const float HumanController::BOOSTING_TIME = 0.1f;
    7072
    71     HumanController::HumanController(BaseObject* creator) : Controller(creator)
     73    HumanController::HumanController(BaseObject* creator) : FormationController(creator)
    7274    {
    7375        RegisterObject(HumanController);
     
    7678        this->boosting_ = false;
    7779        this->boosting_ = false;
    78 
    7980        HumanController::localController_s = this;
    8081        this->boostingTimeout_.setTimer(HumanController::BOOSTING_TIME, false, createExecutor(createFunctor(&HumanController::terminateBoosting, this)));
     
    8485    HumanController::~HumanController()
    8586    {
     87        if (HumanController::localController_s)
     88        {
     89            HumanController::localController_s->removeFromFormation();
     90        }
    8691        HumanController::localController_s = 0;
    8792    }
     
    95100                orxout(internal_warning) << "HumanController, Warning: Using a ControllableEntity without Camera" << endl;
    96101        }
     102
     103        // commandslaves when Master of a formation
     104        if (HumanController::localController_s && HumanController::localController_s->state_==MASTER)
     105        {
     106            if (HumanController::localController_s->formationMode_ != ATTACK)
     107                HumanController::localController_s->commandSlaves();
     108        }
    97109    }
    98110
     
    160172    {
    161173        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
     174        {
    162175            HumanController::localController_s->controllableEntity_->fire(firemode);
     176            //if human fires, set slaves free. See FormationController::forceFreeSlaves()
     177            if (HumanController::localController_s->state_==MASTER && HumanController::localController_s->formationMode_ == NORMAL)
     178            {
     179                HumanController::localController_s->forceFreeSlaves();
     180            }
     181        }
    163182    }
    164183
     
    195214            this->boosting_ = true;
    196215            this->boostingTimeout_.startTimer();
    197            
    198             this->controllableEntity_->boost(this->boosting_);
     216            if(this->controllableEntity_)
     217                this->controllableEntity_->boost(this->boosting_);
    199218//            orxout() << "Start boosting" << endl;
    200219        }
     
    209228        this->boosting_ = false;
    210229        this->boostingTimeout_.stopTimer();
    211 
    212         this->controllableEntity_->boost(this->boosting_);
     230        if(this->controllableEntity_)
     231            this->controllableEntity_->boost(this->boosting_);
    213232//        orxout() << "Stop boosting" << endl;
    214233    }
     
    262281    }
    263282
     283    /**
     284    @brief
     285       toggle the formation. Not usable, if formationflight is disabled generally (formationFlight_)
     286    */
     287    void HumanController::toggleFormationFlight()
     288    {
     289        if (HumanController::localController_s)
     290        {
     291            if (!HumanController::localController_s->formationFlight_)
     292            {
     293                return; //dont use when formationFlight is disabled
     294            }
     295            if (HumanController::localController_s->state_==MASTER)
     296            {
     297                HumanController::localController_s->loseMasterState();
     298                orxout(message) <<"FormationFlight disabled "<< endl;
     299            } else //SLAVE or FREE
     300            {
     301                HumanController::localController_s->takeLeadOfFormation();
     302                orxout(message) <<"FormationFlight enabled "<< endl;
     303            }
     304           
     305        }
     306
     307    }
     308
     309    /**
     310    @brief
     311       Switch through the different Modes of formationflight. You must be a master of a formation to use.
     312    */
     313    void HumanController::FFChangeMode()
     314    {
     315        if (HumanController::localController_s && HumanController::localController_s->state_==MASTER)
     316        {
     317            switch (HumanController::localController_s->getFormationMode()) {
     318                case NORMAL:
     319                    HumanController::localController_s->setFormationMode(DEFEND);
     320                    orxout(message) <<"Mode: DEFEND "<< endl;
     321                    break;
     322                case DEFEND:
     323                    HumanController::localController_s->setFormationMode(ATTACK);
     324                    orxout(message) <<"Mode: ATTACK "<< endl;
     325                    break;
     326                case ATTACK:
     327                    HumanController::localController_s->setFormationMode(NORMAL);
     328                    orxout(message) <<"Mode: NORMAL "<< endl;
     329                    break;
     330            }
     331        }
     332    }
     333
     334
     335    //used, when slaves are in DEFEND mode.
     336    void HumanController::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
     337    {
     338        if (!this->formationFlight_ || this->state_!=MASTER || this->formationMode_!=DEFEND) return;
     339            this->masterAttacked(originator);
     340    }
     341
    264342    void HumanController::addBots(unsigned int amount)
    265343    {
  • code/trunk/src/orxonox/controllers/HumanController.h

    r8706 r9016  
    3434#include "tools/Timer.h"
    3535#include "tools/interfaces/Tickable.h"
    36 #include "Controller.h"
     36#include "FormationController.h"
    3737
    3838// tolua_begin
     
    4141    class _OrxonoxExport HumanController
    4242// tolua_end
    43         : public Controller, public Tickable
     43        : public FormationController, public Tickable
    4444    { // tolua_export
    4545        public:
     
    7474            void keepBoosting(void);
    7575            void terminateBoosting(void);
    76            
     76                 
     77
    7778            static void greet();
    7879            static void switchCamera();
     
    8485            static void toggleGodMode();
    8586            static void myposition();
     87
     88            static void toggleFormationFlight();
     89            static void FFChangeMode();
     90            virtual void hit(Pawn* originator, btManifoldPoint& contactpoint, float damage);
     91
    8692
    8793            static void addBots(unsigned int amount);
  • code/trunk/src/orxonox/controllers/NewHumanController.cc

    r8858 r9016  
    291291        }
    292292        else
    293             HumanController::localController_s->getControllableEntity()->fire(firemode);
    294 
     293            HumanController::doFire(firemode); //call for formationflight
    295294    }
    296295
    297296    void NewHumanController::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
    298297    {
     298        //Used in HumanController for formationFlight
     299        HumanController::hit(originator,contactpoint,damage);
     300       
    299301        if (this->showDamageOverlay_ && !this->controlPaused_ && this->controllableEntity_ && !this->controllableEntity_->isInMouseLook())
    300302        {
  • code/trunk/src/orxonox/controllers/NewHumanController.h

    r7859 r9016  
    6969            virtual void doResumeControl();
    7070
     71            float getCurrentYaw(){ return this->currentYaw_; }
     72            float getCurrentPitch(){ return this->currentPitch_; }
     73
    7174
    7275        protected:
  • code/trunk/src/orxonox/controllers/WaypointPatrolController.cc

    r7184 r9016  
    4242        RegisterObject(WaypointPatrolController);
    4343
    44         //this->team_ = 0;
    4544        this->alertnessradius_ = 500;
    4645
     
    5352
    5453        XMLPortParam(WaypointPatrolController, "alertnessradius", setAlertnessRadius, getAlertnessRadius, xmlelement, mode).defaultValues(500.0f);
    55 //        XMLPortParam(WaypointPatrolController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(0);
    5654    }
    5755
  • code/trunk/src/orxonox/controllers/WaypointPatrolController.h

    r7163 r9016  
    4646            virtual void tick(float dt);
    4747
    48            /* inline void setTeam(int team)
    49                 { this->team_ = team; }
    50             inline int getTeam() const
    51                 { return this->team_; } */
    52 
    5348            inline void setAlertnessRadius(float radius)
    5449                { this->alertnessradius_ = radius; }
     
    5954            void searchEnemy();
    6055
    61             //int team_;
    6256            float alertnessradius_;
    6357            Timer patrolTimer_;
Note: See TracChangeset for help on using the changeset viewer.