Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/campaignHS15/src/orxonox/controllers/CommonController.cc @ 10861

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

finished everything, demos are commented out in AITest.oxw

File size: 42.3 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or ( at your option )any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Dominik Solenicki
26 *
27 */
28#include "controllers/CommonController.h"
29#include "core/XMLPort.h"
30
31//stuff for sameTeam function
32#include "worldentities/pawns/TeamBaseMatchBase.h"
33#include "gametypes/TeamDeathmatch.h"
34#include "gametypes/Dynamicmatch.h"
35#include "gametypes/Mission.h"
36#include "gametypes/Gametype.h"
37#include "controllers/WaypointPatrolController.h"
38#include "controllers/NewHumanController.h"
39#include "controllers/DroneController.h"
40
41
42namespace orxonox
43{
44
45    RegisterClass( CommonController );
46    const float SPEED = 0.9f/0.02f;
47    const float ROTATEFACTOR = 1.0f/0.02f;
48
49    //Table of content:
50    //Constructor, Destructor & tick
51    //XML methods
52    //World interaction
53    //Helper methods
54    //Flying methods
55    //Fighting methods
56    //Actionpoint methods
57
58
59    //------------------------------------------------------------------------------
60    //------------------------Constructor, Destructor & tick------------------------
61    //------------------------------------------------------------------------------
62   
63    CommonController::CommonController( Context* context ): Controller( context )
64    {
65        this->squaredaccuracy_ = 2500;
66        this->bFirstTick_ = true;
67        this->tolerance_ = 50;
68        this->action_ = Action::NONE;
69        this->stopLookingAtTarget();
70        this->attackRange_ = 2500;
71        this->bInLoop_ = false;
72        this->bLoop_ = false;
73        this->bEndLoop_ = false;
74        this->parsedActionpoints_.clear();
75        RegisterObject( CommonController );
76        this->bTakenOver_ = false;
77    }
78    CommonController::~CommonController() 
79    {
80        parsedActionpoints_.clear();
81        actionpoints_.clear();
82    }
83    void CommonController::tick(float dt)
84    {
85        if (this->bHasTargetPosition_)
86        {
87            this->moveToTargetPosition(dt);
88        }
89        else if (this->bLookAtTarget_)
90        {
91            this->lookAtTarget(dt);
92        }
93        if (bShooting_)
94        {
95            this->doFire();
96        }
97        if (this->bFirstTick_)
98        {
99            std::reverse(parsedActionpoints_.begin(), parsedActionpoints_.end());
100            std::reverse(actionpoints_.begin(), actionpoints_.end());
101            if (this->parsedActionpoints_.empty())
102            {
103                this->action_ = Action::FIGHTALL;
104            }
105        }
106        if (this->bFirstTick_)
107            this->bFirstTick_ = false;
108        SUPER(CommonController, tick, dt);
109    }
110
111    //------------------------------------------------------------------------------
112    //----------------------------------XML methods---------------------------------
113    //------------------------------------------------------------------------------
114   
115    void CommonController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
116    {
117        SUPER( CommonController, XMLPort, xmlelement, mode );
118        XMLPortParam( CommonController, "formationMode", setFormationModeXML, getFormationModeXML,  xmlelement, mode );
119        XMLPortObject(CommonController, WorldEntity, "actionpoints", addActionpoint, getActionpoint,  xmlelement, mode);
120    }
121    void CommonController::setFormationModeXML( std::string val )
122    {
123        const std::string valUpper = getUppercase( val );
124        FormationMode::Value value;
125       
126        if ( valUpper == "WALL" )
127            value = FormationMode::WALL;
128        else if ( valUpper == "FINGER4" )
129            value = FormationMode::FINGER4;
130        else if ( valUpper == "DIAMOND" )
131            value = FormationMode::DIAMOND;
132        else
133            ThrowException( ParseError, std::string( "Attempting to set an unknown FormationMode: '" )+ val + "'." );
134        this->setFormationMode( value );
135    }
136    std::string CommonController::getFormationModeXML() 
137    {
138        switch ( this->formationMode_ )
139        {
140            case FormationMode::WALL:
141            { return "WALL"; break; }
142            case FormationMode::FINGER4:
143            { return "FINGER4"; break; }
144            case FormationMode::DIAMOND:
145            { return "DIAMOND"; break; }
146            default:
147                return "DIAMOND"; break;
148        }
149    }
150    void CommonController::setFormationMode(FormationMode::Value val)
151    { 
152        this->formationMode_ = val; 
153    }
154    FormationMode::Value CommonController::getFormationMode() const
155    { 
156        return this->formationMode_; 
157    }
158    void CommonController::setRank(Rank::Value val)
159    { 
160        this->rank_ = val; 
161    }
162    Rank::Value CommonController::getRank() const
163    { 
164        return this->rank_; 
165    }
166    void CommonController::addActionpoint(WorldEntity* actionpoint)
167    {
168        std::string actionName;
169        Vector3 position;
170        std::string targetName;
171        bool inLoop = false;
172        Point p;
173        if (static_cast<Actionpoint*> (actionpoint))
174        {
175            Actionpoint* ap = static_cast<Actionpoint*> (actionpoint);
176            actionName = ap->getActionXML();
177            targetName = ap->getName();
178            position = ap->getWorldPosition();
179
180            if (this->bEndLoop_)
181            {
182                this->bInLoop_ = false;
183            }
184            if (!this->bInLoop_ && ap->getLoopStart())
185            {
186                this->bInLoop_ = true;
187            }
188            if (this->bInLoop_ && ap->getLoopEnd())
189            {
190                this->bEndLoop_ = true;
191            }
192            inLoop = this->bInLoop_;
193
194            Action::Value value;
195           
196            if ( actionName == "FIGHT" )
197            { value = Action::FIGHT; }
198            else if ( actionName == "FLY" )
199            { value = Action::FLY; }
200            else if ( actionName == "PROTECT" )
201            { value = Action::PROTECT; }
202            else if ( actionName == "NONE" )
203            { value = Action::NONE; }
204            else if ( actionName == "FIGHTALL" )
205            { value = Action::FIGHTALL; }
206            else if ( actionName == "ATTACK" )
207            { value = Action::ATTACK; }
208            else
209                ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ actionName + "'." );
210            p.action = value; p.name = targetName; p.position = position; p.inLoop = inLoop;
211        }
212        else
213        {
214            p.action = Action::FLY; p.name = ""; p.position = actionpoint->getWorldPosition(); p.inLoop = inLoop;
215        }
216            parsedActionpoints_.push_back(p);
217            this->actionpoints_.push_back(actionpoint);
218    }
219    WorldEntity* CommonController::getActionpoint(unsigned int index) const
220    {
221        if (index < this->actionpoints_.size())
222            return this->actionpoints_[index];
223        else
224            return 0;
225    }
226
227    //------------------------------------------------------------------------------
228    //-------------------------------World interaction------------------------------
229    //------------------------------------------------------------------------------
230
231    //"Virtual" methods
232    bool CommonController::setWingman ( CommonController* wingman )
233    { return false; }
234    bool CommonController::hasWingman() 
235    { return true; }
236    bool CommonController::hasTarget() 
237    {
238        if ( this->target_ )
239            return true;
240        return false;
241    }
242    ControllableEntity* CommonController::getTarget()
243    {
244        return this->target_;
245    }
246    Action::Value CommonController::getAction ()
247    {
248        return this->action_;
249    }
250    std::string CommonController::getActionName()
251    {
252        switch ( this->action_ )
253        {
254            case Action::FIGHT:
255            { return "FIGHT"; break; }
256            case Action::FLY:
257            { return "FLY"; break; }
258            case Action::PROTECT:
259            { return "PROTECT"; break; }
260            case Action::NONE:
261            { return "NONE"; break; }
262            case Action::FIGHTALL:
263            { return "FIGHTALL"; break; }
264            case Action::ATTACK:
265            { return "ATTACK"; break; }
266            default:
267                return "NONE";
268                break;
269        }
270    }
271    void CommonController::setAction (Action::Value action)
272    {
273        this->action_ = action;
274    }
275    void CommonController::setAction (Action::Value action, ControllableEntity* target)
276    {
277        this->action_ = action;
278        if (action == Action::FIGHT || action == Action::FIGHTALL || action == Action::ATTACK)
279        {   
280            if (target)
281                this->setTarget (target);
282        }
283        else if (action == Action::PROTECT)
284        {
285            if (target)
286                this->setProtect (target);
287        }
288    }
289    void CommonController::setAction (Action::Value action, const Vector3& target)
290    {
291        this->action_ = action;
292        if (action == Action::FLY)
293        {
294            this->setTargetPosition (target);
295        }
296    }
297    void CommonController::setAction (Action::Value action, const Vector3& target,  const Quaternion& orient )
298    {
299        this->action_ = action;
300        if (action == Action::FLY)
301        {
302            this->setTargetPosition (target);
303            this->setTargetOrientation (orient);
304        } 
305    }
306
307    //------------------------------------------------------------------------------
308    //--------------------------------Helper methods--------------------------------
309    //------------------------------------------------------------------------------
310
311    float CommonController::randomInRange( float a, float b )
312    {
313        float random = rnd( 1.0f );
314        float diff = b - a;
315        float r = random * diff;
316        return a + r;
317    }
318    float CommonController::distance (ControllableEntity* entity1, ControllableEntity* entity2)
319    {
320        if (!entity1 || !entity2)
321            return std::numeric_limits<float>::infinity();
322        return ( entity1->getPosition() - entity2->getPosition() ).length();
323    }
324    bool CommonController::sameTeam (ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
325    {
326        /*if (!entity1 || !entity2)
327            return false;
328        return entity1->getTeam() == entity2->getTeam();*/
329        if (entity1 == entity2)
330            return true;
331
332        int team1 = entity1->getTeam();
333        int team2 = entity2->getTeam();
334
335        Controller* controller = 0;
336        if (entity1->getController())
337            controller = entity1->getController();
338        else
339            controller = entity1->getXMLController();
340        if (controller)
341        {
342            CommonController* ac = orxonox_cast<CommonController*>(controller);
343            if (ac)
344                team1 = ac->getTeam();
345        }
346
347        if (entity2->getController())
348            controller = entity2->getController();
349        else
350            controller = entity2->getXMLController();
351        if (controller)
352        {
353            CommonController* ac = orxonox_cast<CommonController*>(controller);
354            if (ac)
355                team2 = ac->getTeam();
356        }
357
358        TeamGametype* tdm = orxonox_cast<TeamGametype*>(gametype);
359        if (tdm)
360        {
361            if (entity1->getPlayer())
362                team1 = tdm->getTeam(entity1->getPlayer());
363
364            if (entity2->getPlayer())
365                team2 = tdm->getTeam(entity2->getPlayer());
366        }
367
368        TeamBaseMatchBase* base = 0;
369        base = orxonox_cast<TeamBaseMatchBase*>(entity1);
370        if (base)
371        {
372            switch (base->getState())
373            {
374                case BaseState::ControlTeam1:
375                    team1 = 0;
376                    break;
377                case BaseState::ControlTeam2:
378                    team1 = 1;
379                    break;
380                case BaseState::Uncontrolled:
381                default:
382                    team1 = -1;
383            }
384        }
385        base = orxonox_cast<TeamBaseMatchBase*>(entity2);
386        if (base)
387        {
388            switch (base->getState())
389            {
390                case BaseState::ControlTeam1:
391                    team2 = 0;
392                    break;
393                case BaseState::ControlTeam2:
394                    team2 = 1;
395                    break;
396                case BaseState::Uncontrolled:
397                default:
398                    team2 = -1;
399            }
400        }
401
402        DroneController* droneController = 0;
403        droneController = orxonox_cast<DroneController*>(entity1->getController());
404        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)
405            return true;
406        droneController = orxonox_cast<DroneController*>(entity2->getController());
407        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)
408            return true;
409        DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController());
410        DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController());
411        if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner())
412            return true;
413
414        Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype);
415        if (dynamic)
416        {
417            if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;}
418
419            if (entity1->getPlayer())
420                team1 = dynamic->getParty(entity1->getPlayer());
421
422            if (entity2->getPlayer())
423                team2 = dynamic->getParty(entity2->getPlayer());
424
425            if (team1 ==-1 ||team2 ==-1 ) {return false;}
426            else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;}
427            else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;}
428            else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;}
429            else return true;
430        }
431
432        return (team1 == team2 && team1 != -1);
433    }
434    bool CommonController::isLooking( ControllableEntity* entityThatLooks, ControllableEntity* entityBeingLookedAt, float angle )
435    {
436        if ( !entityThatLooks || !entityBeingLookedAt )
437            return false;
438        return ( getAngle( entityThatLooks ->getPosition() , 
439            entityThatLooks->getOrientation()  * WorldEntity::FRONT, 
440            entityBeingLookedAt->getWorldPosition() ) < angle );
441    }
442    std::string CommonController::getName(Pawn* entity)
443    {
444        std::string name = entity->getName();
445        if (name == "")
446        {
447            const void * address = static_cast<const void*>(entity);
448            std::stringstream ss;
449            ss << address; 
450            name = ss.str();           
451        }
452        return name;
453    }
454    float CommonController::squaredDistanceToTarget()  const
455    {
456        if ( !this->getControllableEntity()  )
457            return 0;
458        if ( !this->target_ || !this->getControllableEntity() )
459            return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->targetPosition_ ) );
460        else
461            return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->positionOfTarget_ ) );
462    }
463    bool CommonController::isLookingAtTarget( float angle )
464    {
465        if ( !this->getControllableEntity()  || !this->target_ )
466            return false;
467        return this->isLooking(this->getControllableEntity(), this->getTarget(), angle);
468    }
469
470
471    //------------------------------------------------------------------------------
472    //--------------------------------Flying methods--------------------------------
473    //------------------------------------------------------------------------------
474
475    void CommonController::stopMoving()
476    {
477        this->bHasTargetPosition_ = false;
478    }
479    void CommonController::stopLookingAtTarget()
480    {
481        this->bLookAtTarget_ = false;
482    }
483    void CommonController::startLookingAtTarget()
484    {
485        this->bLookAtTarget_ = true;
486    }
487    void CommonController::moveToPosition( const Vector3& target, float dt )
488    {
489        ControllableEntity* entity = this->getControllableEntity();
490        Vector2 coord = get2DViewCoordinates
491            ( entity->getPosition() , 
492            entity->getOrientation()  * WorldEntity::FRONT, 
493            entity->getOrientation()  * WorldEntity::UP, 
494            target );
495
496        float distance = ( target - this->getControllableEntity() ->getPosition() ).length();
497        float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );
498        float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
499
500        if ( distance > this->tolerance_ )
501        {
502            this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );
503            this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );
504
505            if ( distance < 300 )
506            {
507                if ( bHasTargetOrientation_ )
508                {
509                    copyTargetOrientation( dt );
510                }
511            }
512            if (distance > this->tolerance_*1.5f || (rotateX > -0.01 && rotateX < 0.01 && rotateY > -0.01 && rotateY < 0.01))
513                this->getControllableEntity() ->moveFrontBack( SPEED * dt );
514        }
515        else
516        {     
517            bHasTargetPosition_ = false;
518            bHasTargetOrientation_ = false;
519        }
520    }
521    void CommonController::moveToTargetPosition(float dt)
522    {
523        this->moveToPosition (this->targetPosition_, dt);
524    }
525    void CommonController::copyOrientation( const Quaternion& orient, float dt )
526    {
527        //roll angle difference in radian
528        float diff=orient.getRoll(false).valueRadians() -
529                        ( this->getControllableEntity() ->getOrientation() .getRoll( false ).valueRadians() );
530        while( diff>math::twoPi )diff-=math::twoPi;
531        while( diff<-math::twoPi )diff+=math::twoPi;
532        this->getControllableEntity() ->rotateRoll( diff*0.2f*ROTATEFACTOR * dt );
533    }
534    void CommonController::copyTargetOrientation( float dt )
535    {
536        if ( bHasTargetOrientation_ )
537        {   
538            copyOrientation( targetOrientation_, dt );
539        }
540    }
541    void CommonController::lookAtTarget(float dt)
542    {
543        ControllableEntity* entity = this->getControllableEntity();
544        if ( !entity )
545            return;
546        Vector2 coord = get2DViewCoordinates
547            ( entity->getPosition() , 
548            entity->getOrientation()  * WorldEntity::FRONT, 
549            entity->getOrientation()  * WorldEntity::UP, 
550            positionOfTarget_ );
551
552        //rotates should be in range [-1,+1], clamp cuts off all that is not
553        float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );
554        float rotateY = clamp( coord.y * 10, -1.0f, 1.0f ); 
555   
556        //Yaw and Pitch are enough to start facing the target
557        this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );
558        this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );
559    }
560    void CommonController::setTargetPosition( const Vector3& target )
561    {
562        this->targetPosition_ = target;
563        this->bHasTargetPosition_ = true;
564    }
565
566    void CommonController::setTargetOrientation( const Quaternion& orient )
567    {
568        this->targetOrientation_=orient;
569        this->bHasTargetOrientation_=true;
570    }
571
572    void CommonController::setTargetOrientation( ControllableEntity* target )
573    {
574        if ( target )
575            setTargetOrientation( target->getOrientation() );
576    }
577
578    //------------------------------------------------------------------------------
579    //-------------------------------Fighting methods-------------------------------
580    //------------------------------------------------------------------------------
581
582    void CommonController::setTarget( ControllableEntity* target )
583    {
584        this->target_ = target;       
585        if ( this->target_ )
586        {
587            this->setPositionOfTarget( target_->getWorldPosition() );
588        }
589    }
590    void CommonController::setPositionOfTarget( const Vector3& target )
591    {
592        this->positionOfTarget_ = target;
593        this->bHasPositionOfTarget_ = true;
594    }
595    void CommonController::setOrientationOfTarget( const Quaternion& orient )
596    {
597        this->orientationOfTarget_=orient;
598        this->bHasOrientationOfTarget_=true;
599    }
600    void CommonController::setProtect (ControllableEntity* protect)
601    {
602        this->protect_ = protect;
603    }
604    ControllableEntity* CommonController::getProtect ()
605    {
606        return this->protect_;
607    }
608    void CommonController::maneuver() 
609    {
610        maneuverCounter_++;
611        if (maneuverCounter_ > 5)
612            maneuverCounter_ = 0;
613
614        if ( !this->target_ || !this->getControllableEntity())
615            return;
616       
617        Vector3 thisPosition = this->getControllableEntity()->getWorldPosition();
618        this->setPositionOfTarget( getPredictedPosition( 
619            thisPosition, 
620            hardcoded_projectile_speed, 
621            this->target_->getWorldPosition() , 
622            this->target_->getVelocity() 
623            )  );
624        this->setOrientationOfTarget( this->target_->getOrientation() );
625
626        Vector3 diffVector = this->positionOfTarget_ - thisPosition;
627        float diffLength = diffVector.length();
628        Vector3 diffUnit = diffVector/diffLength;
629
630        bool bTargetIsLookingAtThis = this->isLooking ( this->target_, getControllableEntity(), math::pi/10.0f );
631       
632        //too far? well, come closer then
633        if ( diffLength > this->attackRange_ )
634        {
635            this->setTargetPosition( this->positionOfTarget_ );
636        }
637        //too close? How do u expect to dodge anything? Just attack!
638        else if ( diffLength < 500 )
639        {   
640            //at this point, just look and shoot
641            if ( diffLength < 250 )
642            {
643                this->stopMoving();
644                this->startLookingAtTarget();
645            }
646            else
647            {
648                this->setTargetPosition( this->positionOfTarget_ );
649            }
650        }
651        //Good distance? Check if target looks at us. It doesn't? Go hunt!
652        else if ( !bTargetIsLookingAtThis )
653        {
654            this->setTargetPosition( this->positionOfTarget_ );
655        }
656        //That's unfortunate, he is looking and probably shooting... try to dodge what we can... 
657        else 
658        {   
659            if (maneuverCounter_ == 0)
660            {
661                this->setTargetPosition( this->positionOfTarget_ );   
662                return;
663            }
664            dodge( thisPosition, diffUnit );
665        }
666    }
667   
668    void CommonController::dodge(Vector3& thisPosition, Vector3& diffUnit)
669    {
670        float factorX = 0, factorY = 0, factorZ = 0;
671        float rand = randomInRange (0, 1);
672   
673        if (rand <= 0.5)
674        { factorX = 1; }
675        else
676        { factorX = -1; }
677        rand = randomInRange (0, 1);
678        if (rand <= 0.5)
679        { factorY = 1; }
680        else
681        { factorY = -1; }
682        rand = randomInRange (0, 1);
683        if (rand <= 0.5)
684        { factorZ = 1; }
685        else
686        { factorZ = -1; }
687
688        Vector3 target = ( diffUnit )* 8000.0f;
689        Vector3* randVector = new Vector3( 
690            factorX * randomInRange( 10000, 40000 ), 
691            factorY * randomInRange( 10000, 40000 ), 
692            factorZ * randomInRange( 10000, 40000 ) 
693        );
694        Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit;
695        *randVector -= projection;
696        target += *randVector;
697        this->setTargetPosition( thisPosition + target );
698    }
699    bool CommonController::canFire() 
700    {
701        //no target? why fire?
702        if ( !this->target_ )
703            return false;
704
705        Vector3 newPositionOfTarget = getPredictedPosition( this->getControllableEntity() ->getWorldPosition() , 
706            hardcoded_projectile_speed, this->target_->getWorldPosition() , this->target_->getVelocity() );
707        if ( newPositionOfTarget != Vector3::ZERO )
708        {
709            this->setPositionOfTarget( newPositionOfTarget );
710        }
711
712        float squaredDistance = squaredDistanceToTarget();
713
714        if ( squaredDistance < this->attackRange_*this->attackRange_ && this->isLookingAtTarget( math::pi / 20.0f)) 
715        {
716            return true;
717        }
718        else
719        {
720            return false;
721        }
722    }
723    void CommonController::doFire() 
724    {
725        if ( !this->target_ || !this->getControllableEntity() )
726        {
727            return;
728        }
729     
730        Pawn* pawn = orxonox_cast<Pawn*>( this->getControllableEntity() );
731
732        if ( pawn )
733            pawn->setAimPosition( this->positionOfTarget_ );
734        this->getControllableEntity() ->fire( 0 );
735    }
736    void CommonController::setClosestTarget()
737    {
738        this->setTarget (static_cast<ControllableEntity*>( closestTarget() ) ); 
739    }
740    Pawn* CommonController::closestTarget()
741    {
742        if (!this->getControllableEntity())
743            return 0;
744
745        Pawn* closestTarget = 0;
746        float minDistance =  std::numeric_limits<float>::infinity();
747        Gametype* gt = this->getGametype();
748        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
749        {
750            if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
751                continue;
752
753            float distance = CommonController::distance (*itP, this->getControllableEntity());
754            if (distance < minDistance)
755            {
756                closestTarget = *itP;
757                minDistance = distance;
758            }
759        }
760        if (closestTarget)
761        {
762           return closestTarget;
763        } 
764        return 0; 
765    }
766    void CommonController::startAttackingEnemiesThatAreClose()
767    {
768        if (this->action_ != Action::FIGHT && this->action_ != Action::FIGHTALL)
769        {
770            if ( (this->target_ && this->distance (this->getControllableEntity(), this->target_) > this->attackRange_) 
771                || !this->target_ )
772            {
773                Pawn* newTarget = this->closestTarget();
774                if ( newTarget && 
775                    this->distance (this->getControllableEntity(), static_cast<ControllableEntity*>(newTarget))
776                        <= this->attackRange_ )
777                {
778                    Point p = { Action::FIGHT, this->getName(newTarget), Vector3::ZERO, false };
779                    this->parsedActionpoints_.push_back(p);
780                    this->executeActionpoint();
781                }
782            }
783        }
784    }
785
786    //------------------------------------------------------------------------------
787    //------------------------------Actionpoint methods-----------------------------
788    //------------------------------------------------------------------------------
789
790    //POST: this starts doing what was asked by the last element of parsedActionpoints_,
791    //if last element was failed to be parsed, next element will be executed.
792    void CommonController::executeActionpoint()
793    {
794        if (this->bLoop_)
795        {
796            if (!this->loopActionpoints_.empty())
797            {
798                this->action_ = this->loopActionpoints_.back().action;
799                switch ( this->action_ )
800                {
801                    case Action::FIGHT:
802                    {
803                        std::string targetName = this->loopActionpoints_.back().name;
804                        if (targetName == "")
805                        {
806                            break;
807                        }
808                        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
809                        {
810                            if (CommonController::getName(*itP) == targetName)
811                            {
812                                this->setTarget (static_cast<ControllableEntity*>(*itP));
813                            }
814                        }         
815                        break;
816                    }
817                    case Action::FLY:
818                    {
819                        this->setTargetPosition( this->loopActionpoints_.back().position );
820                        if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
821                        {
822                            this->nextActionpoint();
823                            this->executeActionpoint();
824                        }
825                        break;
826                    }
827                    case Action::PROTECT:
828                    {
829                        std::string protectName = this->loopActionpoints_.back().name;
830                        if (protectName == "reservedKeyword:human")
831                        {
832                            for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
833                            {
834                                if (orxonox_cast<ControllableEntity*>(*itP) && ((*itP)->getController()) && orxonox_cast <NewHumanController*> ((*itP)->getController()))
835                                {
836                                    this->setProtect (static_cast<ControllableEntity*>(*itP));
837                                }
838                            }
839                        }
840                        else
841                        {
842                            for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
843                            {
844                                if (CommonController::getName(*itP) == protectName)
845                                {
846                                    this->setProtect (static_cast<ControllableEntity*>(*itP));
847                                }
848                            }                           
849                        }
850                        if (!this->getProtect())
851                        {
852                            this->nextActionpoint();
853                            this->executeActionpoint();
854                        }
855                        break;
856                    }
857                    case Action::NONE:
858                    {
859                        break;
860                    }
861                    case Action::FIGHTALL:
862                    {
863                        break;
864                    }
865                    case Action::ATTACK:
866                    {
867                        std::string targetName = this->loopActionpoints_.back().name;
868
869                        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
870                        {
871                            if (CommonController::getName(*itP) == targetName)
872                            {
873                                this->setTarget (static_cast<ControllableEntity*>(*itP));
874                            }
875                        }
876                        if (!this->hasTarget())
877                        {
878                            this->nextActionpoint();
879                            this->executeActionpoint();
880                        }
881                        break;
882                    }
883                    default:
884                        break;
885                }
886            }
887            else
888            {
889                this->bLoop_ = false;
890            }
891        }
892        else
893        {
894            if (!this->parsedActionpoints_.empty())
895            {
896                if (this->parsedActionpoints_.back().inLoop)
897                {
898                    //MOVES all points that are in loop to a loop vector
899                    this->fillLoop();
900                    this->bLoop_ = true;
901                    executeActionpoint();
902                    return;
903                }
904                this->action_ = this->parsedActionpoints_.back().action;
905                switch ( this->action_ )
906                {
907                    case Action::FIGHT:
908                    {
909                        std::string targetName = this->parsedActionpoints_.back().name;
910                        if (targetName == "")
911                        {
912                            break;
913                        }
914                        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
915                        {
916                            if (CommonController::getName(*itP) == targetName)
917                            {
918                                this->setTarget (static_cast<ControllableEntity*>(*itP));
919                            }
920                        }         
921                        break;
922                    }
923                    case Action::FLY:
924                    {
925                        this->setTargetPosition( this->parsedActionpoints_.back().position );
926                        if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
927                        {
928                            this->nextActionpoint();
929                            this->executeActionpoint();
930                        }
931                        break;
932                    }
933                    case Action::PROTECT:
934                    {
935                       
936                        std::string protectName = this->parsedActionpoints_.back().name;
937                        if (protectName == "reservedKeyword:human")
938                        {
939                            for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
940                            {
941                                if (orxonox_cast<ControllableEntity*>(*itP) && ((*itP)->getController()) && orxonox_cast <NewHumanController*> ((*itP)->getController()))
942                                {
943                                    this->setProtect (static_cast<ControllableEntity*>(*itP));
944                                }
945                            }
946                        }
947                        else
948                        {
949                            for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
950                            {
951                                if (CommonController::getName(*itP) == protectName)
952                                {
953                                    this->setProtect (static_cast<ControllableEntity*>(*itP));
954                                }
955                            }                           
956                        }
957                        if (!this->getProtect())
958                        {
959                            this->nextActionpoint();
960                            this->executeActionpoint();
961                        }
962                        break;
963                    }
964                    case Action::NONE:
965                    {
966                        break;
967                    }
968                    case Action::FIGHTALL:
969                    {
970                        break;
971                    }
972                    case Action::ATTACK:
973                    {
974                        std::string targetName = this->parsedActionpoints_.back().name;
975
976                        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
977                        {
978                            if (CommonController::getName(*itP) == targetName)
979                            {
980                                this->setTarget (static_cast<ControllableEntity*>(*itP));
981                            }
982                        }
983                        if (!this->hasTarget())
984                        {
985                            this->nextActionpoint();
986                            this->executeActionpoint();
987                        }
988                        break;
989                    }
990                    default:
991                        break;
992                }
993            }
994            else
995            {
996                this->setTarget(0);
997                this->setTargetPosition(this->getControllableEntity()->getWorldPosition());
998                this->action_ = Action::NONE;
999            }
1000        }
1001
1002    }
1003    void CommonController::stayNearProtect()
1004    {
1005        Vector3* targetRelativePosition;
1006        targetRelativePosition = new Vector3 (0, 300, 300); 
1007        Vector3 targetAbsolutePosition = ((this->getProtect()->getWorldPosition()) + 
1008            (this->getProtect()->getWorldOrientation()* (*targetRelativePosition)));
1009        this->setTargetPosition(targetAbsolutePosition);
1010    }
1011    void CommonController::nextActionpoint()
1012    {
1013        if (!this || !this->getControllableEntity())
1014            return;
1015        if (this->bLoop_)
1016        {
1017            if (!this->loopActionpoints_.empty())
1018            {
1019                this->moveBackToTop();
1020            }
1021        }
1022        else
1023        {
1024            if (!this->parsedActionpoints_.empty())
1025            {
1026                this->parsedActionpoints_.pop_back();
1027            }           
1028        }
1029        this->setAction(Action::NONE);
1030    }
1031    void CommonController::moveBackToTop()
1032    {
1033        Point temp = loopActionpoints_.back();
1034        loopActionpoints_.pop_back();
1035        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
1036        loopActionpoints_.push_back(temp);
1037        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
1038    }
1039    void CommonController::fillLoop()
1040    {
1041        loopActionpoints_.clear();
1042        fillLoopReversed();
1043        std::reverse (loopActionpoints_.begin(), loopActionpoints_.end());
1044    }
1045    void CommonController::fillLoopReversed()
1046    {
1047        if (parsedActionpoints_.back().inLoop)
1048        {
1049            loopActionpoints_.push_back(parsedActionpoints_.back());
1050            parsedActionpoints_.pop_back();
1051        }
1052        if (parsedActionpoints_.back().inLoop)
1053        {
1054            fillLoopReversed();
1055        }
1056    }
1057    void CommonController::action()
1058    {
1059        if (!this || !this->getControllableEntity())
1060            return;
1061        // orxout (internal_error) << "Size of actions is " << this->parsedActionpoints_.size() << endl;
1062        this->startAttackingEnemiesThatAreClose();
1063        //No action -> pop one from stack
1064        if (this->action_ == Action::NONE || this->bTakenOver_)
1065        {
1066            if (this->parsedActionpoints_.empty() && this->loopActionpoints_.empty())
1067            {
1068                Point p = { Action::FIGHTALL, "", Vector3::ZERO, false };
1069                this->parsedActionpoints_.push_back (p);
1070            }
1071            this->executeActionpoint();
1072            this->bTakenOver_ = false;
1073        }
1074        //Action fightall -> fight till nobody alive
1075        if (this->action_ == Action::FIGHTALL)
1076        {
1077            if (!this->hasTarget())
1078            {
1079                //----find a target----
1080                ControllableEntity* newTarget = this->closestTarget();   
1081                if (newTarget)
1082                {
1083                    this->setAction (Action::FIGHTALL, newTarget);
1084                }
1085                else
1086                {
1087                    this->nextActionpoint();
1088                    return;
1089                }
1090            }
1091            else if (this->hasTarget())
1092            {
1093
1094            }
1095        }
1096        //Action fight -> fight as long as enemies in range
1097        else if (this->action_ == Action::FIGHT)
1098        {
1099            if (!this->hasTarget())
1100            {
1101                //----find a target----
1102                ControllableEntity* newTarget = this->closestTarget();   
1103                if (newTarget && 
1104                        CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
1105                {
1106                    this->setAction (Action::FIGHT, newTarget);
1107                }
1108                else
1109                {
1110                    this->nextActionpoint();
1111                    return;
1112                }
1113            }
1114            else if (this->hasTarget())
1115            {
1116                //----fly in formation if far enough----
1117                Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity()->getWorldPosition();         
1118                   
1119                if (diffVector.length() > this->attackRange_)
1120                {
1121                    ControllableEntity* newTarget = this->closestTarget();
1122                   
1123                    if (newTarget && 
1124                        CommonController::distance (this->getControllableEntity(), newTarget) < this->attackRange_)
1125                    {
1126                        this->setAction (Action::FIGHT, newTarget);
1127                    }
1128                    else
1129                    {
1130                        this->nextActionpoint();
1131                        return;
1132                    }
1133                }
1134            }
1135        }
1136        else if (this->action_ == Action::FLY)
1137        {
1138            if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
1139            {
1140                this->nextActionpoint();   
1141                return;
1142            }
1143        }
1144        else if (this->action_ == Action::PROTECT)
1145        {
1146            if (!this->getProtect())
1147            {
1148                this->nextActionpoint(); 
1149                return;
1150            }
1151            this->stayNearProtect();
1152        }
1153        else if (this->action_ == Action::ATTACK)
1154        {   
1155            if (!this->hasTarget())
1156            {
1157                this->nextActionpoint();
1158                return;
1159            }
1160        }
1161        if (this->hasTarget())
1162        {
1163            //----choose where to go----
1164            this->maneuver();
1165            //----fire if you can----
1166            this->bShooting_ = this->canFire();               
1167        }
1168    }
1169    void CommonController::takeActionpoints (std::vector<Point > vector, std::vector<Point > loop, bool b)
1170    {
1171      this->parsedActionpoints_ = vector;
1172      this->loopActionpoints_ = loop;
1173      this->bLoop_ = this->bLoop_;
1174      this->bTakenOver_ = true;
1175      // orxout(internal_error) << "Top action is " << this->parsedActionpoints_.back().action << endl;
1176    }
1177    void CommonController::boostControl()
1178    {
1179        SpaceShip* ship = orxonox_cast<SpaceShip*>(this->getControllableEntity());
1180        if(ship == NULL) return;
1181        if(ship->getBoostPower()*1.5f > ship->getInitialBoostPower() ) //upper limit ->boost
1182        {
1183
1184            this->getControllableEntity()->boost(true);
1185        }
1186        else if(ship->getBoostPower()*4.0f < ship->getInitialBoostPower()) //lower limit ->do not boost
1187        {
1188           this->getControllableEntity()->boost(false);
1189        }
1190    }
1191}
Note: See TracBrowser for help on using the repository browser.