Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/campaignHS15/src/orxonox/controllers/ActionpointController.cc @ 10958

Last change on this file since 10958 was 10958, checked in by gania, 8 years ago

separated MasterController from my hierarchy

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