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, 14 years ago

consle commands

  • Property svn:eol-style set to native
File size: 24.6 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, passivbehaviour, true);
50
51    static const unsigned int MAX_FORMATION_SIZE = 7;
52    static const int FORMATION_LENGTH =  10;
53    static const int FORMATION_WIDTH =  110;
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;
59    static const int SECONDS_TO_FOLLOW_HUMAN = 10;
60
61    ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator)
62    {
63        RegisterObject(ArtificialController);
64
65        this->target_ = 0;
66        this->formationFlight_ = true;
67        this->passive_ = false;
68        this->myMaster_ = 0;
69        this->freedomCount_ = 0;
70        this->team_ = -1;
71        this->state_ = FREE;
72        this->specificMasterAction_ = NONE;
73        this->specificMasterActionHoldCount_  = 0;
74        this->bShooting_ = false;
75        this->bHasTargetPosition_ = false;
76        this->targetPosition_ = Vector3::ZERO;
77        this->humanToFollow_ = NULL;
78
79        this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this));
80    }
81
82    ArtificialController::~ArtificialController()
83    {
84    }
85
86    void ArtificialController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
87    {
88        SUPER(ArtificialController, XMLPort, xmlelement, mode);
89
90        XMLPortParam(ArtificialController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(-1);
91        XMLPortParam(ArtificialController, "formation", setFormationFlight, getFormationFlight, xmlelement, mode).defaultValues(true);
92    }
93
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    */
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    }
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    */
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
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    */
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;
201
202        }
203    }
204
205
206    void ArtificialController::moveToPosition(const Vector3& target)
207    {
208        if (!this->getControllableEntity())
209            return;
210
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();
213
214
215        if(this->state_ == FREE)
216        {
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            }
223
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        }
229
230
231
232        if(this->state_ == MASTER)
233        {
234            if (this->target_ || distance > 10)
235            {
236                if (this->specificMasterAction_ == NONE)
237                {
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);
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                }
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);
252        }
253
254
255
256        if(this->state_ == SLAVE)
257        {
258
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);
261
262            if (distance < 300)
263            {
264                if (distance < 40)
265                {
266                    this->getControllableEntity()->moveFrontBack(0.8f*SPEED_MASTER);
267                } else this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER);
268
269            } else {
270                this->getControllableEntity()->moveFrontBack(1.2f*SPEED_MASTER + distance/300.0f);
271            }
272        }
273    }
274
275    void ArtificialController::moveToTargetPosition()
276    {
277        this->moveToPosition(this->targetPosition_);
278    }
279
280    int ArtificialController::getState()
281    {
282        return this->state_;
283    }
284
285    /**
286        @brief Unregisters a slave from its master. Called by a slave.
287    */
288    void ArtificialController::unregisterSlave() {
289        if(myMaster_)
290        {
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);
294        }
295    }
296
297    void ArtificialController::searchNewMaster()
298    {
299
300        if (!this->getControllableEntity())
301            return;
302
303        this->targetPosition_ = this->getControllableEntity()->getPosition();
304        this->forgetTarget();
305        int teamSize = 0;
306        //go through all pawns
307        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
308        {
309
310            //same team?
311            if (!ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
312                continue;
313
314            //has it an ArtificialController?
315            if (!it->getController())
316                continue;
317
318            //is pawn oneself?
319            if (static_cast<ControllableEntity*>(*it) == this->getControllableEntity())
320                continue;
321
322            teamSize++;
323
324            ArtificialController *newMaster = static_cast<ArtificialController*>(it->getController());
325
326            //is it a master?
327            if (!newMaster || newMaster->getState() != MASTER)
328                continue;
329
330            float distance = (it->getPosition() - this->getControllableEntity()->getPosition()).length();
331
332            // is pawn in range?
333            if (distance < 5000)
334            {
335                if(newMaster->slaves_.size() > MAX_FORMATION_SIZE) continue;
336
337                for(std::vector<ArtificialController*>::iterator itSlave = this->slaves_.begin(); itSlave != this->slaves_.end(); itSlave++)
338                {
339                    (*itSlave)->myMaster_ = newMaster;
340                    newMaster->slaves_.push_back(*itSlave);
341                }
342                this->slaves_.clear();
343                this->state_ = SLAVE;
344
345                this->myMaster_ = newMaster;
346                newMaster->slaves_.push_back(this);
347
348                break;
349            }
350        }
351
352        if (state_ != SLAVE  && teamSize != 0) state_ = MASTER;
353
354    }
355
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;
362
363        Quaternion orient = this->getControllableEntity()->getOrientation();
364        Vector3 dest = this->getControllableEntity()->getPosition();
365
366        // 1 slave: follow
367        if (this->slaves_.size() == 1)
368        {
369            dest += 4*orient*WorldEntity::BACK;
370            this->slaves_.front()->setTargetPosition(dest);
371        }
372        else 
373        {
374            dest += 1.0f*orient*WorldEntity::BACK;
375            Vector3 pos = Vector3::ZERO;
376            int i = 1;
377
378            for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
379            {
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);
394            }
395        }
396    }
397
398    /**
399        @brief Sets a new master within the formation. Called by a master.
400    */
401    void ArtificialController::setNewMasterWithinFormation()
402    {
403        if(this->state_ != MASTER) return;
404
405        if (this->slaves_.empty())
406            return;
407
408        ArtificialController *newMaster = this->slaves_.back();
409        this->slaves_.pop_back();
410
411        if(!newMaster) return;
412        newMaster->state_ = MASTER;
413        newMaster->slaves_ = this->slaves_;
414
415        this->slaves_.clear();
416        this->state_ = SLAVE;
417        this->myMaster_ = newMaster;
418
419        for(std::vector<ArtificialController*>::iterator it = newMaster->slaves_.begin(); it != newMaster->slaves_.end(); it++)
420        {
421            (*it)->myMaster_ = newMaster;
422        }
423
424    }
425
426    /**
427        @brief Frees all slaves form a master. Called by a master.
428    */
429    void ArtificialController::freeSlaves()
430    {
431        if(this->state_ != MASTER) return;
432
433        for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
434        {
435            (*it)->state_ = FREE;
436        }
437        this->slaves_.clear();
438    }
439
440    /**
441        @brief Master sets its slaves free for \var FREEDOM_COUNT seconds.
442    */
443    void ArtificialController::forceFreeSlaves()
444    {
445        if(this->state_ != MASTER) return;
446
447        for(std::vector<ArtificialController*>::iterator it = slaves_.begin(); it != slaves_.end(); it++)
448        {
449            (*it)->state_ = FREE;
450            (*it)->forceFreedom();
451            (*it)->targetPosition_ = this->targetPosition_;
452            (*it)->bShooting_ = true;
453            (*it)->getControllableEntity()->fire(0);// fire once for fun
454        }
455    }
456
457    void ArtificialController::loseMasterState()
458    {
459        this->freeSlaves();
460        this->state_ = FREE;
461    }
462
463
464    void ArtificialController::forceFreedom()
465    {
466        this->freedomCount_ = FREEDOM_COUNT;
467    }
468
469    /**
470        @brief Checks wether caller has been forced free, decrements time to stay forced free.
471        @return true if forced free.
472    */
473    bool ArtificialController::forcedFree()
474    {
475        if(this->freedomCount_ > 0) 
476        {
477            this->freedomCount_--;
478            return true;
479        } else return false;
480    }
481
482    /**
483        @brief Used to continue a "specific master action" for a certain time.
484    */
485    void ArtificialController::specificMasterActionHold()
486    {
487        if(this->state_ != MASTER) return;
488
489        if (specificMasterActionHoldCount_ == 0) 
490         {
491            this->specificMasterAction_ = NONE;
492            this->searchNewTarget();
493         }
494        else specificMasterActionHoldCount_--;
495    }
496
497    /**
498        @brief Master engages a 180 degree turn. Is a "specific master action".
499    */
500    void ArtificialController::turn180()
501    {
502        if(this->state_ != MASTER) return;
503
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;
511    }
512
513    /**
514        @brief Master spins around looking directions axis. Is a "specific master action".
515    */
516    void ArtificialController::spin()
517    {
518        if(this->state_ != MASTER) return;
519
520        this->specificMasterAction_  =  NONE;
521    }
522
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        }
541
542    }
543
544
545    void ArtificialController::setTargetPosition(const Vector3& target)
546    {
547        this->targetPosition_ = target;
548        this->bHasTargetPosition_ = true;
549    }
550
551    void ArtificialController::searchRandomTargetPosition()
552    {
553        this->targetPosition_ = Vector3(rnd(-2000,2000), rnd(-2000,2000), rnd(-2000,2000));
554        this->bHasTargetPosition_ = true;
555    }
556
557    void ArtificialController::setTarget(Pawn* target)
558    {
559        this->target_ = target;
560
561        if (target)
562            this->targetPosition_ = target->getPosition();
563    }
564
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        {
575            if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
576                continue;
577
578            if (static_cast<ControllableEntity*>(*it) != this->getControllableEntity())
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
604        static const float hardcoded_projectile_speed = 1250;
605
606        this->targetPosition_ = getPredictedPosition(this->getControllableEntity()->getPosition(), hardcoded_projectile_speed, this->target_->getPosition(), this->target_->getVelocity());
607        this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO);
608
609        Pawn* pawn = dynamic_cast<Pawn*>(this->getControllableEntity());
610        if (pawn)
611            pawn->setAimPosition(this->targetPosition_);
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
633    void ArtificialController::abandonTarget(Pawn* target)
634    {
635        if (target == this->target_)
636            this->targetDied();
637    }
638
639    void ArtificialController::targetDied()
640    {
641        this->forgetTarget();
642        this->searchRandomTargetPosition();
643    }
644
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
653        Controller* controller = 0;
654        if (entity1->getController())
655            controller = entity1->getController();
656        else
657            controller = entity1->getXMLController();
658        if (controller)
659        {
660            ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
661            if (ac)
662                team1 = ac->getTeam();
663        }
664
665        if (entity1->getController())
666            controller = entity1->getController();
667        else
668            controller = entity1->getXMLController();
669        if (controller)
670        {
671            ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
672            if (ac)
673                team2 = ac->getTeam();
674        }
675
676        TeamDeathmatch* tdm = orxonox_cast<TeamDeathmatch*>(gametype);
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
686        TeamBaseMatchBase* base = 0;
687        base = orxonox_cast<TeamBaseMatchBase*>(entity1);
688        if (base)
689        {
690            switch (base->getState())
691            {
692                case BaseState::ControlTeam1:
693                    team1 = 0;
694                    break;
695                case BaseState::ControlTeam2:
696                    team1 = 1;
697                    break;
698                case BaseState::Uncontrolled:
699                default:
700                    team1 = -1;
701            }
702        }
703        base = orxonox_cast<TeamBaseMatchBase*>(entity2);
704        if (base)
705        {
706            switch (base->getState())
707            {
708                case BaseState::ControlTeam1:
709                    team2 = 0;
710                    break;
711                case BaseState::ControlTeam2:
712                    team2 = 1;
713                    break;
714                case BaseState::Uncontrolled:
715                default:
716                    team2 = -1;
717            }
718        }
719
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;
727
728        return (team1 == team2 && team1 != -1);
729    }
730}
Note: See TracBrowser for help on using the repository browser.