Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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