Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

almost all works now, check AITest.oxw

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