Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7832 was 7832, checked in by jo, 14 years ago

Now the ai use lensflare if the weapon is on board and if they are close enough to the target. Hardcoded version!

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