Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

didn'change any behaviour yet, but implemented some methods that I don't use yet

File size: 36.0 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 *      Gani Aliguzhinov
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "ActionpointController.h"
30
31#include "core/XMLPort.h"
32#include <algorithm>
33#include "worldentities/Actionpoint.h"
34namespace orxonox
35{
36
37    RegisterClass(ActionpointController);
38
39    ActionpointController::ActionpointController(Context* context) : FightingController(context)
40    {
41        this->actionCounter_ = 0;
42        this->bInLoop_ = false;
43        this->bLoop_ = false;
44        this->bEndLoop_ = false;
45        loopActionpoints_.clear();
46        parsedActionpoints_.clear();
47        actionpoints_.clear();
48        healthSpawners_.clear();
49        damageSpawners_.clear();
50        speedSpawners_.clear();
51        this->bTakenOver_ = false;
52        this->action_ = Action::NONE;
53        this->squaredaccuracy_ = 2500;
54        this->bFirstTick_ = true;
55        this->bStartedDodging_ = false;
56        this->timeDodged_ = 0;
57        RegisterObject(ActionpointController);
58
59    }
60    void ActionpointController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
61    {
62        SUPER( ActionpointController, XMLPort, xmlelement, mode );
63        XMLPortObject(ActionpointController, WorldEntity, "actionpoints", addActionpoint, getActionpoint,  xmlelement, mode);
64    }
65    ActionpointController::~ActionpointController()
66    {
67        loopActionpoints_.clear();
68        parsedActionpoints_.clear();
69        actionpoints_.clear();
70        healthSpawners_.clear();
71        damageSpawners_.clear();
72        speedSpawners_.clear();
73    }
74    void ActionpointController::tick(float dt)
75    {
76
77        if (this->timeout_ > 0 && this->bFiredRocket_)
78        {
79            this->timeout_ -= dt;
80        }
81        if (this->bStartedDodging_)
82        {
83            this->timeDodged_ += dt;
84            if (this->timeDodged_ > 2.0f)
85            {
86                this->bStartedDodging_ = false;
87                this->timeDodged_ = 0;
88            }
89        }
90        maneuverCounter_ += dt;
91        if (maneuverCounter_ > 6.0f)
92            maneuverCounter_ = 0;
93        this->timeOffset_ += dt;
94        if (this->timeOffset_ >= 2.0f)
95            this->timeOffset_ = 0.0f;
96        if (timeout_ <= 0)
97            this->bFiredRocket_ = false;
98
99        if (this->bHasTargetPosition_)
100        {
101            this->moveToTargetPosition(dt);
102        }
103        else if (this->bLookAtTarget_)
104        {
105            this->lookAtTarget(dt);
106        }
107
108
109        if (this->bShooting_)
110        {
111            this->doFire();
112        }
113        if (this->bFirstTick_)
114        {
115            std::reverse(parsedActionpoints_.begin(), parsedActionpoints_.end());
116            std::reverse(actionpoints_.begin(), actionpoints_.end());
117            if (this->parsedActionpoints_.empty())
118            {
119                this->action_ = Action::FIGHTALL;
120            }
121        }
122        if (this->bFirstTick_)
123        {   
124            this->timeOffset_ = 0.0f;
125            this->bActionCalled_ = false;
126            setSpawners();
127            // orxout(internal_error) << "health spawners size = " << this->healthSpawners_.size() <<
128            // ", damage spawners size = " << this->damageSpawners_.size() <<
129            // ", speed spawners size = " << this->speedSpawners_.size() << endl;       
130            this->bFirstTick_ = false;
131        }
132
133        //maneuver every 0.25 sec ->
134        float currentPeriodTime = this->timeOffset_ - static_cast<int>(this->timeOffset_);
135        if (this->hasTarget() && ((currentPeriodTime >= 0.25f && currentPeriodTime <= 0.5f) || (currentPeriodTime >= 0.75 && currentPeriodTime <= 0.999f)) && !this->bManeuverCalled_)
136        {
137            this->bManeuverCalled_ = true;
138            this->maneuver();
139            this->bShooting_ = this->canFire();
140        }
141        if ((currentPeriodTime >= 0.0f && currentPeriodTime <= 0.25f) || (currentPeriodTime >= 0.5f && currentPeriodTime <= 0.75f))
142            this->bManeuverCalled_ = false;
143        SUPER(ActionpointController, tick, dt);
144    }
145    std::pair <ControllableEntity*, ControllableEntity*> ActionpointController::closestTargets()
146    {
147        WeakPtr<ControllableEntity> firstTarget, secondTarget, tempTarget;
148        float firstDistance = std::numeric_limits<float>::infinity(), secondDistance = std::numeric_limits<float>::infinity(), tempDistance = 0;
149        Gametype* gt = this->getGametype();
150        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
151        {
152            tempTarget = static_cast<ControllableEntity*>(*itP);
153            if (CommonController::sameTeam (this->getControllableEntity(), tempTarget, gt))
154                continue;
155
156            tempDistance = CommonController::distance (*itP, this->getControllableEntity());
157            if (tempDistance < firstDistance)
158            {
159                secondDistance = firstDistance;
160                secondTarget = firstTarget;
161
162                firstDistance = tempDistance;
163                firstTarget = tempTarget;
164            }
165            else if (tempDistance < secondDistance)
166            {
167                secondDistance = tempDistance;
168                secondTarget = tempTarget;
169            }
170        }
171        return std::make_pair (firstTarget, secondTarget); 
172    }
173
174    //patrol can only be called by divisionController or others if they don't have a leader
175    //searches for closest enemy and sets target to it. If wasn't fighting, pushes Action::FIGHT on a stack.
176    //patrol gets called constantly either if this is fighting or if this->bDefaultPatrol_ is set to true via XML
177    bool ActionpointController::patrol()
178    {
179        std::pair <ControllableEntity*, ControllableEntity*> newTargets = this->closestTargets();
180        if (!newTargets.first)
181            return false;
182        ControllableEntity* newTarget = newTargets.first;
183
184        float distance = CommonController::distance (this->getControllableEntity(), newTarget);
185        if (distance < this->attackRange_ && distance < CommonController::distance(this->getControllableEntity(), this->target_))
186        {
187            this->setTarget (newTarget);
188
189            if (this->getIdentifier()->getName() == "DivisionController")
190            {
191                if (!newTargets.second)
192                {
193                    if (this->myFollower_)
194                        this->myFollower_->setTarget(newTargets.first);
195                }
196                else
197                {
198                    if (this->myFollower_ && CommonController::distance(this->getControllableEntity(), newTargets.second) < this->attackRange_ + 600.0f)
199                        this->myFollower_->setTarget(newTargets.second);
200                    else if (this->myFollower_)
201                        this->myFollower_->setTarget(newTargets.first);
202                }
203            }
204            if (this->action_ != Action::FIGHT && this->action_ != Action::FIGHTALL)
205            {
206                this->bPatrolling_ = true;
207                if (this->bLoop_)
208                {
209                    Point p = { Action::FIGHT, "", Vector3::ZERO, true };
210                    this->loopActionpoints_.push_back(p);
211                    this->executeActionpoint();
212                }
213                else
214                {
215                    Point p = { Action::FIGHT, "", Vector3::ZERO, false };
216                    this->parsedActionpoints_.push_back(p);
217                    this->executeActionpoint();   
218                }                   
219            }
220            return true;
221        }
222        else
223        {
224            return false;
225        }
226    }
227    //checks if state is still to be executed and makes a transition otherwise.
228    //if this->bDefaultPatrol_ == true, patrols area for enemies and, if not fighting, pushes a state with action = FIGHT
229    void ActionpointController::stateMachine()
230    {
231        //Check if calculations needed
232        if (!this->getControllableEntity() || !orxonox_cast<Pawn*> (this->getControllableEntity()) || !this->isActive())
233            return;
234
235        //state NONE means that either previous state finished executing and next state is to be fetched or no states are left to execute
236        //NONE is never on a stack -> it is only a transition state saved in a variable
237        if (this->action_ == Action::NONE || this->bTakenOver_)
238        {
239            //no actionpoints a.k.a. states left to execute
240            if (this->parsedActionpoints_.empty() && this->loopActionpoints_.empty())
241            {
242                //default action is fighting
243                if (this->bDefaultFightAll_)
244                {
245                    //make state
246                    Point p = { Action::FIGHTALL, "", Vector3::ZERO, false };
247                    //push it on the stack
248                    this->parsedActionpoints_.push_back (p);
249                }
250                //default action is nothing
251                else
252                {
253                    this->bActive_ = false;
254                    return;
255                }     
256            }
257            //switch to the new state
258            this->executeActionpoint(); 
259            this->bTakenOver_ = false; 
260        }
261        if (this->action_ == Action::FIGHTALL)
262        {
263            if (!this->hasTarget())
264            {
265                ControllableEntity* newTarget = this->closestTarget();   
266                if (newTarget)
267                {
268                    this->setTarget (newTarget);
269                }
270                else
271                {
272                    this->nextActionpoint();
273                    this->executeActionpoint();
274                }
275            }
276            else
277            {
278                bool b = this->patrol();
279            }
280
281        }
282        if (this->action_ == Action::FIGHT)
283        {
284            if (!this->hasTarget() )
285            {
286                if (!this->patrol())
287                {
288                    if (this->bPatrolling_)
289                    {
290                        if (this->bLoop_)
291                        {
292                            if (!this->loopActionpoints_.empty())
293                            {
294                                this->loopActionpoints_.pop_back();
295                            }
296                        }
297                        else
298                        {
299                            if (!this->parsedActionpoints_.empty())
300                            {
301                                this->parsedActionpoints_.pop_back();
302                            }           
303                        }
304                        this->setAction(Action::NONE);
305                        this->bHasTargetPosition_ = false;
306                        this->bPatrolling_ = false;
307                    }
308                    else
309                    {
310                        this->nextActionpoint();
311                    }
312                    this->executeActionpoint();
313                }
314            }
315            else if (this->hasTarget())
316            {
317                if (CommonController::distance (this->getControllableEntity(), this->target_) > this->attackRange_)
318                {
319                    this->setTarget(0);
320                    this->stateMachine();
321                }
322            }
323        }
324        if (this->action_ == Action::FLY)
325        {
326            if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
327            {
328                this->nextActionpoint();   
329                this->executeActionpoint();
330            }
331            else if (this->bDefaultPatrol_)
332            {
333                bool b = this->patrol();
334            }
335        }
336        if (this->action_ == Action::PROTECT)
337        {
338            if (!this->getProtect())
339            {
340                this->nextActionpoint();
341                this->executeActionpoint(); 
342            }
343            else
344            {
345                this->stayNearProtect();
346            }
347            if (this->bDefaultPatrol_)
348            {
349                bool b = this->patrol();
350            }
351        }
352        if (this->action_ == Action::ATTACK)
353        {   
354            if (!this->hasTarget())
355            {
356                this->nextActionpoint();
357                this->executeActionpoint();
358            }
359            if (this->bDefaultPatrol_)
360            {
361                bool b = this->patrol();
362            }
363        }
364    }
365
366
367
368    void ActionpointController::action()
369    {
370        if (!this || !this->getControllableEntity())
371            return;
372        if (!this->getControllableEntity() || !orxonox_cast<Pawn*> (this->getControllableEntity()))
373            return;
374        this->startAttackingEnemiesThatAreClose();
375
376        this->deltaHp = orxonox_cast<Pawn*> (this->getControllableEntity())->getHealth() - this->previousHp;
377        this->previousHp = orxonox_cast<Pawn*> (this->getControllableEntity())->getHealth();
378
379        // if (this->actionCounter_ % 2 == 0)
380        //No action -> pop one from stack
381        if (this->action_ == Action::NONE || this->bTakenOver_)
382        {
383            // Point point = closestPickup(PickupType::HEALTH);
384            // if (point.action != Action::NONE)
385            // {
386            //     orxout(internal_error) << "found health" << endl;
387            //     this->parsedActionpoints_.push_back(point);
388            // }
389
390            if (this->parsedActionpoints_.empty() && this->loopActionpoints_.empty())
391            {
392                Point p = { Action::FIGHTALL, "", Vector3::ZERO, false };
393                this->parsedActionpoints_.push_back (p);
394            }
395            this->executeActionpoint();
396            this->bTakenOver_ = false;
397            this->action();
398        }
399        //Action fightall -> fight till nobody alive
400        if (this->action_ == Action::FIGHTALL)
401        {
402
403            if (!this->hasTarget())
404            {
405                ControllableEntity* newTarget = this->closestTarget();   
406                if (newTarget)
407                {
408                    this->setAction (Action::FIGHTALL, newTarget);
409                    this->action();
410                }
411                else
412                {
413                    this->nextActionpoint();
414                    if (!(this->parsedActionpoints_.empty() && this->loopActionpoints_.empty()))
415                    {
416                        this->action();
417                    }
418                    else
419                    {
420                    }     
421                }
422            }
423        }
424        //Action fight -> fight as long as enemies in range
425        else if (this->action_ == Action::FIGHT)
426        {
427
428            if (!this->hasTarget() )
429            {
430                //----find a target----
431                ControllableEntity* newTarget = this->closestTarget();   
432                if (newTarget && 
433                        CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
434                {
435                    this->setAction (Action::FIGHT, newTarget);
436                    this->action();
437                }
438                else
439                {
440                    this->nextActionpoint();
441                    this->action();
442                }
443            }
444            else if (this->hasTarget())
445            {
446                //----fly in formation if far enough----
447                Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();         
448                   
449                if (diffVector.length() > this->attackRange_)
450                {
451                    ControllableEntity* newTarget = this->closestTarget();
452                   
453                    if (newTarget && 
454                        CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
455                    {
456                        this->setAction (Action::FIGHT, newTarget);
457                    }
458                    else
459                    {
460                        this->nextActionpoint();
461                        this->action();
462                    }
463                }
464            }
465        }
466        else if (this->action_ == Action::FLY)
467        {
468            if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
469            {
470                this->nextActionpoint();   
471                this->action();
472            }
473        }
474        else if (this->action_ == Action::PROTECT)
475        {
476            if (!this->getProtect())
477            {
478                this->nextActionpoint();
479                this->action(); 
480            }
481            this->stayNearProtect();
482        }
483        else if (this->action_ == Action::ATTACK)
484        {   
485
486            if (!this->hasTarget())
487            {
488                this->nextActionpoint();
489                this->action();
490            }
491        }
492
493            // Vector3 healthPosition = bestHealthPickup((this->target_->getWorldPosition() - this->getControllableEntity()->getWorldPosition()).length());
494            // if ((this->getControllableEntity()->getWorldPosition() - healthPosition).length() < this->tolerance_)
495            // {
496            //     //----choose where to go----
497            //     this->maneuver();
498            // }
499            // else
500            // {
501            //     this->dodgeTowards(healthPosition);
502            // }
503            // //----fire if you can----
504            // this->bShooting_ = this->canFire(); 
505         
506        this->actionCounter_ += this->actionCounter_ < 100000 ? 1 : -this->actionCounter_ ;
507
508    }
509    void ActionpointController::setProtect (ControllableEntity* protect)
510    {
511        this->protect_ = protect;
512    }
513    ControllableEntity* ActionpointController::getProtect ()
514    {
515        return this->protect_;
516    }
517    void ActionpointController::addActionpoint(WorldEntity* actionpoint)
518    {
519        std::string actionName;
520        Vector3 position;
521        std::string targetName;
522        bool inLoop = false;
523        Point p;
524        if (actionpoint->getIdentifier()->getName() == "Actionpoint")
525        {
526            Actionpoint* ap = orxonox_cast<Actionpoint*> (actionpoint);
527            actionName = ap->getActionXML();
528            targetName = ap->getName();
529            position = ap->getWorldPosition();
530
531            if (this->bEndLoop_)
532            {
533                this->bInLoop_ = false;
534            }
535            if (!this->bInLoop_ && ap->getLoopStart())
536            {
537                this->bInLoop_ = true;
538            }
539            if (this->bInLoop_ && ap->getLoopEnd())
540            {
541                this->bEndLoop_ = true;
542            }
543            inLoop = this->bInLoop_;
544
545            Action::Value value;
546           
547            if ( actionName == "FIGHT" )
548            { value = Action::FIGHT; }
549            else if ( actionName == "FLY" )
550            { value = Action::FLY; }
551            else if ( actionName == "PROTECT" )
552            { value = Action::PROTECT; }
553            else if ( actionName == "NONE" )
554            { value = Action::NONE; }
555            else if ( actionName == "FIGHTALL" )
556            { value = Action::FIGHTALL; }
557            else if ( actionName == "ATTACK" )
558            { value = Action::ATTACK; }
559            else
560                ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ actionName + "'." );
561            p.action = value; p.name = targetName; p.position = position; p.inLoop = inLoop;
562        }
563        else
564        {
565            inLoop = true;
566            p.action = Action::FLY; p.name = ""; p.position = actionpoint->getWorldPosition(); p.inLoop = inLoop;
567        }
568            parsedActionpoints_.push_back(p);
569            this->actionpoints_.push_back(actionpoint);
570    }
571    WorldEntity* ActionpointController::getActionpoint(unsigned int index) const
572    {
573        if (index < this->actionpoints_.size())
574            return this->actionpoints_[index];
575        else
576            return 0;
577    }
578
579    Action::Value ActionpointController::getAction ()
580    {
581        return this->action_;
582    }
583    std::string ActionpointController::getActionName()
584    {
585        switch ( this->action_ )
586        {
587            case Action::FIGHT:
588            { return "FIGHT"; break; }
589            case Action::FLY:
590            { return "FLY"; break; }
591            case Action::PROTECT:
592            { return "PROTECT"; break; }
593            case Action::NONE:
594            { return "NONE"; break; }
595            case Action::FIGHTALL:
596            { return "FIGHTALL"; break; }
597            case Action::ATTACK:
598            { return "ATTACK"; break; }
599            default:
600                return "NONE";
601                break;
602        }
603    }
604    void ActionpointController::setAction (Action::Value action)
605    {
606        this->action_ = action;
607    }
608    void ActionpointController::setAction (Action::Value action, ControllableEntity* target)
609    {
610        this->action_ = action;
611        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
612        {   
613            if (target)
614                this->setTarget (target);
615        }
616        else if (action == Action::PROTECT)
617        {
618            if (target)
619                this->setProtect (target);
620        }
621    }
622    void ActionpointController::setAction (Action::Value action, const Vector3& target)
623    {
624        this->action_ = action;
625        if (action == Action::FLY)
626        {
627            this->setTargetPosition (target);
628        }
629    }
630    void ActionpointController::setAction (Action::Value action, const Vector3& target,  const Quaternion& orient )
631    {
632        this->action_ = action;
633        if (action == Action::FLY)
634        {
635            this->setTargetPosition (target);
636            this->setTargetOrientation (orient);
637        } 
638    }
639   
640    //------------------------------------------------------------------------------
641    //------------------------------Actionpoint methods-----------------------------
642    //------------------------------------------------------------------------------
643
644    //POST: this starts doing what was asked by the last element of parsedActionpoints_,
645    //if last element was failed to be parsed, next element will be executed.
646    void ActionpointController::executeActionpoint()
647    {
648        Point p;
649        if (this->bLoop_ && !loopActionpoints_.empty())
650        {
651            p = loopActionpoints_.back();
652        }
653        else if (this->bLoop_)
654        {
655            this->bLoop_ = false;
656            return;
657        }
658        else if (!this->bLoop_ && !parsedActionpoints_.empty())
659        {
660            p = parsedActionpoints_.back();
661        }
662        else
663        {
664            this->setTarget(0);
665            this->setTargetPosition(this->getControllableEntity()->getWorldPosition());
666            this->action_ = Action::NONE;
667            return;
668        }
669        if (!this->bLoop_ && this->parsedActionpoints_.back().inLoop)
670        {
671            //MOVES all points that are in loop to a loop vector
672            this->fillLoop();
673            this->bLoop_ = true;
674            executeActionpoint();
675            return;
676        }
677        this->setAction (p.action);
678        switch (this->action_)
679        {
680            case Action::FIGHT:
681            {
682                std::string targetName = p.name;
683                if (targetName == "")
684                    break;
685                for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
686                {
687                    if (CommonController::getName(*itP) == targetName)
688                    {
689                        this->setTarget (static_cast<ControllableEntity*>(*itP));
690                    }
691                }
692                break;
693            }
694            case Action::FLY:
695            {
696                this->setTargetPosition( p.position );
697                if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
698                {
699                    this->nextActionpoint();
700                    this->executeActionpoint();
701                }
702                break;
703            }
704            case Action::PROTECT:
705            {
706               
707                std::string protectName = p.name;
708                if (protectName == "reservedKeyword:human")
709                {
710                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
711                    {
712                        if (orxonox_cast<ControllableEntity*>(*itP) && ((*itP)->getController()) && ((*itP)->getController()->getIdentifier()->getName() == "NewHumanController"))
713                        {
714                            this->setProtect (static_cast<ControllableEntity*>(*itP));
715                        }
716                    }
717                }
718                else
719                {
720                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
721                    {
722                        if (CommonController::getName(*itP) == protectName)
723                        {
724                            this->setProtect (static_cast<ControllableEntity*>(*itP));
725                        }
726                    }                           
727                }
728                if (!this->getProtect())
729                {
730                    this->nextActionpoint();
731                    this->executeActionpoint();
732                }
733                break;
734            }
735            case Action::NONE:
736            {
737                break;
738            }
739            case Action::FIGHTALL:
740            {
741                break;
742            }
743            case Action::ATTACK:
744            {
745                std::string targetName = p.name;
746
747                for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
748                {
749                    if (CommonController::getName(*itP) == targetName)
750                    {
751                        this->setTarget (static_cast<ControllableEntity*>(*itP));
752                    }
753                }
754                if (!this->hasTarget())
755                {
756                    this->nextActionpoint();
757                    this->executeActionpoint();
758                }
759                break;
760            }
761            default:
762                break;
763        }   
764    }
765
766   
767    void ActionpointController::stayNearProtect()
768    {
769        Vector3 targetRelativePosition(0, 300, 300);
770        if (!this->getProtect())
771        {
772            this->nextActionpoint();
773            return;
774        } 
775        Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) + 
776            (this->getProtect()->getWorldOrientation()* (targetRelativePosition)));
777        this->setTargetPosition(targetAbsolutePosition);
778        if (!this->getProtect())
779        {
780            this->nextActionpoint();
781            return;
782        } 
783        this->setTargetOrientation(this->getProtect()->getWorldOrientation());
784    }
785    void ActionpointController::nextActionpoint()
786    {
787        if (!this || !this->getControllableEntity())
788            return;
789        if (this->bLoop_)
790        {
791            if (!this->loopActionpoints_.empty())
792            {
793                this->moveBackToTop();
794            }
795        }
796        else
797        {
798            if (!this->parsedActionpoints_.empty())
799            {
800                this->parsedActionpoints_.pop_back();
801            }           
802        }
803        this->setAction(Action::NONE);
804        this->bHasTargetPosition_ = false;
805    }
806    void ActionpointController::moveBackToTop()
807    {
808        Point temp = loopActionpoints_.back();
809        loopActionpoints_.pop_back();
810        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
811        loopActionpoints_.push_back(temp);
812        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
813    }
814    void ActionpointController::fillLoop()
815    {
816        loopActionpoints_.clear();
817        fillLoopReversed();
818        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
819    }
820    void ActionpointController::fillLoopReversed()
821    {
822        if (parsedActionpoints_.back().inLoop)
823        {
824            loopActionpoints_.push_back(parsedActionpoints_.back());
825            parsedActionpoints_.pop_back();
826        }
827        if (parsedActionpoints_.back().inLoop)
828        {
829            fillLoopReversed();
830        }
831    }
832   
833    void ActionpointController::takeActionpoints (const std::vector<Point>& vector, const std::vector<Point>& loop, bool b)
834    {
835      this->parsedActionpoints_ = vector;
836      this->loopActionpoints_ = loop;
837      this->bLoop_ = b;
838      this->bTakenOver_ = true;
839    }
840    void ActionpointController::setClosestTarget()
841    {
842        this->setTarget (static_cast<ControllableEntity*>( closestTarget() ) ); 
843    }
844    Pawn* ActionpointController::closestTarget()
845    {
846        if (!this->getControllableEntity())
847            return 0;
848
849        Pawn* closestTarget = 0;
850        float minDistance =  std::numeric_limits<float>::infinity();
851        Gametype* gt = this->getGametype();
852        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
853        {
854            if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
855                continue;
856
857            float distance = CommonController::distance (*itP, this->getControllableEntity());
858            if (distance < minDistance)
859            {
860                closestTarget = *itP;
861                minDistance = distance;
862            }
863        }
864        if (closestTarget)
865        {
866           return closestTarget;
867        } 
868        return 0; 
869    }
870    void ActionpointController::startAttackingEnemiesThatAreClose()
871    {
872        //if (this->action_ != Action::FIGHT && this->action_ != Action::FIGHTALL)
873        {
874            if (!this->target_ || (this->target_ && CommonController::distance (this->getControllableEntity(), this->target_) > this->attackRange_))
875            {
876                Pawn* newTarget = this->closestTarget();
877                if ( newTarget && 
878                    CommonController::distance (this->getControllableEntity(), static_cast<ControllableEntity*>(newTarget))
879                        <= this->attackRange_ )
880                {
881                    if (this->bLoop_)
882                    {
883                        Point p = { Action::FIGHT, CommonController::getName(newTarget), Vector3::ZERO, true };
884                        this->loopActionpoints_.push_back(p);
885                    }
886                    else
887                    {
888                        //orxout (internal_error) << "found new target " << CommonController::getName(newTarget) <<endl;
889                        Point p = { Action::FIGHT, CommonController::getName(newTarget), Vector3::ZERO, false };
890                        this->parsedActionpoints_.push_back(p);
891                    }
892                    this->executeActionpoint();
893                }
894            }
895        }
896    }
897    Vector3 ActionpointController::bestHealthPickup(float searchRadius)
898    {
899
900        //1000000/distance^2 * 1/index+1
901        float maxUse = 0;
902        float tempUse = -1;
903        int index = 0;
904        float distance = 0;
905        Vector3 bestPosition = this->getControllableEntity()->getWorldPosition();
906
907        for (std::multimap<int, std::pair<PickupSpawner*, bool> >::iterator it=healthSpawners_.begin(); it!=healthSpawners_.end(); ++it)
908        {
909            distance = (this->getControllableEntity()->getWorldPosition() - (*it).second.first->getWorldPosition()).length();
910            if (distance < this->tolerance_ || !(*it).second.second)
911            {
912                (*it).second.second = false;
913                continue;
914            }
915            if (distance > searchRadius)
916                continue;
917            index = (*it).first;
918            tempUse = 1000000*1/(1+distance*distance) * 1/((index/2.0f)+1);
919            if (tempUse > maxUse)
920            {
921                bestPosition = (*it).second.first->getWorldPosition();
922                maxUse = tempUse;
923            }
924        }
925        //std::multimap<int, std::pair<PickupSpawner*, bool> >::iterator it = this->healthSpawners_.find(index);
926        //P.S. check if it == ... .end()
927        //orxout (internal_error) << "best position = " << bestPosition << endl;
928        return  bestPosition;
929    }
930    void ActionpointController::setSpawners()
931    {
932        std::vector<std::string> damagePickups;
933        std::vector<std::string> healthPickups;
934        std::vector<std::string> speedPickups;       
935        int index = 0;
936
937
938        damagePickups.push_back("largedamageboostpickup");
939        damagePickups.push_back("dronepickup");           
940        damagePickups.push_back("mediumdamageboostpickup");
941        damagePickups.push_back("smalldamageboostpickup");
942
943        healthPickups.push_back("triplehealthspeedinvisibilitypickup");           
944        healthPickups.push_back("crazyhealthpickup");
945        healthPickups.push_back("hugehealthpickup");
946        healthPickups.push_back("hugeshieldpickup");
947        healthPickups.push_back("hugeinvisiblepickup");
948        healthPickups.push_back("hugeshrinkpickup");
949        healthPickups.push_back("mediumhealthpickup");
950        healthPickups.push_back("mediumshieldpickup");
951        healthPickups.push_back("mediuminvisiblepickup");
952        healthPickups.push_back("mediumshrinkpickup"); 
953        healthPickups.push_back("smallhealthpickup");                   
954        healthPickups.push_back("smallshieldpickup");
955        healthPickups.push_back("smallinvisiblepickup");
956        healthPickups.push_back("smallshrinkpickup");
957
958        speedPickups.push_back("triplehealthspeedinvisibilitypickup");
959        speedPickups.push_back("hugespeedpickup");
960        speedPickups.push_back("smalljumppickup");
961        speedPickups.push_back("mediumspeedpickup");
962        speedPickups.push_back("smallspeedpickup");
963       
964
965
966        for (ObjectList<WorldEntity>::iterator it = ObjectList<WorldEntity>::begin(); it; ++it)
967        {
968            if ((*it)->getIdentifier()->getName() != "PickupSpawner")
969                continue;
970            PickupSpawner* spawner = static_cast<PickupSpawner*>(*it);
971            std::string name = spawner->getPickupTemplateName();
972            //float distance = ((*it)->getWorldPosition() - this->getControllableEntity()->getWorldPosition()).length();
973            // if (distance < 50.0f)
974            //     continue;           
975            for (unsigned int i = 0; i < healthPickups.size(); ++i)
976            {
977                if (name == healthPickups.at(i))
978                {
979                    index = i;
980                    this->healthSpawners_.insert(std::make_pair(index, std::make_pair(spawner, true)));
981                    break;
982                }
983            }
984            for (unsigned int i = 0; i < damagePickups.size(); ++i)
985            {
986                if (name == damagePickups.at(i))
987                {
988                    //tempUse = 1000000*1/(1+distance*distance) * 1/((i/2.0f)+1);
989                    index = i;
990                    this->damageSpawners_.insert(std::make_pair(index, std::make_pair(spawner, true)));
991                    break;
992                }
993            }
994            for (unsigned int i = 0; i < speedPickups.size(); ++i)
995            {
996                if (name == speedPickups.at(i))
997                {
998                    //tempUse = 1000000*1/(1+distance*distance) * 1/((i/2.0f)+1);
999                    index = i;
1000                    this->speedSpawners_.insert(std::make_pair(index, std::make_pair(spawner, true)));
1001                    break;
1002                }
1003            }
1004            // if (tempUse > maxUse)
1005            // {
1006            //     Point p = { Action::FLY, "", (*it)->getWorldPosition(), false };
1007            //     maxUse = tempUse;
1008            //     maxPoint = p;
1009            // }
1010            // else
1011            // {
1012            //     tempUse = -1;
1013            //     continue;
1014            // }
1015            // orxout(internal_error) << "resp time  = " << static_cast<PickupSpawner*>(*it)->getRespawnTime() << endl;
1016        } 
1017    }
1018}
Note: See TracBrowser for help on using the repository browser.