Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ai/src/orxonox/controllers/ArtificialController.cc @ 6978

Last change on this file since 6978 was 6978, checked in by solex, 15 years ago

consle commands

  • Property svn:eol-style set to native
File size: 24.6 KB
RevLine 
[2362]1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
[6978]25 *      Dominik Solenicki
[2362]26 *
27 */
28
29#include "ArtificialController.h"
30
[6978]31#include <vector>
[2362]32#include "core/CoreIncludes.h"
[6601]33#include "core/XMLPort.h"
[5735]34#include "worldentities/ControllableEntity.h"
35#include "worldentities/pawns/Pawn.h"
36#include "worldentities/pawns/TeamBaseMatchBase.h"
37#include "gametypes/TeamDeathmatch.h"
38#include "controllers/WaypointPatrolController.h"
[6978]39#include "controllers/NewHumanController.h"
[6918]40#include "controllers/DroneController.h"
[6888]41#include "util/Math.h"
[6958]42#include "core/ConsoleCommand.h"
[3049]43
[2362]44namespace orxonox
45{
[6978]46    SetConsoleCommand(ArtificialController, formationflight, true);
[6958]47    SetConsoleCommand(ArtificialController, masteraction, true);
[6978]48    SetConsoleCommand(ArtificialController, followme, true);
49    SetConsoleCommand(ArtificialController, passivbehaviour, true);
[6888]50
[6919]51    static const unsigned int MAX_FORMATION_SIZE = 7;
52    static const int FORMATION_LENGTH =  10;
53    static const int FORMATION_WIDTH =  110;
[6888]54    static const int FREEDOM_COUNT = 4; //seconds the slaves in a formation will be set free when master attacks an enemy
55    static const float SPEED_MASTER = 0.6f;
56    static const float ROTATEFACTOR_MASTER = 0.2f;
57    static const float SPEED_FREE = 0.8f;
58    static const float ROTATEFACTOR_FREE = 0.8f;
[6978]59    static const int SECONDS_TO_FOLLOW_HUMAN = 10;
[6888]60
[2362]61    ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator)
62    {
63        RegisterObject(ArtificialController);
64
65        this->target_ = 0;
[6958]66        this->formationFlight_ = true;
[6978]67        this->passive_ = false;
[6695]68        this->myMaster_ = 0;
[6850]69        this->freedomCount_ = 0;
70        this->team_ = -1;
71        this->state_ = FREE;
[6919]72        this->specificMasterAction_ = NONE;
73        this->specificMasterActionHoldCount_  = 0;
[2362]74        this->bShooting_ = false;
75        this->bHasTargetPosition_ = false;
76        this->targetPosition_ = Vector3::ZERO;
[6978]77        this->humanToFollow_ = NULL;
[6417]78
[5929]79        this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this));
[2362]80    }
81
82    ArtificialController::~ArtificialController()
83    {
84    }
85
[6601]86    void ArtificialController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
87    {
88        SUPER(ArtificialController, XMLPort, xmlelement, mode);
89
[6919]90        XMLPortParam(ArtificialController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(-1);
[6958]91        XMLPortParam(ArtificialController, "formation", setFormationFlight, getFormationFlight, xmlelement, mode).defaultValues(true);
[6601]92    }
93
[6978]94// Documentation only here to get a faster overview for creating a useful documentation, what you're reading here not intended for an actual documentation...
95
96    /**
97        @brief Activates / deactivates formationflight behaviour
98        @param form activate formflight if form is true
99    */
[6958]100    void ArtificialController::formationflight(bool form)
101    {
102        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
103        {
104            if (!it->getController())
105                continue;
106
107            ArtificialController *aiController = static_cast<ArtificialController*>(it->getController());
108
109            if(aiController)
110            {
111                aiController->formationFlight_ = form;
112            }
113        }
114    }
[6978]115
116    /**
117        @brief Get all masters to do a specific action
118        @param action which action to perform (integer, so it can be called with a console command (tmp solution))
119    */
[6958]120    void ArtificialController::masteraction(int action) 
121    {
122        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
123        {
124            if (!it->getController())
125                continue;
126
127            ArtificialController *aiController = static_cast<ArtificialController*>(it->getController());
128
129            if(aiController || aiController->state_ == MASTER)
130            {
131                aiController->specificMasterAction_ = TURN180;
132            }
133        }
134    }
135
[6978]136    /**
137        @brief A human player gets followed by its nearest master. Initiated by console command, only for demonstration puproses. Does not work at the moment.
138    */
139    void ArtificialController::followme()
140    {
141
142        Pawn *humanPawn = NULL;
143        NewHumanController *currentHumanController = NULL;
144        std::vector<ArtificialController*> allMasters;
145
146        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
147        {
148            if (!it->getController())
149                continue;
150
151            currentHumanController = static_cast<NewHumanController*>(it->getController());
152
153            if(currentHumanController) humanPawn = *it;
154
155            ArtificialController *aiController = static_cast<ArtificialController*>(it->getController());
156
157            if(aiController || aiController->state_ == MASTER)
158                allMasters.push_back(aiController);
159
160        }
161        /*if((humanPawn != NULL) && (allMasters.size != 0))
162        {
163
164                float posHuman = humanPawn->getPosition().length();
165                float distance = 0.0f;
166                float minDistance = posHuman - allMasters.back()->getControllableEntity()->getPosition().length();
167                int index = 0;
168                int i = 0;
169
170                for(std::vector<ArtificialController*>::iterator it = allMasters.begin(); it != allMasters.end(); it++)
171                    {
172                        distance = posHuman - (*it)->getControllableEntity()->getPosition().length();
173                        if(distance < minDistance) index = i;
174                    }
175                allMasters[index].humanToFollow_ = humanPawn;
176                allMasters[index].followHuman(humanPawn, false);
177            }*/
178
179    }
180
181    /**
182        @brief Sets shootingbehaviour of pawns.
183        @param passive if true, pawns won't shoot.
184    */
185    void ArtificialController::passivebehaviour(bool passive)
186    {
187        this->passive_ = passive;
188    }
189
190    /**
191        @brief Gets called if ControllableEntity is changed. Resets the bot when it dies.
192    */
[6850]193    void ArtificialController::changedControllableEntity()
194    {
195        if(!getControllableEntity()) 
196        {
197        if (this->state_ == SLAVE) unregisterSlave();
198         if (this->state_ == MASTER) setNewMasterWithinFormation();
199        this->slaves_.clear();
200        this->state_ = FREE;
[6888]201
[6850]202        }
203    }
204
[6978]205
[3049]206    void ArtificialController::moveToPosition(const Vector3& target)
[2362]207    {
208        if (!this->getControllableEntity())
209            return;
210
[3049]211        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
212        float distance = (target - this->getControllableEntity()->getPosition()).length();
[2362]213
[6888]214
215        if(this->state_ == FREE)
[2362]216        {
[6888]217            if (this->target_ || distance > 10)
218            {
219                // Multiply with 0.8 to make them a bit slower
220                this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_FREE * sgn(coord.x) * coord.x*coord.x);
221                this->getControllableEntity()->rotatePitch(ROTATEFACTOR_FREE * sgn(coord.y) * coord.y*coord.y);
222            }
[6850]223
[6888]224            if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
225            {
226              this->getControllableEntity()->moveFrontBack(-0.05f); // They don't brake with full power to give the player a chance
227            } else this->getControllableEntity()->moveFrontBack(SPEED_FREE);
228        }
[6850]229
230
231
[6888]232        if(this->state_ == MASTER)
233        {
234            if (this->target_ || distance > 10)
235            {
[6958]236                if (this->specificMasterAction_ == NONE)
237                {
[6888]238                this->getControllableEntity()->rotateYaw(-1.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x);
239                this->getControllableEntity()->rotatePitch(ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y);
[6958]240                } else if (this->specificMasterAction_ == TURN180)
241                {
242                this->getControllableEntity()->rotateYaw(-1.0f * sgn(coord.x) * coord.x*coord.x);
243                this->getControllableEntity()->rotatePitch(sgn(coord.y) * coord.y*coord.y);
244                }
[6888]245
246            }
247
248            if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
249            {
250                this->getControllableEntity()->moveFrontBack(-0.05f);
251            } else this->getControllableEntity()->moveFrontBack(SPEED_MASTER);
[2362]252        }
253
[6888]254
255
256        if(this->state_ == SLAVE)
[6850]257        {
[6888]258
[6919]259           this->getControllableEntity()->rotateYaw(-2.0f * ROTATEFACTOR_MASTER * sgn(coord.x) * coord.x*coord.x);
260           this->getControllableEntity()->rotatePitch(2.0f * ROTATEFACTOR_MASTER * sgn(coord.y) * coord.y*coord.y);
[6888]261
[6919]262            if (distance < 300)
[6888]263            {
[6919]264                if (distance < 40)
[6888]265                {
[6919]266                    this->getControllableEntity()->moveFrontBack(0.8f*SPEED_MASTER);
267                } else this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER);
[6888]268
269            } else {
[6919]270                this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER + distance/300.0f);
[6888]271            }
[6850]272        }
[2362]273    }
274
[3049]275    void ArtificialController::moveToTargetPosition()
276    {
277        this->moveToPosition(this->targetPosition_);
278    }
279
[6640]280    int ArtificialController::getState()
281    {
282        return this->state_;
283    }
284
[6978]285    /**
286        @brief Unregisters a slave from its master. Called by a slave.
287    */
[6695]288    void ArtificialController::unregisterSlave() {
289        if(myMaster_)
290        {
[6888]291            std::vector<ArtificialController*>::iterator it = std::find(myMaster_->slaves_.begin(), myMaster_->slaves_.end(), this);
292            if( it != myMaster_->slaves_.end() )
293                myMaster_->slaves_.erase(it);
[6695]294        }
295    }
296
[6640]297    void ArtificialController::searchNewMaster()
298    {
[6695]299
[6640]300        if (!this->getControllableEntity())
301            return;
302
303        this->targetPosition_ = this->getControllableEntity()->getPosition();
304        this->forgetTarget();
[6919]305        int teamSize = 0;
[6640]306        //go through all pawns
307        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
308        {
[6695]309
310            //same team?
[6640]311            if (!ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
312                continue;
313
[6919]314            //has it an ArtificialController?
[6695]315            if (!it->getController())
316                continue;
[6640]317
[6919]318            //is pawn oneself?
319            if (static_cast<ControllableEntity*>(*it) == this->getControllableEntity())
320                continue;
321
322            teamSize++;
323
[6850]324            ArtificialController *newMaster = static_cast<ArtificialController*>(it->getController());
325
[6919]326            //is it a master?
[6850]327            if (!newMaster || newMaster->getState() != MASTER)
[6640]328                continue;
329
[6888]330            float distance = (it->getPosition() - this->getControllableEntity()->getPosition()).length();
331
[6919]332            // is pawn in range?
333            if (distance < 5000)
[6640]334            {
[6888]335                if(newMaster->slaves_.size() > MAX_FORMATION_SIZE) continue;
[6696]336
[6888]337                for(std::vector<ArtificialController*>::iterator itSlave = this->slaves_.begin(); itSlave != this->slaves_.end(); itSlave++)
[6850]338                {
339                    (*itSlave)->myMaster_ = newMaster;
340                    newMaster->slaves_.push_back(*itSlave);
341                }
[6795]342                this->slaves_.clear();
[6683]343                this->state_ = SLAVE;
[6696]344
[6850]345                this->myMaster_ = newMaster;
346                newMaster->slaves_.push_back(this);
[6696]347
[6695]348                break;
[6640]349            }
[6978]350        }
[6640]351
[6978]352        if (state_ != SLAVE  && teamSize != 0) state_ = MASTER;
353
[6640]354    }
355
[6978]356    /**
357        @brief Commands the slaves of a master into a formation. Called by a master.
358    */
359    void ArtificialController::commandSlaves() 
360    {
361        if(this->state_ != MASTER) return;
[6683]362
[6888]363        Quaternion orient = this->getControllableEntity()->getOrientation();
364        Vector3 dest = this->getControllableEntity()->getPosition();
365
366        // 1 slave: follow
367        if (this->slaves_.size() == 1)
[6695]368        {
[6888]369            dest += 4*orient*WorldEntity::BACK;
370            this->slaves_.front()->setTargetPosition(dest);
[6695]371        }
[6919]372        else 
[6888]373        {
[6919]374            dest += 1.0f*orient*WorldEntity::BACK;
375            Vector3 pos = Vector3::ZERO;
376            int i = 1;
[6888]377
378            for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
379            {
[6919]380                pos = Vector3::ZERO;
381                if (i <= 1) pos += dest  + FORMATION_WIDTH*WorldEntity::LEFT;
382                if (i == 2) pos += dest  + FORMATION_WIDTH*WorldEntity::RIGHT;
383                if (i == 3) pos += dest  + FORMATION_WIDTH*WorldEntity::UP;
384                if (i >= 4)
385                {
386                    pos += dest  + FORMATION_WIDTH*WorldEntity::DOWN;
387                    i = 1;
388                    dest += FORMATION_LENGTH*orient*WorldEntity::BACK;
389                    (*it)->setTargetPosition(pos);
390                    continue;
391                }
392                i++;
393                (*it)->setTargetPosition(pos);
[6888]394            }
395        }
[6683]396    }
397
[6978]398    /**
399        @brief Sets a new master within the formation. Called by a master.
400    */
[6795]401    void ArtificialController::setNewMasterWithinFormation()
402    {
[6978]403        if(this->state_ != MASTER) return;
[6888]404
[6795]405        if (this->slaves_.empty())
406            return;
407
408        ArtificialController *newMaster = this->slaves_.back();
409        this->slaves_.pop_back();
[6888]410
[6795]411        if(!newMaster) return;
412        newMaster->state_ = MASTER;
413        newMaster->slaves_ = this->slaves_;
[6888]414
[6850]415        this->slaves_.clear();
[6795]416        this->state_ = SLAVE;
417        this->myMaster_ = newMaster;
418
[6888]419        for(std::vector<ArtificialController*>::iterator it = newMaster->slaves_.begin(); it != newMaster->slaves_.end(); it++)
[6795]420        {
421            (*it)->myMaster_ = newMaster;
422        }
423
424    }
425
[6978]426    /**
427        @brief Frees all slaves form a master. Called by a master.
428    */
[6850]429    void ArtificialController::freeSlaves()
[6683]430    {
[6978]431        if(this->state_ != MASTER) return;
432
[6888]433        for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
[6696]434        {
435            (*it)->state_ = FREE;
436        }
[6850]437        this->slaves_.clear();
438    }
439
[6978]440    /**
441        @brief Master sets its slaves free for \var FREEDOM_COUNT seconds.
442    */
[6850]443    void ArtificialController::forceFreeSlaves()
444    {
[6978]445        if(this->state_ != MASTER) return;
446
[6888]447        for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
[6683]448        {
[6850]449            (*it)->state_ = FREE;
450            (*it)->forceFreedom();
451            (*it)->targetPosition_ = this->targetPosition_;
452            (*it)->bShooting_ = true;
[6888]453            (*it)->getControllableEntity()->fire(0);// fire once for fun
[6683]454        }
[6696]455    }
[6683]456
[6696]457    void ArtificialController::loseMasterState()
458    {
[6850]459        this->freeSlaves();
[6696]460        this->state_ = FREE;
[6683]461    }
462
[6978]463
[6850]464    void ArtificialController::forceFreedom()
465    {
[6888]466        this->freedomCount_ = FREEDOM_COUNT;
[6850]467    }
468
[6978]469    /**
470        @brief Checks wether caller has been forced free, decrements time to stay forced free.
471        @return true if forced free.
472    */
[6850]473    bool ArtificialController::forcedFree()
474    {
475        if(this->freedomCount_ > 0) 
476        {
477            this->freedomCount_--;
478            return true;
479        } else return false;
480    }
481
[6978]482    /**
483        @brief Used to continue a "specific master action" for a certain time.
484    */
[6919]485    void ArtificialController::specificMasterActionHold()
486    {
[6978]487        if(this->state_ != MASTER) return;
488
[6958]489        if (specificMasterActionHoldCount_ == 0) 
490         {
491            this->specificMasterAction_ = NONE;
492            this->searchNewTarget();
493         }
[6919]494        else specificMasterActionHoldCount_--;
495    }
496
[6978]497    /**
498        @brief Master engages a 180 degree turn. Is a "specific master action".
499    */
[6919]500    void ArtificialController::turn180()
501    {
[6978]502        if(this->state_ != MASTER) return;
503
[6958]504        COUT(0) << "~turn" << std::endl;
505
506        Quaternion orient = this->getControllableEntity()->getOrientation();
507
508        this->setTargetPosition(this->getControllableEntity()->getPosition() + 500.0f*orient*WorldEntity::BACK);
509        this->specificMasterActionHoldCount_ = 2;
510        this->specificMasterAction_  =  HOLD;
[6919]511    }
512
[6978]513    /**
514        @brief Master spins around looking directions axis. Is a "specific master action".
515    */
[6919]516    void ArtificialController::spin()
517    {
[6978]518        if(this->state_ != MASTER) return;
519
[6919]520        this->specificMasterAction_  =  NONE;
521    }
522
[6978]523    /**
524        @brief Master begins to follow a human player. Is a "specific master action".
525        @param humanController human to follow.
526        @param alaways follows human forever if true - yet only inplemented for false.
527    */
528    void ArtificialController::followHuman(Pawn* human, bool always)
529    {
530        if (human == NULL)
531        {
532            this->specificMasterAction_ = NONE;
533            return;
534        }
535        if (!always)
536        {
537            this->setTarget(human);
538            this->specificMasterActionHoldCount_ = SECONDS_TO_FOLLOW_HUMAN;
539            this->specificMasterAction_  =  HOLD;
540        }
[6919]541
[6978]542    }
543
544
[3049]545    void ArtificialController::setTargetPosition(const Vector3& target)
546    {
547        this->targetPosition_ = target;
548        this->bHasTargetPosition_ = true;
549    }
550
[2362]551    void ArtificialController::searchRandomTargetPosition()
552    {
[2493]553        this->targetPosition_ = Vector3(rnd(-2000,2000), rnd(-2000,2000), rnd(-2000,2000));
[2362]554        this->bHasTargetPosition_ = true;
555    }
556
[3049]557    void ArtificialController::setTarget(Pawn* target)
558    {
559        this->target_ = target;
560
561        if (target)
562            this->targetPosition_ = target->getPosition();
563    }
564
[2362]565    void ArtificialController::searchNewTarget()
566    {
567        if (!this->getControllableEntity())
568            return;
569
570        this->targetPosition_ = this->getControllableEntity()->getPosition();
571        this->forgetTarget();
572
573        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
574        {
[3049]575            if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
576                continue;
577
[2506]578            if (static_cast<ControllableEntity*>(*it) != this->getControllableEntity())
[2362]579            {
580                float speed = this->getControllableEntity()->getVelocity().length();
581                Vector3 distanceCurrent = this->targetPosition_ - this->getControllableEntity()->getPosition();
582                Vector3 distanceNew = it->getPosition() - this->getControllableEntity()->getPosition();
583                if (!this->target_ || it->getPosition().squaredDistance(this->getControllableEntity()->getPosition()) * (1.5f + acos((this->getControllableEntity()->getOrientation() * WorldEntity::FRONT).dotProduct(distanceNew) / speed / distanceNew.length()) / (2 * Ogre::Math::PI))
584                        < this->targetPosition_.squaredDistance(this->getControllableEntity()->getPosition()) * (1.5f + acos((this->getControllableEntity()->getOrientation() * WorldEntity::FRONT).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / (2 * Ogre::Math::PI)) + rnd(-250, 250))
585                {
586                    this->target_ = (*it);
587                    this->targetPosition_ = it->getPosition();
588                }
589            }
590        }
591    }
592
593    void ArtificialController::forgetTarget()
594    {
595        this->target_ = 0;
596        this->bShooting_ = false;
597    }
598
599    void ArtificialController::aimAtTarget()
600    {
601        if (!this->target_ || !this->getControllableEntity())
602            return;
603
[2493]604        static const float hardcoded_projectile_speed = 1250;
[2362]605
[2493]606        this->targetPosition_ = getPredictedPosition(this->getControllableEntity()->getPosition(), hardcoded_projectile_speed, this->target_->getPosition(), this->target_->getVelocity());
[2362]607        this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO);
[6417]608
609        Pawn* pawn = dynamic_cast<Pawn*>(this->getControllableEntity());
610        if (pawn)
611            pawn->setAimPosition(this->targetPosition_);
[2362]612    }
613
614    bool ArtificialController::isCloseAtTarget(float distance) const
615    {
616        if (!this->getControllableEntity())
617            return false;
618
619        if (!this->target_)
620            return (this->getControllableEntity()->getPosition().squaredDistance(this->targetPosition_) < distance*distance);
621        else
622            return (this->getControllableEntity()->getPosition().squaredDistance(this->target_->getPosition()) < distance*distance);
623    }
624
625    bool ArtificialController::isLookingAtTarget(float angle) const
626    {
627        if (!this->getControllableEntity())
628            return false;
629
630        return (getAngle(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->targetPosition_) < angle);
631    }
632
[5929]633    void ArtificialController::abandonTarget(Pawn* target)
[2362]634    {
[5929]635        if (target == this->target_)
636            this->targetDied();
[2362]637    }
[3049]638
[5929]639    void ArtificialController::targetDied()
640    {
641        this->forgetTarget();
642        this->searchRandomTargetPosition();
643    }
644
[3049]645    bool ArtificialController::sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
646    {
647        if (entity1 == entity2)
648            return true;
649
650        int team1 = -1;
651        int team2 = -1;
652
[6601]653        Controller* controller = 0;
654        if (entity1->getController())
655            controller = entity1->getController();
656        else
657            controller = entity1->getXMLController();
658        if (controller)
[3049]659        {
[6601]660            ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
661            if (ac)
662                team1 = ac->getTeam();
[3049]663        }
[6601]664
665        if (entity1->getController())
666            controller = entity1->getController();
667        else
668            controller = entity1->getXMLController();
669        if (controller)
[3049]670        {
[6601]671            ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
672            if (ac)
673                team2 = ac->getTeam();
[3049]674        }
675
[3325]676        TeamDeathmatch* tdm = orxonox_cast<TeamDeathmatch*>(gametype);
[3049]677        if (tdm)
678        {
679            if (entity1->getPlayer())
680                team1 = tdm->getTeam(entity1->getPlayer());
681
682            if (entity2->getPlayer())
683                team2 = tdm->getTeam(entity2->getPlayer());
684        }
685
[3086]686        TeamBaseMatchBase* base = 0;
[3325]687        base = orxonox_cast<TeamBaseMatchBase*>(entity1);
[3086]688        if (base)
689        {
690            switch (base->getState())
691            {
[3280]692                case BaseState::ControlTeam1:
[3086]693                    team1 = 0;
694                    break;
[3280]695                case BaseState::ControlTeam2:
[3086]696                    team1 = 1;
697                    break;
[3280]698                case BaseState::Uncontrolled:
[3086]699                default:
700                    team1 = -1;
701            }
702        }
[3325]703        base = orxonox_cast<TeamBaseMatchBase*>(entity2);
[3086]704        if (base)
705        {
706            switch (base->getState())
707            {
[3280]708                case BaseState::ControlTeam1:
[3086]709                    team2 = 0;
710                    break;
[3280]711                case BaseState::ControlTeam2:
[3086]712                    team2 = 1;
713                    break;
[3280]714                case BaseState::Uncontrolled:
[3086]715                default:
716                    team2 = -1;
717            }
718        }
719
[6891]720        DroneController* droneController = 0;
721        droneController = orxonox_cast<DroneController*>(entity1->getController());
722        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)
723            return true;
724        droneController = orxonox_cast<DroneController*>(entity2->getController());
725        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)
726            return true;
[6958]727
[3049]728        return (team1 == team2 && team1 != -1);
729    }
[2362]730}
Note: See TracBrowser for help on using the repository browser.