Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 16, 2011, 8:36:41 PM (12 years ago)
Author:
jo
Message:

Merged Formation branch. There are still some bugs (just have a look at the tutorial level)

Location:
code/branches/presentation2011
Files:
10 edited
2 copied

Legend:

Unmodified
Added
Removed
  • code/branches/presentation2011

  • code/branches/presentation2011/data/defaultConfig/keybindings.ini

    r8706 r8992  
    7171KeyNumLock=
    7272KeyNumRow0=
    73 KeyNumRow1=
    74 KeyNumRow2=
     73KeyNumRow1="toggleFormationFlight"
     74KeyNumRow2="FFChangeMode"
    7575KeyNumRow3=
    7676KeyNumRow4=
  • code/branches/presentation2011/src/orxonox/controllers/AIController.cc

    r8980 r8992  
    7575
    7676            this->defaultBehaviour(maxrand);
    77         }
    78 
    79         if (this->state_ == SLAVE)
    80         {
     77
     78        }
     79
     80        if (this->state_ == SLAVE && this->formationMode_ == ATTACK) //TODO: add botlevel parameter
     81        {
     82            // search enemy
     83            random = rnd(maxrand);
     84            if (random < 75 && (!this->target_))
     85                this->searchNewTarget();
     86
     87            // next enemy
     88            random = rnd(maxrand);
     89            if (random < 10 && (this->target_))
     90                this->searchNewTarget();
     91
     92            // shoot
     93            random = rnd(maxrand);
     94            if (!(this->passive_) && random < 75 && (this->target_ && !this->bShooting_))
     95                this->bShooting_ = true;
     96
     97            // stop shooting
     98            random = rnd(maxrand);
     99            if (random < 25 && (this->bShooting_))
     100                this->bShooting_ = false;
    81101
    82102        }
     
    101121                   this->spinInit();
    102122
    103                 // follow a randomly chosen human - a specific Master Action
     123                /*// follow a randomly chosen human - a specific Master Action
    104124                random = rnd(1000.0f);
    105125                if (random < 1)
    106126                   this->followRandomHumanInit();
    107 
     127*/
    108128                 // lose master status (only if less than 4 slaves in formation)
    109129                random = rnd(maxrand);
     
    117137
    118138                this->defaultBehaviour(maxrand);
    119             }
    120         }
     139
     140            }
     141        }
     142
    121143    }
    122144
     
    129151        float maxrand = 100.0f / ACTION_INTERVAL;
    130152        ControllableEntity* controllable = this->getControllableEntity();
    131 
     153        //DOES: Either move to the waypoint or search for a Point of interest
    132154        if (controllable && this->mode_ == DEFAULT)// bot is ready to move to a target
    133155        {
     
    151173            }
    152174        }
    153         if(this->mode_ == DEFAULT)
    154             {
     175
     176        if (this->mode_ == DEFAULT)
     177        {
    155178            if (this->state_ == MASTER)
    156179            {
     
    165188                            this->aimAtTarget();
    166189                            random = rnd(maxrand);
    167                             if(this->botlevel_*100 > random && !this->isCloseAtTarget(20))
     190                            if(this->botlevel_*70 > random && !this->isCloseAtTarget(100))
    168191                                this->follow();  //If a bot is shooting a player, it shouldn't let him go away easily.
    169192                        }
     
    172195                    if (this->bHasTargetPosition_)
    173196                        this->moveToTargetPosition();
    174 
    175197                    this->doFire();
    176198                }
     
    185207            }
    186208
    187             if (this->state_ == SLAVE)
     209            if (this->state_ == SLAVE && this->formationMode_ != ATTACK)
    188210            {
    189211                if (this->bHasTargetPosition_)
     
    191213            }
    192214
    193             if (this->state_ == FREE)
     215            if (this->state_ == FREE || (this->state_==SLAVE && this->formationMode_ == ATTACK) )
    194216            {
    195217                if (this->target_)
     
    197219                    if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */
    198220                        this->forgetTarget();
    199                     else
    200                     {
    201                         this->aimAtTarget();
    202                         random = rnd(maxrand);
    203 
    204                         if(this->botlevel_*100 > random && !this->isCloseAtTarget(20))
    205                             this->follow();//If a bot is shooting a player, it shouldn't let him go away easily.
    206                      }
     221                    else this->aimAtTarget();
    207222                }
    208223
     
    210225                    this->moveToTargetPosition();
    211226
    212                 this->doFire();
    213             }
    214         }//END_OF DEFAULT MODE
     227                    this->doFire();
     228            }
     229        }
    215230        else if (this->mode_ == ROCKET)//Rockets do not belong to a group of bots -> bot states are not relevant.
    216231        {   //Vector-implementation: mode_.back() == ROCKET;
     
    237252        SUPER(AIController, tick, dt);
    238253    }
    239 
     254//**********************************************NEW
    240255    void AIController::defaultBehaviour(float maxrand)
    241256    {       float random;
  • code/branches/presentation2011/src/orxonox/controllers/AIController.h

    r8980 r8992  
    5353            static const float ACTION_INTERVAL;
    5454
    55             Timer actionTimer_; //<! Regularly calls action(). 
     55            Timer actionTimer_; //<! Regularly calls action().
    5656    };
    5757}
  • code/branches/presentation2011/src/orxonox/controllers/ArtificialController.cc

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

    r8980 r8992  
    3131
    3232#include "OrxonoxPrereqs.h"
    33 
    34 #include <map>
    35 
    36 #include "util/Math.h"
    37 #include "Controller.h"
    38 #include "controllers/NewHumanController.h"
    39 #include "weaponsystem/WeaponSystem.h"
     33#include "controllers/FormationController.h"
    4034
    4135namespace orxonox
    4236{
    43     class _OrxonoxExport ArtificialController : public Controller
     37    class _OrxonoxExport ArtificialController : public FormationController
    4438    {
    4539        public:
     
    4741            virtual ~ArtificialController();
    4842
    49             virtual void XMLPort(Element& xmlelement, XMLPort::Mode mode);
    50 
    5143            void abandonTarget(Pawn* target);
    5244
    53             inline void setTeam(int team) //TODO: write through to controllable entity.
    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 
    7345            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);
    80 
     46//************************************************************************* NEW
    8147            virtual void doFire();
    8248            void setBotLevel(float level=1.0f);
     
    9561            void manageWaypoints();
    9662
     63           
     64
    9765        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();
     66           
    14767            void aimAtTarget();
    14868
    14969            bool isCloseAtTarget(float distance) const;
    15070            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_;
    161 
     71//************************************************************************* NEW
    16272            float botlevel_; //<! Makes the level of a bot configurable.
    16373            enum Mode {DEFAULT, ROCKET, DEFENCE, MOVING};//TODO; implement DEFENCE, MOVING modes
     
    16575            void setPreviousMode();
    16676
     77
    16778            //WEAPONSYSTEM DATA
    168             std::map<std::string, int> weaponModes_; //<! Links each "weapon" to it's weaponmode- managed by setupWeapons()
     79            std::map<std::string, int> weaponModes_; //<! Links each "weapon" to it's weaponmode - managed by setupWeapons()
    16980            //std::vector<int> projectiles_; //<! Displays amount of projectiles of each weapon. - managed by setupWeapons()
    17081            float timeout_; //<! Timeout for rocket usage. (If a rocket misses, a bot should stop using it.)
     
    17384            int getFiremode(std::string name);
    17485
     86
    17587            //WAYPOINT DATA
    17688            std::vector<WeakPtr<WorldEntity> > waypoints_;
     
    17890            float squaredaccuracy_;
    17991            WorldEntity* defaultWaypoint_;
     92
     93            void boostControl(); //<! Sets and resets the boost parameter of the spaceship. Bots alternate between boosting and saving boost.
     94
     95        private:
    18096    };
    18197}
  • code/branches/presentation2011/src/orxonox/controllers/CMakeLists.txt

    r7163 r8992  
    99  WaypointPatrolController.cc
    1010  DroneController.cc
     11  FormationController.cc
    1112)
  • code/branches/presentation2011/src/orxonox/controllers/FormationController.cc

    r8991 r8992  
    4040#include "gametypes/TeamDeathmatch.h"
    4141#include "gametypes/Dynamicmatch.h"
    42 //#include "gametypes/Mission.h" TODO: include mission after merging
     42#include "gametypes/Mission.h" TODO: include mission after merging
    4343#include "gametypes/Gametype.h"
    4444#include "controllers/WaypointPatrolController.h"
     
    962962        }
    963963
    964         /*Mission* miss = orxonox_cast<Mission*>(gametype); //NEW
     964        Mission* miss = orxonox_cast<Mission*>(gametype);
    965965        if (miss)
    966966        {
     
    970970            if (entity2->getPlayer())
    971971                team2 = miss->getTeam(entity2->getPlayer());
    972         }*/
     972        }
    973973
    974974        TeamBaseMatchBase* base = 0;
     
    10391039    }
    10401040
     1041    void FormationController::absoluteMoveToPosition(const Vector3& target)
     1042    {
     1043        float minDistance = 40.0f;
     1044        if (!this->getControllableEntity())
     1045            return;
     1046
     1047        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
     1048        float distance = (target - this->getControllableEntity()->getPosition()).length();
     1049
     1050            if (this->target_ || distance > minDistance)
     1051            {
     1052                // Multiply with ROTATEFACTOR_FREE to make them a bit slower
     1053                this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x);
     1054                this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y);
     1055                this->getControllableEntity()->moveFrontBack(SPEED_FREE);
     1056            }
     1057
     1058
     1059        if (distance < minDistance)
     1060        {
     1061            this->positionReached();
     1062        }
     1063    }
     1064
    10411065}
  • code/branches/presentation2011/src/orxonox/controllers/FormationController.h

    r8991 r8992  
    118118      void moveToPosition(const Vector3& target);
    119119      void moveToTargetPosition();
     120      void absoluteMoveToPosition(const Vector3& target);
    120121      void copyOrientation(const Quaternion& orient);
    121122      void copyTargetOrientation();
  • code/branches/presentation2011/src/orxonox/controllers/HumanController.cc

    r8980 r8992  
    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 
     80        this->tempMaster=NULL;
    7981        HumanController::localController_s = this;
    8082        this->boostingTimeout_.setTimer(HumanController::BOOSTING_TIME, false, createExecutor(createFunctor(&HumanController::terminateBoosting, this)));
    8183        this->boostingTimeout_.stopTimer();
     84        this->state_=FREE;
    8285    }
    8386
    8487    HumanController::~HumanController()
    8588    {
     89        if (HumanController::localController_s)
     90        {
     91            HumanController::localController_s->removeFromFormation();
     92        }
    8693        HumanController::localController_s = 0;
    8794    }
     
    95102                orxout(internal_warning) << "HumanController, Warning: Using a ControllableEntity without Camera" << endl;
    96103        }
     104
     105        // commandslaves when Master of a formation
     106        if (HumanController::localController_s && HumanController::localController_s->state_==MASTER)
     107        {
     108            if (HumanController::localController_s->formationMode_ != ATTACK)
     109                HumanController::localController_s->commandSlaves();
     110        }
    97111    }
    98112
     
    160174    {
    161175        if (HumanController::localController_s && HumanController::localController_s->controllableEntity_)
     176        {
    162177            HumanController::localController_s->controllableEntity_->fire(firemode);
     178            //if human fires, set slaves free. See FormationController::forceFreeSlaves()
     179            if (HumanController::localController_s->state_==MASTER && HumanController::localController_s->formationMode_ == NORMAL)
     180            {
     181                HumanController::localController_s->forceFreeSlaves();
     182            }
     183        }
    163184    }
    164185
     
    262283    }
    263284
     285    /**
     286    @brief
     287       toggle the formation. Not usable, if formationflight is disabled generally (formationFlight_)
     288    */
     289    void HumanController::toggleFormationFlight()
     290    {
     291        if (HumanController::localController_s)
     292        {
     293            if (!HumanController::localController_s->formationFlight_)
     294            {
     295                return; //dont use when formationFlight is disabled
     296            }
     297            if (HumanController::localController_s->state_==MASTER)
     298            {
     299                HumanController::localController_s->loseMasterState();
     300                orxout(message) <<"FormationFlight disabled "<< endl;
     301            } else //SLAVE or FREE
     302            {
     303                HumanController::localController_s->takeLeadOfFormation();
     304                orxout(message) <<"FormationFlight enabled "<< endl;
     305            }
     306           
     307        }
     308
     309    }
     310
     311    /**
     312    @brief
     313       Switch through the different Modes of formationflight. You must be a master of a formation to use.
     314    */
     315    void HumanController::FFChangeMode()
     316    {
     317        if (HumanController::localController_s && HumanController::localController_s->state_==MASTER)
     318        {
     319            switch (HumanController::localController_s->getFormationMode()) {
     320                case NORMAL:
     321                    HumanController::localController_s->setFormationMode(DEFEND);
     322                    orxout(message) <<"Mode: DEFEND "<< endl;
     323                    break;
     324                case DEFEND:
     325                    HumanController::localController_s->setFormationMode(ATTACK);
     326                    orxout(message) <<"Mode: ATTACK "<< endl;
     327                    break;
     328                case ATTACK:
     329                    HumanController::localController_s->setFormationMode(NORMAL);
     330                    orxout(message) <<"Mode: NORMAL "<< endl;
     331                    break;
     332            }
     333        }
     334    }
     335
     336
     337    //used, when slaves are in DEFEND mode.
     338    void HumanController::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
     339    {
     340        if (!this->formationFlight_ || this->state_!=MASTER || this->formationMode_!=DEFEND) return;
     341            this->masterAttacked(originator);
     342    }
     343
    264344    void HumanController::addBots(unsigned int amount)
    265345    {
  • code/branches/presentation2011/src/orxonox/controllers/HumanController.h

    r8706 r8992  
    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);
     
    107113            Timer boostingTimeout_; // A timer to check whether the player is no longer boosting.
    108114            static const float BOOSTING_TIME; // The time after it is checked, whether the player is no longer boosting.
     115            FormationController* tempMaster;
    109116
    110117    }; // tolua_export
  • code/branches/presentation2011/src/orxonox/controllers/NewHumanController.cc

    r8858 r8992  
    277277    }
    278278
    279     void NewHumanController::doFire(unsigned int firemode)
     279    void NewHumanController::doFire(unsigned int firemode)//TODO??
    280280    {
    281281        if (!this->controllableEntity_)
     
    297297    void NewHumanController::hit(Pawn* originator, btManifoldPoint& contactpoint, float damage)
    298298    {
     299        //Used in HumanController for formationFlight
     300        HumanController::hit(originator,contactpoint,damage);
     301       
    299302        if (this->showDamageOverlay_ && !this->controlPaused_ && this->controllableEntity_ && !this->controllableEntity_->isInMouseLook())
    300303        {
Note: See TracChangeset for help on using the changeset viewer.