Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10885 was 10885, checked in by gania, 9 years ago

added other weapons

File size: 20.2 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"
34
35
36namespace orxonox
37{
38
39    RegisterClass(ActionpointController);
40
41    ActionpointController::ActionpointController(Context* context) : FightingController(context)
42    {
43        this->actionCounter_ = 0;
44        this->bInLoop_ = false;
45        this->bLoop_ = false;
46        this->bEndLoop_ = false;
47        this->parsedActionpoints_.clear();
48        this->bTakenOver_ = false;
49        this->action_ = Action::NONE;
50        this->squaredaccuracy_ = 2500;
51        this->bFirstTick_ = true;
52
53        RegisterObject(ActionpointController);
54
55    }
56    void ActionpointController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
57    {
58        SUPER( ActionpointController, XMLPort, xmlelement, mode );
59        XMLPortObject(ActionpointController, WorldEntity, "actionpoints", addActionpoint, getActionpoint,  xmlelement, mode);
60    }
61        void ActionpointController::tick(float dt)
62        {
63        if (this->timeout_ > 0 && this->bFiredRocket_)
64        {
65            this->timeout_ -= dt;
66        }
67        if (timeout_ <= 0)
68            this->bFiredRocket_ = false;
69
70                if (this->bHasTargetPosition_)
71        {
72            this->moveToTargetPosition(dt);
73        }
74        else if (this->bLookAtTarget_)
75        {
76            this->lookAtTarget(dt);
77        }
78        if (this->bShooting_)
79        {
80            this->doFire();
81        }
82        if (this->bFirstTick_)
83        {
84            std::reverse(parsedActionpoints_.begin(), parsedActionpoints_.end());
85            std::reverse(actionpoints_.begin(), actionpoints_.end());
86            if (this->parsedActionpoints_.empty())
87            {
88                this->action_ = Action::FIGHTALL;
89            }
90        }
91        if (this->bFirstTick_)
92        {
93            // this->getControllableEntity()->setOrientation(1,0,0,0);
94            // this->getControllableEntity()->rotateRoll(-this->getControllableEntity()->getOrientation().getRoll(true).valueRadians());
95            // this->getControllableEntity()->rotateYaw(-this->getControllableEntity()->getOrientation().getYaw(true).valueRadians());
96            // this->getControllableEntity()->rotatePitch(-this->getControllableEntity()->getOrientation().getPitch(true).valueRadians());           
97            this->bFirstTick_ = false;
98
99        }
100                SUPER(ActionpointController, tick, dt);
101        }
102    ActionpointController::~ActionpointController()
103    {
104        loopActionpoints_.clear();
105        parsedActionpoints_.clear();
106        actionpoints_.clear();
107    }
108    void ActionpointController::setProtect (ControllableEntity* protect)
109    {
110        this->protect_ = protect;
111    }
112    ControllableEntity* ActionpointController::getProtect ()
113    {
114        return this->protect_;
115    }
116    void ActionpointController::addActionpoint(WorldEntity* actionpoint)
117    {
118        std::string actionName;
119        Vector3 position;
120        std::string targetName;
121        bool inLoop = false;
122        Point p;
123        if (static_cast<Actionpoint*> (actionpoint))
124        {
125            Actionpoint* ap = static_cast<Actionpoint*> (actionpoint);
126            actionName = ap->getActionXML();
127            targetName = ap->getName();
128            position = ap->getWorldPosition();
129
130            if (this->bEndLoop_)
131            {
132                this->bInLoop_ = false;
133            }
134            if (!this->bInLoop_ && ap->getLoopStart())
135            {
136                this->bInLoop_ = true;
137            }
138            if (this->bInLoop_ && ap->getLoopEnd())
139            {
140                this->bEndLoop_ = true;
141            }
142            inLoop = this->bInLoop_;
143
144            Action::Value value;
145           
146            if ( actionName == "FIGHT" )
147            { value = Action::FIGHT; }
148            else if ( actionName == "FLY" )
149            { value = Action::FLY; }
150            else if ( actionName == "PROTECT" )
151            { value = Action::PROTECT; }
152            else if ( actionName == "NONE" )
153            { value = Action::NONE; }
154            else if ( actionName == "FIGHTALL" )
155            { value = Action::FIGHTALL; }
156            else if ( actionName == "ATTACK" )
157            { value = Action::ATTACK; }
158            else
159                ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ actionName + "'." );
160            p.action = value; p.name = targetName; p.position = position; p.inLoop = inLoop;
161        }
162        else
163        {
164            p.action = Action::FLY; p.name = ""; p.position = actionpoint->getWorldPosition(); p.inLoop = inLoop;
165        }
166            parsedActionpoints_.push_back(p);
167            this->actionpoints_.push_back(actionpoint);
168    }
169    WorldEntity* ActionpointController::getActionpoint(unsigned int index) const
170    {
171        if (index < this->actionpoints_.size())
172            return this->actionpoints_[index];
173        else
174            return 0;
175    }
176
177      Action::Value ActionpointController::getAction ()
178    {
179        return this->action_;
180    }
181    std::string ActionpointController::getActionName()
182    {
183        switch ( this->action_ )
184        {
185            case Action::FIGHT:
186            { return "FIGHT"; break; }
187            case Action::FLY:
188            { return "FLY"; break; }
189            case Action::PROTECT:
190            { return "PROTECT"; break; }
191            case Action::NONE:
192            { return "NONE"; break; }
193            case Action::FIGHTALL:
194            { return "FIGHTALL"; break; }
195            case Action::ATTACK:
196            { return "ATTACK"; break; }
197            default:
198                return "NONE";
199                break;
200        }
201    }
202    void ActionpointController::setAction (Action::Value action)
203    {
204        this->action_ = action;
205    }
206    void ActionpointController::setAction (Action::Value action, ControllableEntity* target)
207    {
208        this->action_ = action;
209        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
210        {   
211            if (target)
212                this->setTarget (target);
213        }
214        else if (action == Action::PROTECT)
215        {
216            if (target)
217                this->setProtect (target);
218        }
219    }
220    void ActionpointController::setAction (Action::Value action, const Vector3& target)
221    {
222        this->action_ = action;
223        if (action == Action::FLY)
224        {
225            this->setTargetPosition (target);
226        }
227    }
228    void ActionpointController::setAction (Action::Value action, const Vector3& target,  const Quaternion& orient )
229    {
230        this->action_ = action;
231        if (action == Action::FLY)
232        {
233            this->setTargetPosition (target);
234            this->setTargetOrientation (orient);
235        } 
236    }
237   
238    //------------------------------------------------------------------------------
239    //------------------------------Actionpoint methods-----------------------------
240    //------------------------------------------------------------------------------
241
242    //POST: this starts doing what was asked by the last element of parsedActionpoints_,
243    //if last element was failed to be parsed, next element will be executed.
244    void ActionpointController::executeActionpoint()
245    {
246        Point p;
247        if (this->bLoop_ && !loopActionpoints_.empty())
248        {
249            p = loopActionpoints_.back();
250        }
251        else if (this->bLoop_)
252        {
253            this->bLoop_ = false;
254            return;
255        }
256        else if (!this->bLoop_ && !parsedActionpoints_.empty())
257        {
258            p = parsedActionpoints_.back();
259        }
260        else
261        {
262            this->setTarget(0);
263            this->setTargetPosition(this->getControllableEntity()->getWorldPosition());
264            this->action_ = Action::NONE;
265            return;
266        }
267        if (!this->bLoop_ && this->parsedActionpoints_.back().inLoop)
268        {
269            //MOVES all points that are in loop to a loop vector
270            this->fillLoop();
271            this->bLoop_ = true;
272            executeActionpoint();
273            return;
274        }
275        this->action_ = p.action;
276        switch ( this->action_ )
277        {
278            case Action::FIGHT:
279            {
280                std::string targetName = p.name;
281                if (targetName == "")
282                {
283                    break;
284                }
285                for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
286                {
287                    if (CommonController::getName(*itP) == targetName)
288                    {
289                        this->setTarget (static_cast<ControllableEntity*>(*itP));
290                    }
291                }         
292                break;
293            }
294            case Action::FLY:
295            {
296                this->setTargetPosition( p.position );
297                if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
298                {
299                    this->nextActionpoint();
300                    this->executeActionpoint();
301                }
302                break;
303            }
304            case Action::PROTECT:
305            {
306               
307                std::string protectName = p.name;
308                if (protectName == "reservedKeyword:human")
309                {
310                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
311                    {
312                        if (orxonox_cast<ControllableEntity*>(*itP) && ((*itP)->getController()) && ((*itP)->getController()->getIdentifier()->getName() == "NewHumanController"))
313                        {
314                            this->setProtect (static_cast<ControllableEntity*>(*itP));
315                        }
316                    }
317                }
318                else
319                {
320                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
321                    {
322                        if (CommonController::getName(*itP) == protectName)
323                        {
324                            this->setProtect (static_cast<ControllableEntity*>(*itP));
325                        }
326                    }                           
327                }
328                if (!this->getProtect())
329                {
330                    this->nextActionpoint();
331                    this->executeActionpoint();
332                }
333                break;
334            }
335            case Action::NONE:
336            {
337                break;
338            }
339            case Action::FIGHTALL:
340            {
341                break;
342            }
343            case Action::ATTACK:
344            {
345                std::string targetName = p.name;
346
347                for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
348                {
349                    if (CommonController::getName(*itP) == targetName)
350                    {
351                        this->setTarget (static_cast<ControllableEntity*>(*itP));
352                    }
353                }
354                if (!this->hasTarget())
355                {
356                    this->nextActionpoint();
357                    this->executeActionpoint();
358                }
359                break;
360            }
361            default:
362                break;
363        }
364       
365    }
366
367   
368    void ActionpointController::stayNearProtect()
369    {
370        Vector3 targetRelativePosition(0, 300, 300); 
371        Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) + 
372            (this->getProtect()->getWorldOrientation()* (targetRelativePosition)));
373        this->setTargetPosition(targetAbsolutePosition);
374        if (this->actionCounter_ % 3 == 0)
375            this->setTargetOrientation(this->getProtect()->getWorldOrientation());
376    }
377    void ActionpointController::nextActionpoint()
378    {
379        if (!this || !this->getControllableEntity())
380            return;
381        if (this->bLoop_)
382        {
383            if (!this->loopActionpoints_.empty())
384            {
385                this->moveBackToTop();
386            }
387        }
388        else
389        {
390            if (!this->parsedActionpoints_.empty())
391            {
392                this->parsedActionpoints_.pop_back();
393            }           
394        }
395        this->setAction(Action::NONE);
396        this->bHasTargetPosition_ = false;
397    }
398    void ActionpointController::moveBackToTop()
399    {
400        Point temp = loopActionpoints_.back();
401        loopActionpoints_.pop_back();
402        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
403        loopActionpoints_.push_back(temp);
404        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
405    }
406    void ActionpointController::fillLoop()
407    {
408        loopActionpoints_.clear();
409        fillLoopReversed();
410        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
411    }
412    void ActionpointController::fillLoopReversed()
413    {
414        if (parsedActionpoints_.back().inLoop)
415        {
416            loopActionpoints_.push_back(parsedActionpoints_.back());
417            parsedActionpoints_.pop_back();
418        }
419        if (parsedActionpoints_.back().inLoop)
420        {
421            fillLoopReversed();
422        }
423    }
424    void ActionpointController::action()
425    {
426        if (!this || !this->getControllableEntity())
427            return;
428        // orxout (internal_error) << "Size of actions is " << this->parsedActionpoints_.size() << endl;
429        if (this->actionCounter_ % 2 == 0)
430            this->startAttackingEnemiesThatAreClose();
431        //No action -> pop one from stack
432        if (this->action_ == Action::NONE || this->bTakenOver_)
433        {
434            if (this->parsedActionpoints_.empty() && this->loopActionpoints_.empty())
435            {
436                Point p = { Action::FIGHTALL, "", Vector3::ZERO, false };
437                this->parsedActionpoints_.push_back (p);
438
439            }
440            this->executeActionpoint();
441            this->bTakenOver_ = false;
442            this->action();
443        }
444        //Action fightall -> fight till nobody alive
445        if (this->action_ == Action::FIGHTALL)
446        {
447            if (!this->hasTarget())
448            {
449                //----find a target----
450                ControllableEntity* newTarget = this->closestTarget();   
451                if (newTarget)
452                {
453                    this->setAction (Action::FIGHTALL, newTarget);
454                }
455                else
456                {
457                    this->nextActionpoint();
458
459                    if (!(this->parsedActionpoints_.empty() && this->loopActionpoints_.empty()))
460                    {
461                        this->action();
462                    }
463                   
464                }
465            }
466            else if (this->hasTarget())
467            {
468
469            }
470        }
471        //Action fight -> fight as long as enemies in range
472        else if (this->action_ == Action::FIGHT)
473        {
474            if (!this->hasTarget())
475            {
476                //----find a target----
477                ControllableEntity* newTarget = this->closestTarget();   
478                if (newTarget && 
479                        CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
480                {
481                    this->setAction (Action::FIGHT, newTarget);
482                }
483                else
484                {
485                    this->nextActionpoint();
486                    this->action();
487                }
488            }
489            else if (this->hasTarget())
490            {
491                //----fly in formation if far enough----
492                Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();         
493                   
494                if (diffVector.length() > this->attackRange_)
495                {
496                    ControllableEntity* newTarget = this->closestTarget();
497                   
498                    if (newTarget && 
499                        CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
500                    {
501                        this->setAction (Action::FIGHT, newTarget);
502                    }
503                    else
504                    {
505                        this->nextActionpoint();
506                        this->action();
507                    }
508                }
509            }
510        }
511        else if (this->action_ == Action::FLY)
512        {
513            if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
514            {
515                this->nextActionpoint();   
516                this->action();
517            }
518        }
519        else if (this->action_ == Action::PROTECT)
520        {
521            if (!this->getProtect())
522            {
523                this->nextActionpoint();
524                this->action(); 
525            }
526            this->stayNearProtect();
527        }
528        else if (this->action_ == Action::ATTACK)
529        {   
530            if (!this->hasTarget())
531            {
532                this->nextActionpoint();
533                this->action();
534            }
535        }
536        if (this->hasTarget())
537        {
538            //----choose where to go----
539            this->maneuver();
540            //----fire if you can----
541            this->bShooting_ = this->canFire();               
542        }
543        this->actionCounter_ += this->actionCounter_ < 100000 ? 1 : -this->actionCounter_ ;
544
545    }
546    void ActionpointController::takeActionpoints (const std::vector<Point>& vector, const std::vector<Point>& loop, bool b)
547    {
548      this->parsedActionpoints_ = vector;
549      this->loopActionpoints_ = loop;
550      this->bLoop_ = b;
551      this->bTakenOver_ = true;
552      // orxout(internal_error) << "Top action is " << this->parsedActionpoints_.back().action << endl;
553    }
554    void ActionpointController::setClosestTarget()
555    {
556        this->setTarget (static_cast<ControllableEntity*>( closestTarget() ) ); 
557    }
558    Pawn* ActionpointController::closestTarget()
559    {
560        if (!this->getControllableEntity())
561            return 0;
562
563        Pawn* closestTarget = 0;
564        float minDistance =  std::numeric_limits<float>::infinity();
565        Gametype* gt = this->getGametype();
566        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
567        {
568            if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
569                continue;
570
571            float distance = CommonController::distance (*itP, this->getControllableEntity());
572            if (distance < minDistance)
573            {
574                closestTarget = *itP;
575                minDistance = distance;
576            }
577        }
578        if (closestTarget)
579        {
580           return closestTarget;
581        } 
582        return 0; 
583    }
584    void ActionpointController::startAttackingEnemiesThatAreClose()
585    {
586        if (this->action_ != Action::FIGHT && this->action_ != Action::FIGHTALL)
587        {
588            if (!this->target_ || (this->target_ && CommonController::distance (this->getControllableEntity(), this->target_) > this->attackRange_))
589            {
590                Pawn* newTarget = this->closestTarget();
591                if ( newTarget && 
592                    CommonController::distance (this->getControllableEntity(), static_cast<ControllableEntity*>(newTarget))
593                        <= this->attackRange_ )
594                {
595                    Point p = { Action::FIGHT, CommonController::getName(newTarget), Vector3::ZERO, false };
596                    this->parsedActionpoints_.push_back(p);
597                    this->executeActionpoint();
598                }
599            }
600        }
601    }
602}
Note: See TracBrowser for help on using the repository browser.