Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/controllers/ActionpointController.cc @ 11071

Last change on this file since 11071 was 11071, checked in by landauf, 8 years ago

merged branch cpp11_v3 back to trunk

  • Property svn:eol-style set to native
File size: 25.8 KB
RevLine 
[10864]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:
[10885]23 *      Gani Aliguzhinov
[10864]24 *   Co-authors:
[10885]25 *      ...
[10864]26 *
27 */
28
29#include "ActionpointController.h"
30
31#include "core/XMLPort.h"
[10875]32#include <algorithm>
[10877]33#include "worldentities/Actionpoint.h"
[10864]34namespace orxonox
35{
36
37    RegisterClass(ActionpointController);
38
[10871]39    ActionpointController::ActionpointController(Context* context) : FightingController(context)
[10864]40    {
[10923]41        this->ticks_ = 0;
[10915]42        this->bPatrolling_ = false;
[10877]43        this->bInLoop_ = false;
[10864]44        this->bLoop_ = false;
45        this->bEndLoop_ = false;
[10888]46        loopActionpoints_.clear();
47        parsedActionpoints_.clear();
48        actionpoints_.clear();
[10864]49        this->bTakenOver_ = false;
50        this->action_ = Action::NONE;
51        this->squaredaccuracy_ = 2500;
[10906]52        this->bStartedDodging_ = false;
[10912]53        this->bDefaultPatrol_ = true;
54        this->bDefaultFightAll_ = true;
[10864]55        RegisterObject(ActionpointController);
56
57    }
58    void ActionpointController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
59    {
60        SUPER( ActionpointController, XMLPort, xmlelement, mode );
[10912]61
[10864]62        XMLPortObject(ActionpointController, WorldEntity, "actionpoints", addActionpoint, getActionpoint,  xmlelement, mode);
[10912]63        XMLPortParam(ActionpointController, "defaultFightAll", setDefaultFightAll, getDefaultFightAll, xmlelement, mode).defaultValues(true);
64        XMLPortParam(ActionpointController, "defaultPatrol", setDefaultPatrol, getDefaultPatrol, xmlelement, mode).defaultValues(true);
[10864]65    }
[10912]66
[10886]67    ActionpointController::~ActionpointController()
68    {
69        loopActionpoints_.clear();
70        parsedActionpoints_.clear();
71        actionpoints_.clear();
[10935]72
[10886]73    }
74    void ActionpointController::tick(float dt)
75    {
[10974]76        if (!this || !this->getControllableEntity() || !this->isActive())
[10915]77            return;
[10953]78
[10955]79        //count ticks, ticks_ is unsigned, so overflow is not a problem
[10923]80        ++this->ticks_;
[10953]81        if (this->ticks_ == 1)
[10885]82        {
[10955]83            //those vectors are in reversed order after being set by XML.
[10923]84            std::reverse(parsedActionpoints_.begin(), parsedActionpoints_.end());
85            std::reverse(actionpoints_.begin(), actionpoints_.end());
[10906]86        }
[10935]87
[10923]88        if (!this || !this->getControllableEntity())
89            return;
[10955]90        //fly
[10886]91        if (this->bHasTargetPosition_)
[10864]92        {
93            this->moveToTargetPosition(dt);
[10955]94        }//or just rotate
[10864]95        else if (this->bLookAtTarget_)
96        {
97            this->lookAtTarget(dt);
98        }
[10925]99       
[10923]100
101        if (!this || !this->getControllableEntity())
102            return;
[10955]103        //don't fire rocket each tick
[10923]104        if (timeout_ <= 0)
[10953]105        {   
[10923]106            this->bFiredRocket_ = false;
[10953]107        }
108        else if (this->bFiredRocket_)
[10925]109        {
[10934]110            --this->timeout_;
[10925]111        }
112
[10924]113        if (!this || !this->getControllableEntity())
114            return;
[10955]115        //sometimes dodge, sometimes attack
[10953]116        if (this->ticks_ % 80 <= 10)
[10927]117        {
118            this->bDodge_ = false;
119        }
120        else
121        {
122            this->bDodge_ = true;
123        }
[10925]124
[10924]125        if (!this || !this->getControllableEntity())
126            return;
[10955]127        //fire if you can
[10953]128        if (this->bShooting_)
[10924]129        {
[10953]130            this->doFire();
[10906]131        }
[10886]132        SUPER(ActionpointController, tick, dt);
133    }
[10912]134     
[10955]135    /**
136    @brief
137        action() manages the state machine.
138    */
[10910]139
[10886]140    void ActionpointController::action()
141    {
[10953]142        if (!this || !this->getControllableEntity() || !this->isActive())
[10886]143            return;
[10935]144
[10955]145        //deltaHp is used to know if this got attacked
[10953]146        this->deltaHp = orxonox_cast<Pawn*> (this->getControllableEntity())->getHealth() - this->previousHp;
147        this->previousHp = orxonox_cast<Pawn*> (this->getControllableEntity())->getHealth();
[10955]148
149        //look out for enemies
[10912]150        if (this->bDefaultPatrol_ || (this->action_ != Action::FLY && this->action_ != Action::NONE))
151        {
152            this->startAttackingEnemiesThatAreClose();
153        }
[10923]154        if (!this || !this->getControllableEntity())
155            return;
156
[10886]157        //No action -> pop one from stack
158        if (this->action_ == Action::NONE || this->bTakenOver_)
159        {
[10955]160            //if default behaviour is fighting all, push it onto the stack
[10912]161            if (this->parsedActionpoints_.empty() && this->loopActionpoints_.empty() && this->bDefaultFightAll_)
[10886]162            {
[10946]163                if (!this || !this->getControllableEntity())
164                    return;
[10886]165                Point p = { Action::FIGHTALL, "", Vector3::ZERO, false };
166                this->parsedActionpoints_.push_back (p);
167            }
[10946]168            if (!this || !this->getControllableEntity())
169                return;
[10886]170            this->executeActionpoint();
[10946]171            if (!this || !this->getControllableEntity())
172                return;
[10886]173            this->bTakenOver_ = false;
[10879]174        }
[10923]175        if (!this || !this->getControllableEntity())
176            return;
177
[10886]178        //Action fightall -> fight till nobody alive
179        if (this->action_ == Action::FIGHTALL)
180        {
[10903]181
[10886]182            if (!this->hasTarget())
183            {
184                ControllableEntity* newTarget = this->closestTarget();   
185                if (newTarget)
186                {
[10946]187                    if (!this || !this->getControllableEntity())
188                        return;
[10886]189                    this->setAction (Action::FIGHTALL, newTarget);
190                }
191                else
192                {
[10946]193                    if (!this || !this->getControllableEntity())
194                        return;
[10886]195                    this->nextActionpoint();
[10946]196                    if (!this || !this->getControllableEntity())
197                        return;
[10915]198                    this->executeActionpoint();
199   
[10886]200                }
201            }
202        }
203        //Action fight -> fight as long as enemies in range
204        else if (this->action_ == Action::FIGHT)
205        {
[10903]206            if (!this->hasTarget() )
[10886]207            {
208                //----find a target----
[10946]209                ControllableEntity* newTarget = this->closestTarget(); 
210                if (!this || !this->getControllableEntity())
211                    return; 
[10886]212                if (newTarget && 
213                        CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
214                {
[10946]215                    if (!this || !this->getControllableEntity())
216                        return;
[10886]217                    this->setAction (Action::FIGHT, newTarget);
218                }
219                else
220                {
[10946]221                    if (!this || !this->getControllableEntity())
222                        return;
[10886]223                    this->nextActionpoint();
[10946]224                    if (!this || !this->getControllableEntity())
225                        return;
[10915]226                    this->executeActionpoint();
[10886]227                }
228            }
229            else if (this->hasTarget())
230            {
231                //----fly in formation if far enough----
232                Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();         
233                   
234                if (diffVector.length() > this->attackRange_)
235                {
236                    ControllableEntity* newTarget = this->closestTarget();
[10946]237                    if (!this || !this->getControllableEntity())
238                        return;
[10886]239                    if (newTarget && 
240                        CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
241                    {
[10946]242                        if (!this || !this->getControllableEntity())
243                            return;
[10886]244                        this->setAction (Action::FIGHT, newTarget);
245                    }
246                    else
247                    {
[10946]248                        if (!this || !this->getControllableEntity())
249                            return;
[10886]250                        this->nextActionpoint();
[10946]251                        if (!this || !this->getControllableEntity())
252                            return;
[10915]253                        this->executeActionpoint();
[10886]254                    }
255                }
256            }
257        }
258        else if (this->action_ == Action::FLY)
259        {
260            if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
261            {
[10946]262                if (!this || !this->getControllableEntity())
263                    return;
[10886]264                this->nextActionpoint();   
[10946]265                if (!this || !this->getControllableEntity())
266                    return;
[10915]267                this->executeActionpoint();
[10886]268            }
269        }
270        else if (this->action_ == Action::PROTECT)
271        {
272            if (!this->getProtect())
273            {
[10946]274                if (!this || !this->getControllableEntity())
275                    return;
[10886]276                this->nextActionpoint();
[10946]277                if (!this || !this->getControllableEntity())
278                    return;
[10915]279                this->executeActionpoint(); 
[10886]280            }
[10946]281            if (!this || !this->getControllableEntity())
282                return;
[10886]283            this->stayNearProtect();
284        }
285        else if (this->action_ == Action::ATTACK)
286        {   
[10946]287            if (!this || !this->getControllableEntity())
288                return;
[10886]289            if (!this->hasTarget())
290            {
[10946]291                if (!this || !this->getControllableEntity())
292                    return;
[10886]293                this->nextActionpoint();
[10946]294                if (!this || !this->getControllableEntity())
295                    return;
[10915]296                this->executeActionpoint();
[10886]297            }
298        }
[10864]299    }
[10955]300    /**
301    @brief
302        if action is protect, this follows protect_ and fights enemies that are close
303    */
[10864]304    void ActionpointController::setProtect (ControllableEntity* protect)
305    {
306        this->protect_ = protect;
307    }
308    ControllableEntity* ActionpointController::getProtect ()
309    {
310        return this->protect_;
311    }
[10955]312    //XML method
[10864]313    void ActionpointController::addActionpoint(WorldEntity* actionpoint)
314    {
315        std::string actionName;
316        Vector3 position;
317        std::string targetName;
318        bool inLoop = false;
319        Point p;
[10888]320        if (actionpoint->getIdentifier()->getName() == "Actionpoint")
[10864]321        {
[10888]322            Actionpoint* ap = orxonox_cast<Actionpoint*> (actionpoint);
[10864]323            actionName = ap->getActionXML();
324            targetName = ap->getName();
325            position = ap->getWorldPosition();
326
327            if (this->bEndLoop_)
328            {
329                this->bInLoop_ = false;
330            }
331            if (!this->bInLoop_ && ap->getLoopStart())
332            {
333                this->bInLoop_ = true;
334            }
335            if (this->bInLoop_ && ap->getLoopEnd())
336            {
337                this->bEndLoop_ = true;
338            }
339            inLoop = this->bInLoop_;
340
[11071]341            Action value;
[10864]342           
343            if ( actionName == "FIGHT" )
344            { value = Action::FIGHT; }
345            else if ( actionName == "FLY" )
346            { value = Action::FLY; }
347            else if ( actionName == "PROTECT" )
348            { value = Action::PROTECT; }
349            else if ( actionName == "NONE" )
350            { value = Action::NONE; }
351            else if ( actionName == "FIGHTALL" )
352            { value = Action::FIGHTALL; }
353            else if ( actionName == "ATTACK" )
354            { value = Action::ATTACK; }
355            else
356                ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ actionName + "'." );
357            p.action = value; p.name = targetName; p.position = position; p.inLoop = inLoop;
358        }
359        else
360        {
[10888]361            inLoop = true;
[10864]362            p.action = Action::FLY; p.name = ""; p.position = actionpoint->getWorldPosition(); p.inLoop = inLoop;
363        }
364            parsedActionpoints_.push_back(p);
365            this->actionpoints_.push_back(actionpoint);
366    }
[10955]367    //XML method
[10864]368    WorldEntity* ActionpointController::getActionpoint(unsigned int index) const
369    {
370        if (index < this->actionpoints_.size())
371            return this->actionpoints_[index];
372        else
[11071]373            return nullptr;
[10864]374    }
[10955]375    //XML method
[11071]376    Action ActionpointController::getAction ()
[10864]377    {
378        return this->action_;
379    }
[10955]380    //XML method
[10864]381    std::string ActionpointController::getActionName()
382    {
383        switch ( this->action_ )
384        {
385            case Action::FIGHT:
[10923]386            { return "FIGHT"; }
[10864]387            case Action::FLY:
[10923]388            { return "FLY"; }
[10864]389            case Action::PROTECT:
[10923]390            { return "PROTECT"; }
[10864]391            case Action::NONE:
[10923]392            { return "NONE"; }
[10864]393            case Action::FIGHTALL:
[10923]394            { return "FIGHTALL"; }
[10864]395            case Action::ATTACK:
[10923]396            { return "ATTACK"; }
[10864]397            default:
398                return "NONE";
399                break;
400        }
401    }
[10955]402    //XML method
[11071]403    void ActionpointController::setAction (Action action)
[10864]404    {
405        this->action_ = action;
406    }
[10955]407    //set action and target/protect
[11071]408    void ActionpointController::setAction (Action action, ControllableEntity* target)
[10864]409    {
[10946]410        if (!this || !this->getControllableEntity())
411            return;
[10864]412        this->action_ = action;
413        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
414        {   
415            if (target)
416                this->setTarget (target);
417        }
418        else if (action == Action::PROTECT)
419        {
420            if (target)
421                this->setProtect (target);
422        }
423    }
[10955]424    //set action and target position
[11071]425    void ActionpointController::setAction (Action action, const Vector3& target)
[10864]426    {
[10946]427        if (!this || !this->getControllableEntity())
428            return;
[10864]429        this->action_ = action;
430        if (action == Action::FLY)
431        {
432            this->setTargetPosition (target);
433        }
434    }
[10955]435    //set action and target position and orientation
[11071]436    void ActionpointController::setAction (Action action, const Vector3& target,  const Quaternion& orient )
[10864]437    {
[10946]438        if (!this || !this->getControllableEntity())
439            return;
[10864]440        this->action_ = action;
441        if (action == Action::FLY)
442        {
443            this->setTargetPosition (target);
444            this->setTargetOrientation (orient);
445        } 
446    }
447   
448    //------------------------------------------------------------------------------
449    //------------------------------Actionpoint methods-----------------------------
450    //------------------------------------------------------------------------------
451
452    //POST: this starts doing what was asked by the last element of parsedActionpoints_,
453    //if last element was failed to be parsed, next element will be executed.
454    void ActionpointController::executeActionpoint()
455    {
[10923]456        if (!this || !this->getControllableEntity())
457            return;
458
[10872]459        Point p;
460        if (this->bLoop_ && !loopActionpoints_.empty())
[10864]461        {
[10872]462            p = loopActionpoints_.back();
463        }
464        else if (this->bLoop_)
465        {
466            this->bLoop_ = false;
467            return;
468        }
469        else if (!this->bLoop_ && !parsedActionpoints_.empty())
470        {
471            p = parsedActionpoints_.back();
472        }
473        else
474        {
[10923]475            if (!this || !this->getControllableEntity())
476                return;
477
[11071]478            this->setTarget(nullptr);
[10872]479            this->setTargetPosition(this->getControllableEntity()->getWorldPosition());
480            this->action_ = Action::NONE;
481            return;
482        }
[10946]483        if (!this || !this->getControllableEntity())
484            return;
[10872]485        if (!this->bLoop_ && this->parsedActionpoints_.back().inLoop)
486        {
487            //MOVES all points that are in loop to a loop vector
488            this->fillLoop();
[10946]489            if (!this || !this->getControllableEntity())
490                return;
[10872]491            this->bLoop_ = true;
492            executeActionpoint();
493            return;
494        }
[10946]495        if (!this || !this->getControllableEntity())
496            return;
[10886]497        this->setAction (p.action);
[10925]498        if (!this || !this->getControllableEntity())
499            return;
500
[10886]501        switch (this->action_)
[10872]502        {
503            case Action::FIGHT:
[10864]504            {
[10872]505                std::string targetName = p.name;
506                if (targetName == "")
507                    break;
[11071]508                for (Pawn* pawn : ObjectList<Pawn>())
[10872]509                {
[10946]510                    if (!this || !this->getControllableEntity())
511                        return;
[11071]512                    if (CommonController::getName(pawn) == targetName)
[10864]513                    {
[11071]514                        this->setTarget (static_cast<ControllableEntity*>(pawn));
[10864]515                    }
[10886]516                }
[10872]517                break;
518            }
519            case Action::FLY:
520            {
521                this->setTargetPosition( p.position );
[10946]522                if (!this || !this->getControllableEntity())
523                    return;
[10872]524                if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
525                {
[10946]526                    if (!this || !this->getControllableEntity())
527                        return;
[10872]528                    this->nextActionpoint();
[10946]529                    if (!this || !this->getControllableEntity())
530                        return;
[10872]531                    this->executeActionpoint();
532                }
533                break;
534            }
535            case Action::PROTECT:
536            {
[10923]537                if (!this || !this->getControllableEntity())
538                    return;
539
[10872]540                std::string protectName = p.name;
541                if (protectName == "reservedKeyword:human")
542                {
[11071]543                    for (Pawn* pawn : ObjectList<Pawn>())
[10864]544                    {
[11071]545                        if (orxonox_cast<ControllableEntity*>(pawn) && (pawn->getController()) && (pawn->getController()->getIdentifier()->getName() == "NewHumanController"))
[10864]546                        {
[11071]547                            this->setProtect (static_cast<ControllableEntity*>(pawn));
[10864]548                        }
549                    }
[10872]550                }
551                else
552                {
[11071]553                    for (Pawn* pawn : ObjectList<Pawn>())
[10864]554                    {
[11071]555                        if (CommonController::getName(pawn) == protectName)
[10864]556                        {
[11071]557                            this->setProtect (static_cast<ControllableEntity*>(pawn));
[10864]558                        }
[10872]559                    }                           
[10864]560                }
[10872]561                if (!this->getProtect())
562                {
563                    this->nextActionpoint();
564                    this->executeActionpoint();
565                }
566                break;
[10864]567            }
[10872]568            case Action::NONE:
[10864]569            {
[10872]570                break;
[10864]571            }
[10872]572            case Action::FIGHTALL:
[10864]573            {
[10872]574                break;
575            }
576            case Action::ATTACK:
577            {
578                std::string targetName = p.name;
579
[11071]580                for (Pawn* pawn : ObjectList<Pawn>())
[10864]581                {
[11071]582                    if (CommonController::getName(pawn) == targetName)
[10864]583                    {
[10946]584                        if (!this || !this->getControllableEntity())
585                            return;
[11071]586                        this->setTarget (static_cast<ControllableEntity*>(pawn));
[10864]587                    }
588                }
[10872]589                if (!this->hasTarget())
590                {
591                    this->nextActionpoint();
[10946]592                    if (!this || !this->getControllableEntity())
593                        return;
[10872]594                    this->executeActionpoint();
595                }
596                break;
[10864]597            }
[10872]598            default:
599                break;
[10886]600        }   
[10872]601    }
[10864]602
[10955]603    //calculate where in world coordinates this ship has to be, so that it keeps distance to protect_, and fly there
[10864]604    void ActionpointController::stayNearProtect()
605    {
[10923]606        if (!this || !this->getControllableEntity())
607            return;
608
[10886]609        Vector3 targetRelativePosition(0, 300, 300);
610        if (!this->getProtect())
611        {
612            this->nextActionpoint();
613            return;
614        } 
[10864]615        Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) + 
[10880]616            (this->getProtect()->getWorldOrientation()* (targetRelativePosition)));
[10864]617        this->setTargetPosition(targetAbsolutePosition);
[10886]618        if (!this->getProtect())
619        {
620            this->nextActionpoint();
621            return;
622        } 
[10909]623        this->setTargetOrientation(this->getProtect()->getWorldOrientation());
[10864]624    }
[10955]625    //remove current point from the stack
[10864]626    void ActionpointController::nextActionpoint()
627    {
628        if (!this || !this->getControllableEntity())
629            return;
630        if (this->bLoop_)
631        {
[10915]632            if (this->bPatrolling_)
[10864]633            {
[10915]634                this->loopActionpoints_.pop_back();
635                this->bPatrolling_ = false;
636            }
637            else if (!this->loopActionpoints_.empty())
638            {
[10864]639                this->moveBackToTop();
640            }
641        }
642        else
643        {
644            if (!this->parsedActionpoints_.empty())
645            {
646                this->parsedActionpoints_.pop_back();
647            }           
648        }
649        this->setAction(Action::NONE);
[10882]650        this->bHasTargetPosition_ = false;
[10864]651    }
[10955]652    //if looping, instead of erasing point, move it to the top (back is what gets executed, so it's kinda reversed stack)
[10864]653    void ActionpointController::moveBackToTop()
654    {
[10925]655        if (!this || !this->getControllableEntity())
656            return;
657
[10864]658        Point temp = loopActionpoints_.back();
659        loopActionpoints_.pop_back();
660        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
661        loopActionpoints_.push_back(temp);
662        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
663    }
[10955]664    //POST: moves all consecutive points that are in loop to the loop stack
[10864]665    void ActionpointController::fillLoop()
666    {
667        loopActionpoints_.clear();
668        fillLoopReversed();
669        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
670    }
671    void ActionpointController::fillLoopReversed()
672    {
673        if (parsedActionpoints_.back().inLoop)
674        {
675            loopActionpoints_.push_back(parsedActionpoints_.back());
676            parsedActionpoints_.pop_back();
677        }
678        if (parsedActionpoints_.back().inLoop)
679        {
680            fillLoopReversed();
681        }
682    }
[10955]683    //copy other ship's stacks so that if it dies, this can finish that ship's actions
[10885]684    void ActionpointController::takeActionpoints (const std::vector<Point>& vector, const std::vector<Point>& loop, bool b)
[10864]685    {
[10946]686        if (!this || !this->getControllableEntity())
687            return;
688        this->parsedActionpoints_ = vector;
689        if (!this || !this->getControllableEntity())
690            return;
691        this->loopActionpoints_ = loop;
692        this->bLoop_ = b;
693        this->bTakenOver_ = true;
[10864]694    }
[10955]695    //attack closest target
[10864]696    void ActionpointController::setClosestTarget()
697    {
698        this->setTarget (static_cast<ControllableEntity*>( closestTarget() ) ); 
699    }
[10955]700    //find closest target
[10864]701    Pawn* ActionpointController::closestTarget()
702    {
[10923]703        if (!this || !this->getControllableEntity())
[11071]704            return nullptr;
[10864]705
[11071]706        Pawn* closestTarget = nullptr;
[10864]707        float minDistance =  std::numeric_limits<float>::infinity();
708        Gametype* gt = this->getGametype();
[11071]709        for (Pawn* pawn : ObjectList<Pawn>())
[10864]710        {
[10946]711            if (!this || !this->getControllableEntity())
[11071]712                return nullptr;
713            if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(pawn), gt) )
[10864]714                continue;
715
[11071]716            float distance = CommonController::distance (pawn, this->getControllableEntity());
[10864]717            if (distance < minDistance)
718            {
[11071]719                closestTarget = pawn;
[10864]720                minDistance = distance;
721            }
722        }
723        if (closestTarget)
724        {
725           return closestTarget;
726        } 
[11071]727        return nullptr;
[10864]728    }
[10955]729    //push action FIGHT to the stack and set target to the closest enemy
[10864]730    void ActionpointController::startAttackingEnemiesThatAreClose()
731    {
[10923]732        if (!this || !this->getControllableEntity())
733            return;
[10974]734       
735        if (!this->target_ || (this->target_ && CommonController::distance (this->getControllableEntity(), this->target_) > this->attackRange_))
[10864]736        {
[10974]737            if (!this || !this->getControllableEntity())
738                return;
739            Pawn* newTarget = this->closestTarget();
740            if ( newTarget && 
741                CommonController::distance (this->getControllableEntity(), static_cast<ControllableEntity*>(newTarget))
742                    <= this->attackRange_ )
[10864]743            {
[10946]744                if (!this || !this->getControllableEntity())
745                    return;
[10974]746                this->setTarget(newTarget);
747                if (this->bLoop_ && !this->bPatrolling_)
[10864]748                {
[10974]749                    Point p = { Action::FIGHT, "", Vector3::ZERO, true };
750                    this->loopActionpoints_.push_back(p);
[10864]751                }
[10974]752                else if (!this->bPatrolling_)
753                {
754                    Point p = { Action::FIGHT, "", Vector3::ZERO, false };
755                    this->parsedActionpoints_.push_back(p);
756                }
757                this->bPatrolling_ = true;
758                this->executeActionpoint();
[10864]759            }
760        }
761    }
[10923]762}   
Note: See TracBrowser for help on using the repository browser.