Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Aug 11, 2010, 8:55:13 AM (14 years ago)
Author:
dafrick
Message:

Merged presentation3 branch into trunk.

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

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

    r6502 r7163  
    2323 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      ...
     25 *      Dominik Solenicki
    2626 *
    2727 */
     
    2929#include "ArtificialController.h"
    3030
     31#include <vector>
     32#include <climits>
     33
     34#include "util/Math.h"
     35#include "core/ConsoleCommand.h"
    3136#include "core/CoreIncludes.h"
     37#include "core/XMLPort.h"
    3238#include "worldentities/ControllableEntity.h"
    3339#include "worldentities/pawns/Pawn.h"
    3440#include "worldentities/pawns/TeamBaseMatchBase.h"
    3541#include "gametypes/TeamDeathmatch.h"
     42#include "gametypes/Dynamicmatch.h"
    3643#include "controllers/WaypointPatrolController.h"
     44#include "controllers/NewHumanController.h"
     45#include "controllers/DroneController.h"
    3746
    3847namespace orxonox
    3948{
     49    SetConsoleCommand(ArtificialController, formationflight, true);
     50    SetConsoleCommand(ArtificialController, masteraction, true);
     51    SetConsoleCommand(ArtificialController, followme, true);
     52    SetConsoleCommand(ArtificialController, passivebehaviour, true);
     53    SetConsoleCommand(ArtificialController, formationsize, true);
     54
     55    static const unsigned int STANDARD_MAX_FORMATION_SIZE = 7;
     56    static const int RADIUS_TO_SEARCH_FOR_MASTERS = 5000;
     57    static const int FORMATION_LENGTH =  130;
     58    static const int FORMATION_WIDTH =  110;
     59    static const int FREEDOM_COUNT = 4; //seconds the slaves in a formation will be set free when master attacks an enemy
     60    static const float SPEED_MASTER = 0.6f;
     61    static const float ROTATEFACTOR_MASTER = 0.2f;
     62    static const float SPEED_FREE = 0.8f;
     63    static const float ROTATEFACTOR_FREE = 0.8f;
     64
     65
    4066    ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator)
    4167    {
     
    4369
    4470        this->target_ = 0;
     71        this->formationFlight_ = true;
     72        this->passive_ = false;
     73        this->maxFormationSize_ = STANDARD_MAX_FORMATION_SIZE;
     74        this->myMaster_ = 0;
     75        this->freedomCount_ = 0;
     76        this->team_ = -1;
     77        this->state_ = FREE;
     78        this->specificMasterAction_ = NONE;
     79        this->specificMasterActionHoldCount_  = 0;
    4580        this->bShooting_ = false;
    4681        this->bHasTargetPosition_ = false;
     82        this->speedCounter_ = 0.2f;
    4783        this->targetPosition_ = Vector3::ZERO;
    4884
     
    5288    ArtificialController::~ArtificialController()
    5389    {
     90        if (this->isInitialized())
     91        {
     92            this->removeFromFormation();
     93
     94            for (ObjectList<ArtificialController>::iterator it = ObjectList<ArtificialController>::begin(); it; ++it)
     95            {
     96                if (*it != this)
     97                {
     98                    if (it->myMaster_ == this)
     99                    {
     100                        COUT(1) << "error: " << this << " is still master in " << (*it) << std::endl;
     101                        it->myMaster_ = 0;
     102                    }
     103
     104                    while (true)
     105                    {
     106                        std::vector<ArtificialController*>::iterator it2 = std::find(it->slaves_.begin(), it->slaves_.end(), this);
     107                        if (it2 != it->slaves_.end())
     108                        {
     109                            COUT(1) << "error: " << this << " is still slave in " << (*it) << std::endl;
     110                            it->slaves_.erase(it2);
     111                        }
     112                        else
     113                            break;
     114                    }
     115                }
     116            }
     117        }
     118    }
     119
     120    void ArtificialController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
     121    {
     122        SUPER(ArtificialController, XMLPort, xmlelement, mode);
     123
     124        XMLPortParam(ArtificialController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(-1);
     125        XMLPortParam(ArtificialController, "formationFlight", setFormationFlight, getFormationFlight, xmlelement, mode).defaultValues(false);
     126        XMLPortParam(ArtificialController, "formationSize", setFormationSize, getFormationSize, xmlelement, mode).defaultValues(STANDARD_MAX_FORMATION_SIZE);
     127        XMLPortParam(ArtificialController, "passive", setPassive, getPassive, xmlelement, mode).defaultValues(false);
     128    }
     129
     130// Documentation only here to get a faster overview for creating a useful documentation...
     131
     132    /**
     133        @brief Activates / deactivates formationflight behaviour
     134        @param form activate formflight if form is true
     135    */
     136    void ArtificialController::formationflight(const bool form)
     137    {
     138        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
     139        {
     140            Controller* controller = 0;
     141
     142            if (it->getController())
     143                controller = it->getController();
     144            else if (it->getXMLController())
     145                controller = it->getXMLController();
     146
     147            if (!controller)
     148                continue;
     149
     150            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
     151
     152            if (aiController)
     153            {
     154                aiController->formationFlight_ = form;
     155                if (!form)
     156                {
     157                    aiController->removeFromFormation();
     158                }
     159            }
     160        }
     161    }
     162
     163    /**
     164        @brief Get all masters to do a "specific master action"
     165        @param action which action to perform (integer, so it can be called with a console command (tmp solution))
     166    */
     167    void ArtificialController::masteraction(const int action)
     168    {
     169        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
     170        {
     171            Controller* controller = 0;
     172
     173            if (it->getController())
     174                controller = it->getController();
     175            else if (it->getXMLController())
     176                controller = it->getXMLController();
     177
     178            if (!controller)
     179                continue;
     180
     181            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
     182
     183            if(aiController && aiController->state_ == MASTER)
     184            {
     185                if (action == 1)
     186                    aiController->spinInit();
     187                if (action == 2)
     188                    aiController->turn180Init();
     189            }
     190        }
     191    }
     192
     193    /**
     194        @brief A human player gets followed by its nearest master. Initiated by console command, so far intended for demonstration puproses (possible future pickup).
     195    */
     196    void ArtificialController::followme()
     197    {
     198
     199        Pawn *humanPawn = NULL;
     200        NewHumanController *currentHumanController = NULL;
     201        std::vector<ArtificialController*> allMasters;
     202
     203        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
     204        {
     205            Controller* controller = 0;
     206
     207            if (it->getController())
     208                controller = it->getController();
     209            else if (it->getXMLController())
     210                controller = it->getXMLController();
     211
     212            if (!controller)
     213                continue;
     214
     215            currentHumanController = orxonox_cast<NewHumanController*>(controller);
     216
     217            if(currentHumanController) humanPawn = *it;
     218
     219            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
     220
     221            if(aiController && aiController->state_ == MASTER)
     222                allMasters.push_back(aiController);
     223
     224        }
     225
     226        if((humanPawn != NULL) && (allMasters.size() != 0))
     227        {
     228                float posHuman = humanPawn->getPosition().length();
     229                float distance = 0.0f;
     230                float minDistance = FLT_MAX;
     231                int index = 0;
     232                int i = 0;
     233
     234                for(std::vector<ArtificialController*>::iterator it = allMasters.begin(); it != allMasters.end(); it++, i++)
     235                    {
     236                        if (!ArtificialController::sameTeam((*it)->getControllableEntity(), humanPawn, (*it)->getGametype())) continue;
     237                        distance = posHuman - (*it)->getControllableEntity()->getPosition().length();
     238                        if(distance < minDistance) index = i;
     239                    }
     240                allMasters[index]->followInit(humanPawn);
     241            }
     242
     243    }
     244
     245    /**
     246        @brief Sets shooting behaviour of pawns.
     247        @param passive if true, bots won't shoot.
     248    */
     249    void ArtificialController::passivebehaviour(const bool passive)
     250    {
     251        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
     252        {
     253            Controller* controller = 0;
     254
     255            if (it->getController())
     256                controller = it->getController();
     257            else if (it->getXMLController())
     258                controller = it->getXMLController();
     259
     260            if (!controller)
     261                continue;
     262
     263            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
     264
     265            if(aiController)
     266            {
     267                aiController->passive_ = passive;
     268            }
     269        }
     270    }
     271
     272
     273    /**
     274        @brief Sets maximal formation size
     275        @param size maximal formation size.
     276    */
     277    void ArtificialController::formationsize(const int size)
     278    {
     279        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
     280        {
     281            Controller* controller = 0;
     282
     283            if (it->getController())
     284                controller = it->getController();
     285            else if (it->getXMLController())
     286                controller = it->getXMLController();
     287
     288            if (!controller)
     289                continue;
     290
     291            ArtificialController *aiController = orxonox_cast<ArtificialController*>(controller);
     292
     293            if(aiController)
     294            {
     295                aiController->maxFormationSize_ = size;
     296            }
     297        }
     298    }
     299
     300    /**
     301        @brief Gets called when ControllableEntity is being changed. Resets the bot when it dies.
     302    */
     303    void ArtificialController::changedControllableEntity()
     304    {
     305        if (!this->getControllableEntity())
     306            this->removeFromFormation();
     307    }
     308
     309    void ArtificialController::removeFromFormation()
     310    {
     311        if (this->state_ == SLAVE || this->myMaster_) // slaves can also be temporary free, so check if myMaster_ is set
     312            this->unregisterSlave();
     313        else if (this->state_ == MASTER)
     314            this->setNewMasterWithinFormation();
    54315    }
    55316
     
    59320            return;
    60321
     322        // Slave uses special movement if its master is in FOLLOW mode
     323        if(this->state_ == SLAVE && this->myMaster_ && this->myMaster_->specificMasterAction_ == FOLLOW)
     324        {
     325//             this->followForSlaves(target);
     326//             return;
     327        }
     328
    61329        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
    62330        float distance = (target - this->getControllableEntity()->getPosition()).length();
    63331
    64         if (this->target_ || distance > 10)
    65         {
    66             // Multiply with 0.8 to make them a bit slower
    67             this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
    68             this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
    69         }
    70 
    71         if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
    72             this->getControllableEntity()->moveFrontBack(-0.5f); // They don't brake with full power to give the player a chance
     332
     333        if(this->state_ == FREE)
     334        {
     335            if (this->target_ || distance > 10)
     336            {
     337                // Multiply with ROTATEFACTOR_FREE to make them a bit slower
     338                this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x);
     339                this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y);
     340            }
     341
     342            if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
     343            {
     344              this->getControllableEntity()->moveFrontBack(-0.05f); // They don't brake with full power to give the player a chance
     345            } else this->getControllableEntity()->moveFrontBack(SPEED_FREE);
     346        }
     347
     348
     349
     350        if(this->state_ == MASTER)
     351        {
     352            if (this->target_ || distance > 10)
     353            {
     354                this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x);
     355                this->getControllableEntity()->rotatePitch(ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y);
     356            }
     357
     358            if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
     359            {
     360                this->getControllableEntity()->moveFrontBack(-0.05f);
     361            } else this->getControllableEntity()->moveFrontBack(SPEED_MASTER);
     362        }
     363
     364
     365
     366        if(this->state_ == SLAVE)
     367        {
     368
     369           this->getControllableEntity()->rotateYaw(-2.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x);
     370           this->getControllableEntity()->rotatePitch(2.0f * ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y);
     371
     372            if (distance < 300)
     373            {
     374                if (distance < 40)
     375                {
     376                    this->getControllableEntity()->moveFrontBack(0.8f*SPEED_MASTER);
     377                } else this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER);
     378
     379            } else {
     380                this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER + distance/300.0f);
     381            }
     382        }
     383    }
     384
     385    void ArtificialController::moveToTargetPosition()
     386    {
     387        this->moveToPosition(this->targetPosition_);
     388    }
     389
     390
     391    /**
     392        @brief Unregisters a slave from its master. Initiated by a slave.
     393    */
     394    void ArtificialController::unregisterSlave()
     395    {
     396        if (this->myMaster_)
     397        {
     398            std::vector<ArtificialController*>::iterator it = std::find(this->myMaster_->slaves_.begin(), this->myMaster_->slaves_.end(), this);
     399            if (it != this->myMaster_->slaves_.end())
     400                this->myMaster_->slaves_.erase(it);
     401        }
     402
     403        this->myMaster_ = 0;
     404        this->state_ = FREE;
     405    }
     406
     407    void ArtificialController::searchNewMaster()
     408    {
     409
     410        if (!this->getControllableEntity())
     411            return;
     412
     413        this->targetPosition_ = this->getControllableEntity()->getPosition();
     414        this->forgetTarget();
     415        int teamSize = 0;
     416        //go through all pawns
     417        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
     418        {
     419            //same team?
     420            if (!ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
     421                continue;
     422
     423            //has it an ArtificialController?
     424            Controller* controller = 0;
     425
     426            if (it->getController())
     427                controller = it->getController();
     428            else if (it->getXMLController())
     429                controller = it->getXMLController();
     430
     431            if (!controller)
     432                continue;
     433
     434            //is pawn oneself?
     435            if (orxonox_cast<ControllableEntity*>(*it) == this->getControllableEntity())
     436                continue;
     437
     438            teamSize++;
     439
     440            ArtificialController *newMaster = orxonox_cast<ArtificialController*>(controller);
     441
     442            //is it a master?
     443            if (!newMaster || newMaster->state_ != MASTER)
     444                continue;
     445
     446            float distance = (it->getPosition() - this->getControllableEntity()->getPosition()).length();
     447
     448            // is pawn in range?
     449            if (distance < RADIUS_TO_SEARCH_FOR_MASTERS)
     450            {
     451                if(newMaster->slaves_.size() > this->maxFormationSize_) continue;
     452
     453                for(std::vector<ArtificialController*>::iterator itSlave = this->slaves_.begin(); itSlave != this->slaves_.end(); itSlave++)
     454                {
     455                    (*itSlave)->myMaster_ = newMaster;
     456                    newMaster->slaves_.push_back(*itSlave);
     457                }
     458                this->slaves_.clear();
     459                this->state_ = SLAVE;
     460
     461                this->myMaster_ = newMaster;
     462                newMaster->slaves_.push_back(this);
     463
     464                break;
     465            }
     466        }
     467
     468        if (this->state_ != SLAVE  && teamSize != 0)
     469        {
     470            this->state_ = MASTER;
     471            this->myMaster_ = 0;
     472        }
     473    }
     474
     475    /**
     476        @brief Commands the slaves of a master into a formation. Sufficiently fast not to be called within tick. Initiated by a master.
     477    */
     478    void ArtificialController::commandSlaves()
     479    {
     480        if(this->state_ != MASTER) return;
     481
     482        Quaternion orient = this->getControllableEntity()->getOrientation();
     483        Vector3 dest = this->getControllableEntity()->getPosition();
     484
     485        // 1 slave: follow
     486        if (this->slaves_.size() == 1)
     487        {
     488            dest += 4*orient*WorldEntity::BACK;
     489            this->slaves_.front()->setTargetPosition(dest);
     490        }
    73491        else
    74             this->getControllableEntity()->moveFrontBack(0.8f);
    75     }
    76 
    77     void ArtificialController::moveToTargetPosition()
    78     {
    79         this->moveToPosition(this->targetPosition_);
    80     }
     492        {
     493            dest += 1.0f*orient*WorldEntity::BACK;
     494            Vector3 pos = Vector3::ZERO;
     495            int i = 1;
     496
     497            for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
     498            {
     499                pos = Vector3::ZERO;
     500                if (i <= 1) pos += dest  + FORMATION_WIDTH*(orient*WorldEntity::LEFT);
     501                if (i == 2) pos += dest  + FORMATION_WIDTH*(orient*WorldEntity::RIGHT);
     502                if (i == 3) pos += dest  + FORMATION_WIDTH*(orient*WorldEntity::UP);
     503                if (i >= 4)
     504                {
     505                    pos += dest  + FORMATION_WIDTH*(orient*WorldEntity::DOWN);
     506                    i = 1;
     507                    dest += FORMATION_LENGTH*(orient*WorldEntity::BACK);
     508                    (*it)->setTargetPosition(pos);
     509                    continue;
     510                }
     511                i++;
     512                (*it)->setTargetPosition(pos);
     513            }
     514        }
     515    }
     516
     517    /**
     518        @brief Sets a new master within the formation. Called by a master.
     519    */
     520    void ArtificialController::setNewMasterWithinFormation()
     521    {
     522        if(this->state_ != MASTER) return;
     523
     524        if (!this->slaves_.empty())
     525        {
     526            ArtificialController *newMaster = this->slaves_.back();
     527            this->slaves_.pop_back();
     528
     529            newMaster->state_ = MASTER;
     530            newMaster->slaves_ = this->slaves_;
     531            newMaster->myMaster_ = 0;
     532
     533            for(std::vector<ArtificialController*>::iterator it = newMaster->slaves_.begin(); it != newMaster->slaves_.end(); it++)
     534            {
     535                (*it)->myMaster_ = newMaster;
     536            }
     537        }
     538
     539        this->slaves_.clear();
     540        this->specificMasterAction_ = NONE;
     541        this->state_ = FREE;
     542    }
     543
     544    /**
     545        @brief Frees all slaves form a master. Initiated by a master.
     546    */
     547    void ArtificialController::freeSlaves()
     548    {
     549        if(this->state_ != MASTER) return;
     550
     551        for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
     552        {
     553            (*it)->state_ = FREE;
     554            (*it)->myMaster_ = 0;
     555        }
     556        this->slaves_.clear();
     557    }
     558
     559    /**
     560        @brief Master sets its slaves free for @var FREEDOM_COUNT seconds.
     561    */
     562    void ArtificialController::forceFreeSlaves()
     563    {
     564        if(this->state_ != MASTER) return;
     565
     566        for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
     567        {
     568            (*it)->state_ = FREE;
     569            (*it)->forceFreedom();
     570            (*it)->targetPosition_ = this->targetPosition_;
     571            (*it)->bShooting_ = true;
     572//             (*it)->getControllableEntity()->fire(0);// fire once for fun
     573        }
     574    }
     575
     576    void ArtificialController::loseMasterState()
     577    {
     578        this->freeSlaves();
     579        this->state_ = FREE;
     580    }
     581
     582
     583    void ArtificialController::forceFreedom()
     584    {
     585        this->freedomCount_ = FREEDOM_COUNT;
     586    }
     587
     588    /**
     589        @brief Checks wether caller has been forced free, decrements time to stay forced free.
     590        @return true if forced free.
     591    */
     592    bool ArtificialController::forcedFree()
     593    {
     594        if(this->freedomCount_ > 0)
     595        {
     596            this->freedomCount_--;
     597            return true;
     598        } else return false;
     599    }
     600
     601    /**
     602        @brief Used to continue a "specific master action" for a certain time and resuming normal behaviour after.
     603    */
     604    void ArtificialController::specificMasterActionHold()
     605    {
     606        if(this->state_ != MASTER) return;
     607
     608        if (specificMasterActionHoldCount_ == 0)
     609         {
     610            this->specificMasterAction_ = NONE;
     611            this->searchNewTarget();
     612         }
     613        else specificMasterActionHoldCount_--;
     614    }
     615
     616    /**
     617        @brief Master initializes a 180 degree turn. Leads to a "specific master action".
     618    */
     619    void ArtificialController::turn180Init()
     620    {
     621        if(this->state_ != MASTER) return;
     622
     623        Quaternion orient = this->getControllableEntity()->getOrientation();
     624
     625        this->setTargetPosition(this->getControllableEntity()->getPosition() + 1000.0f*orient*WorldEntity::BACK);
     626
     627        this->specificMasterActionHoldCount_ = 4;
     628
     629        this->specificMasterAction_ = TURN180;
     630    }
     631
     632    /**
     633        @brief Execute the 180 degree turn. Called within tick.
     634    */
     635    void ArtificialController::turn180()
     636    {
     637            Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->targetPosition_);
     638
     639            this->getControllableEntity()->rotateYaw(-2.0f * sgn(coord.x) * coord.x*coord.x);
     640            this->getControllableEntity()->rotatePitch(2.0f * sgn(coord.y) * coord.y*coord.y);
     641
     642            this->getControllableEntity()->moveFrontBack(SPEED_MASTER);
     643    }
     644
     645    /**
     646        @brief Master initializes a spin around its looking direction axis. Leads to a "specific master action".
     647    */
     648    void ArtificialController::spinInit()
     649    {
     650        if(this->state_ != MASTER) return;
     651        this->specificMasterAction_ = SPIN;
     652        this->specificMasterActionHoldCount_ = 10;
     653    }
     654
     655    /**
     656        @brief Execute the spin. Called within tick.
     657    */
     658    void ArtificialController::spin()
     659    {
     660            this->moveToTargetPosition();
     661            this->getControllableEntity()->rotateRoll(0.8f);
     662    }
     663
     664    /**
     665        @brief Master begins to follow a pawn. Is a "specific master action".
     666        @param pawn pawn to follow.
     667        @param alaways follows pawn forever if true (false if omitted).
     668        @param secondsToFollow seconds to follow the pawn if always is false. Will follow pawn 100 seconds if omitted (set in header).
     669    */
     670    void ArtificialController::followInit(Pawn* pawn, const bool always, const int secondsToFollow)
     671    {
     672        if (pawn == NULL || this->state_ != MASTER)
     673            return;
     674        this->specificMasterAction_  =  FOLLOW;
     675
     676        this->setTarget(pawn);
     677        if (!always)
     678            this->specificMasterActionHoldCount_ = secondsToFollow;
     679        else
     680            this->specificMasterActionHoldCount_ = INT_MAX; //for now...
     681
     682    }
     683
     684
     685    /**
     686        @brief Master begins to follow a randomly chosen human player of the same team. Is a "specific master action".
     687    */
     688    void ArtificialController::followRandomHumanInit()
     689    {
     690
     691        Pawn *humanPawn = NULL;
     692        NewHumanController *currentHumanController = NULL;
     693
     694        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
     695        {
     696            if (!it->getController())
     697                continue;
     698
     699            currentHumanController = orxonox_cast<NewHumanController*>(it->getController());
     700            if(currentHumanController)
     701            {
     702                if (!ArtificialController::sameTeam(this->getControllableEntity(), *it, this->getGametype())) continue;
     703                humanPawn = *it;
     704                break;
     705            }
     706        }
     707
     708        if((humanPawn != NULL))
     709                this->followInit(humanPawn);
     710    }
     711
     712    /**
     713        @brief Master follows target with adjusted speed. Called within tick.
     714    */
     715    void ArtificialController::follow()
     716    {
     717        if (this->target_)
     718            this->moveToPosition(this->target_->getPosition());
     719        else
     720            this->specificMasterActionHoldCount_ = 0;
     721/*
     722        if (!this->getControllableEntity())
     723            return;
     724
     725        float distance = (this->target_->getPosition() - this->getControllableEntity()->getPosition()).length();
     726
     727        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->target_->getPosition());
     728
     729
     730        this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
     731        this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
     732
     733        float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->target_->getVelocity().squaredLength();
     734
     735COUT(0) << "~follow distance: " << distance << "SpeedCounter: " << this->speedCounter_ << "~speedDiv: " << speedDiv << std::endl;
     736        if (distance < 800)
     737        {
     738            if (distance < 200)
     739            {
     740                this->speedCounter_ -= 0.5f;
     741                if(this->speedCounter_ < 0) this->speedCounter_ = 0.0f;
     742                this->getControllableEntity()->moveFrontBack(speedCounter_);
     743            } else {
     744                if(speedDiv < 0)
     745                    this->speedCounter_ +=  0.01f;
     746                else
     747                    this->speedCounter_ -= 0.05f;
     748                this->getControllableEntity()->moveFrontBack(speedCounter_);
     749            }
     750
     751        } else {
     752            this->speedCounter_ += 0.05f;
     753            this->getControllableEntity()->moveFrontBack(speedCounter_ + distance/300.0f);
     754        }
     755//         if (this->getControllableEntity()->getVelocity().squaredLength() > 50.0f) this->speedCounter_ = 0;
     756
     757*/
     758    }
     759
     760
     761    /**
     762        @brief Slave moving behaviour when master is following a pawn, gets redirected from moveToPosition(const Vector3& target)). Called within tick.
     763    */
     764    void ArtificialController::followForSlaves(const Vector3& target)
     765    {
     766
     767/*
     768        if (!this->getControllableEntity() && !this->myMaster_ && this->myMaster_->state_ != FOLLOW && !this->myMaster_->target_)
     769            return;
     770
     771        float distance = (target - this->getControllableEntity()->getPosition()).length();
     772
     773        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
     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
     780        float speedDiv = this->getControllableEntity()->getVelocity().squaredLength() - this->myMaster_->target_->getVelocity().squaredLength();
     781
     782
     783         if (distance < 800)
     784        {
     785            if (distance < 200)
     786            {
     787                this->speedCounter_ -= 5.0f;
     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
    81806
    82807    void ArtificialController::setTargetPosition(const Vector3& target)
     
    111836        {
    112837            if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
     838                continue;
     839
     840            /* So AI won't choose invisible Spaceships as target */
     841            if (!it->getRadarVisibility())
    113842                continue;
    114843
     
    144873        this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO);
    145874
    146         Pawn* pawn = dynamic_cast<Pawn*>(this->getControllableEntity());
     875        Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
    147876        if (pawn)
    148877            pawn->setAimPosition(this->targetPosition_);
     
    188917        int team2 = -1;
    189918
    190         if (entity1->getXMLController())
    191         {
    192             WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity1->getXMLController());
    193             if (wpc)
    194                 team1 = wpc->getTeam();
    195         }
    196         if (entity2->getXMLController())
    197         {
    198             WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity2->getXMLController());
    199             if (wpc)
    200                 team2 = wpc->getTeam();
     919        Controller* controller = 0;
     920        if (entity1->getController())
     921            controller = entity1->getController();
     922        else
     923            controller = entity1->getXMLController();
     924        if (controller)
     925        {
     926            ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
     927            if (ac)
     928                team1 = ac->getTeam();
     929        }
     930
     931        if (entity2->getController())
     932            controller = entity2->getController();
     933        else
     934            controller = entity2->getXMLController();
     935        if (controller)
     936        {
     937            ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
     938            if (ac)
     939                team2 = ac->getTeam();
    201940        }
    202941
     
    245984        }
    246985
     986        DroneController* droneController = 0;
     987        droneController = orxonox_cast<DroneController*>(entity1->getController());
     988        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)
     989            return true;
     990        droneController = orxonox_cast<DroneController*>(entity2->getController());
     991        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)
     992            return true;
     993        DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController());
     994        DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController());
     995        if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner())
     996            return true;
     997
     998        Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype);
     999        if (dynamic)
     1000        {
     1001            if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;}
     1002
     1003            if (entity1->getPlayer())
     1004                team1 = dynamic->getParty(entity1->getPlayer());
     1005
     1006            if (entity2->getPlayer())
     1007                team2 = dynamic->getParty(entity2->getPlayer());
     1008
     1009            if (team1 ==-1 ||team2 ==-1 ) {return false;}
     1010            else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;}
     1011            else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;}
     1012            else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;}
     1013            else return true;
     1014        }
     1015
    2471016        return (team1 == team2 && team1 != -1);
    2481017    }
Note: See TracChangeset for help on using the changeset viewer.