Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6986 was 6986, checked in by solex, 14 years ago

nearly finished formationflight

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