Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

fixed loops

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