Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

still not compilable

File size: 33.8 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//bug or feature? Press 4 control keys from {Q,W,E,A,S,D,C} at the same time or 3 keys from {Q,E,A,D}, spaceship goes in free fly mode
29#include "controllers/CommonController.h"
30#include "core/XMLPort.h"
31
32#include "weaponsystem/WeaponMode.h"
33#include "weaponsystem/WeaponPack.h"
34#include "weaponsystem/Weapon.h"
35#include "weaponsystem/WeaponSlot.h"
36#include "weaponsystem/WeaponSlot.h"
37#include "worldentities/pawns/SpaceShip.h"
38
39#include "Scene.h"
40
41#include "worldentities/pawns/TeamBaseMatchBase.h"
42#include "gametypes/TeamDeathmatch.h"
43#include "gametypes/Dynamicmatch.h"
44#include "gametypes/Mission.h"
45#include "gametypes/Gametype.h"
46#include "controllers/WaypointPatrolController.h"
47#include "controllers/NewHumanController.h"
48#include "controllers/DroneController.h"
49
50
51namespace orxonox
52{
53
54    RegisterClass( CommonController );
55    const float SPEED = 0.9f/0.02f;
56    const float ROTATEFACTOR = 1.0f/0.02f;
57
58    CommonController::CommonController( Context* context ): Controller( context )
59    {
60        this->action_ = Action::FLY;
61        this->stopLookingAtTarget();
62        this->attackRange_ = 2500;
63        RegisterObject( CommonController );
64    }
65
66
67    CommonController::~CommonController() 
68    {
69        //orxout(internal_error) << "I died, my Rank is " << rank_ << endl;
70    }
71    void CommonController::backupAction()
72    {
73        this->actionpoints_.push_back (this->currentActionpoint_);
74    }
75    void CommonController::restoreAction()
76    {
77        this->currentActionpoint_ = this->actionpoints_.back();
78        this->actionpoints_.pop_back();
79    }
80    void CommonController::popAction()
81    {
82        this->currentActionpoint_ = actionpoints_.back();
83        actionpoints_.pop_back();
84    }
85
86    void CommonController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
87    {
88        SUPER( CommonController, XMLPort, xmlelement, mode );
89        XMLPortParam( CommonController, "formationMode", setFormationModeXML, getFormationModeXML,  xmlelement, mode );
90        //XMLPortParam( CommonController, "action", setActionXML, getActionXML,  xmlelement, mode );
91        //XMLPortParam ( CommonController, "protect", setProtectXML, getProtectXML,  xmlelement, mode );
92        //XMLPortParam ( CommonController, "enemy", setEnemyXML, getEnemyXML,  xmlelement, mode );
93        XMLPortObject(CommonController, WorldEntity, "actionpoints", addActionpoint, getActionpoint,  xmlelement, mode);
94
95    }
96    void CommonController::setProtectXML( std::string val )
97    {
98        this->protectName_ = val;
99       
100    }
101    void CommonController::tick(float dt)
102    {
103        if (this->bHasTargetPosition_)
104        {
105            this->moveToTargetPosition(dt);
106        }
107        else if (this->bLookAtTarget_)
108        {
109            this->lookAtTarget(dt);
110        }
111        if (bShooting_)
112        {
113            this->doFire();
114        }
115        SUPER(CommonController, tick, dt);
116    }
117
118    std::string CommonController::getProtectXML ()
119    {
120        if (!this->getProtect())
121            return "noProtectWasSet";
122        return CommonController::getName (this->getProtect());
123    }
124    std::string CommonController::getName(Pawn* entity)
125    {
126        std::string name = entity->getName();
127        if (name == "")
128        {
129            const void * address = static_cast<const void*>(entity);
130            std::stringstream ss;
131            ss << address; 
132            name = ss.str();           
133        }
134        return name;
135
136    }
137    void CommonController::setProtect (ControllableEntity* protect)
138    {
139        this->protect_ = protect;
140    }
141    ControllableEntity* CommonController::getProtect ()
142    {
143        return this->protect_;
144    }
145    void CommonController::setActionXML( std::string val)
146    {
147        const std::string valUpper = getUppercase( val );
148        Action::Value value;
149       
150        if ( valUpper == "FIGHT" )
151            value = Action::FIGHT;
152        else if ( valUpper == "FLY" )
153            value = Action::FLY;
154        else if ( valUpper == "PROTECT" )
155            value = Action::PROTECT;
156        else if ( valUpper == "NONE" )
157            value = Action::NONE;
158        else if ( valUpper == "FIGHTALL" )
159            value = Action::FIGHTALL;
160        else if ( valUpper == "ATTACK" )
161            value = Action::ATTACK;
162        else
163            ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ val + "'." );
164        this->setAction( value );
165    }
166    std::string CommonController::getActionXML()
167    {
168        switch ( this->action_ )
169        {
170            case Action::FIGHT:
171            {
172                return "FIGHT";
173                break;
174            }
175            case Action::FLY:
176            {
177                return "FLY";
178                break;
179            }
180            case Action::PROTECT:
181            {
182                return "PROTECT";
183                break;
184            }
185            case Action::NONE:
186            {
187                return "NONE";
188                break;
189            }
190            case Action::FIGHTALL:
191            {
192                return "FIGHTALL";
193                break;
194            }
195            case Action::ATTACK:
196            {
197                return "ATTACK";
198                break;
199            }
200            default:
201                return "NONE";
202                break;
203        }
204    }
205    void CommonController::setFormationModeXML( std::string val )
206    {
207        const std::string valUpper = getUppercase( val );
208        FormationMode::Value value;
209       
210        if ( valUpper == "WALL" )
211            value = FormationMode::WALL;
212        else if ( valUpper == "FINGER4" )
213            value = FormationMode::FINGER4;
214        else if ( valUpper == "DIAMOND" )
215            value = FormationMode::DIAMOND;
216        else
217            ThrowException( ParseError, std::string( "Attempting to set an unknown FormationMode: '" )+ val + "'." );
218        this->setFormationMode( value );
219       
220    }
221    std::string CommonController::getFormationModeXML() 
222    {
223        switch ( this->formationMode_ )
224        {
225            case FormationMode::WALL:
226            {
227                return "WALL";
228                break;
229            }
230            case FormationMode::FINGER4:
231            {
232                return "FINGER4";
233                break;
234            }
235            case FormationMode::DIAMOND:
236            {
237                return "DIAMOND";
238                break;
239            }
240            default:
241                return "DIAMOND";
242                break;
243
244        }
245    }
246    Action::Value CommonController::getAction ()
247    {
248        return this->action_;
249    }
250    void CommonController::setAction (Action::Value action)
251    {
252        this->action_ = action;
253    }
254
255    void CommonController::setAction (Action::Value action, ControllableEntity* target)
256    {
257        this->action_ = action;
258        if (action == Action::FIGHT)
259        {   
260            if (target)
261                this->setTarget (target);
262        }
263        else if (action == Action::PROTECT)
264        {
265            if (target)
266                this->setProtect (target);
267        }
268    }
269    void CommonController::setAction (Action::Value action, const Vector3& target)
270    {
271        this->action_ = action;
272        if (action == Action::FLY)
273        {
274            this->setTargetPosition (target);
275        }
276       
277    }
278    void CommonController::setAction (Action::Value action, const Vector3& target,  const Quaternion& orient )
279    {
280        this->action_ = action;
281        if (action == Action::FLY)
282        {
283            this->setTargetPosition (target);
284            this->setTargetOrientation (orient);
285        }
286       
287    }
288    void CommonController::addActionpoint(WorldEntity* actionpoint)
289    {
290        std::string actionName;
291        Vector3 position;
292        std::string targetName;
293
294        if (static_cast<Actionpoint*> (actionpoint))
295        {
296            Actionpoint* ap = static_cast<Actionpoint*> (actionpoint);
297           
298            actionName = ap->getActionXML();
299            targetName = ap->getName();
300            position = ap->getWorldPosition();
301
302            Action::Value value;
303           
304            if ( actionName == "FIGHT" )
305            {
306                value = Action::FIGHT;
307
308            }
309            else if ( actionName == "FLY" )
310            {
311                value = Action::FLY;
312
313            }
314            else if ( actionName == "PROTECT" )
315            {
316                value = Action::PROTECT;
317
318            }
319            else if ( actionName == "NONE" )
320            {
321                value = Action::NONE;
322
323            }
324            else if ( actionName == "FIGHTALL" )
325            {
326                value = Action::FIGHTALL;
327
328            }
329            else if ( actionName == "ATTACK" )
330            {
331                value = Action::ATTACK;
332
333
334            }
335            else
336                ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ val + "'." );
337            //this->setAction( value );
338            parsedActionpoints_.push_back( std::make_tuple (value, targetName, position) );
339        }
340        else
341        {
342            parsedActionpoints_.push_back( 
343                std::make_tuple (Action::FLY, "", actionpoint->getWorldPosition()) );
344        }
345            this->actionpoints_.push_back(actionpoint);
346
347       
348    }
349
350    WorldEntity* CommonController::getActionpoint(unsigned int index) const
351    {
352        if (index < this->actionpoints_.size())
353            return this->actionpoints_[index];
354        else
355            return 0;
356    }
357    void CommonController::setClosestTarget()
358    {
359        this->setTarget (closestTarget()); 
360    }
361    ControllableEntity* CommonController::closestTarget()
362    {
363        if (!this->getControllableEntity())
364            return 0;
365
366        Pawn* closestTarget = 0;
367        float minDistance =  std::numeric_limits<float>::infinity();
368        Gametype* gt = this->getGametype();
369        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
370        {
371            if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
372                continue;
373
374            float distance = CommonController::distance (*itP, this->getControllableEntity());
375            if (distance < minDistance)
376            {
377                closestTarget = *itP;
378                minDistance = distance;
379            }
380        }
381        if (closestTarget)
382        {
383           return static_cast<ControllableEntity*>(closestTarget);
384        } 
385        return 0; 
386    }
387    //POST: this starts doing what was asked by the last element of parsedActionpoints_,
388    //if last element was failed to be parsed, next element will be executed.
389    void CommonController::executeActionpoint()
390    {
391        if (!this->parsedActionpoints_.empty())
392        {
393            this->action_ = std::get<0>( this->parsedActionpoints_.back() );
394
395            switch ( this->action_ )
396            {
397                case Action::FIGHT:
398                {               
399                    break;
400                }
401                case Action::FLY:
402                {
403                    this->setTargetPosition(std::get<2>( this->parsedActionpoints_.back() ));
404                    if (this->squaredDistanceToTarget() <= this->squaredaccuracy_)
405                    {
406                        this->nextActionpoint();
407                        this->executeActionpoint();
408                    }
409                    break;
410                }
411                case Action::PROTECT:
412                {
413                    std::string protectName = std::get<1>( this->parsedActionpoints_.back() );
414
415                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
416                    {
417                        if (CommonController::getName(*itP) == protectName)
418                        {
419                            this->setProtect (static_cast<ControllableEntity*>(*itP));
420                        }
421                    }
422                    if (!this->getProtect())
423                    {
424                        this->nextActionpoint();
425                        this->executeActionpoint();
426                    }
427                    break;
428                }
429                case Action::NONE:
430                {
431                    break;
432                }
433                case Action::FIGHTALL:
434                {
435                    break;
436                }
437                case Action::ATTACK:
438                {
439                    std::string targetName = std::get<1>( this->parsedActionpoints_.back() );
440
441                    for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
442                    {
443                        if (CommonController::getName(*itP) == targetName)
444                        {
445                            this->setTarget (static_cast<ControllableEntity*>(*itP));
446                        }
447                    }
448                    if (!this->getTarget())
449                    {
450                        this->nextActionpoint();
451                        this->executeActionpoint();
452                    }
453                    break;
454                }
455                default:
456                    break;
457            }
458           
459
460        }
461        else
462        {
463            this->setTarget(0);
464            this->setTargetPosition(this->getControllableEntity()->getWorldPosition());
465            this->action_ = Action::NONE;
466        }
467    }
468    void CommonController::nextActionpoint()
469    {
470        if (!this->parsedActionpoints_.empty())
471        {
472            this->parsedActionpoints_.pop_back();
473        }
474        this->setAction(Action::NONE);
475    }
476
477    void CommonController::maneuver() 
478    {
479        maneuverCounter_++;
480
481        if (maneuverCounter_ > 5)
482            maneuverCounter_ = 0;
483        if ( this->target_ && this->getControllableEntity())
484        {
485            Vector3 thisPosition = this->getControllableEntity()->getWorldPosition();
486            //Quaternion thisOrientation = this->getControllableEntity()->getOrientation();
487
488            this->setPositionOfTarget( getPredictedPosition( 
489                thisPosition, 
490                hardcoded_projectile_speed, 
491                this->target_->getWorldPosition() , 
492                this->target_->getVelocity() 
493                )  );
494            this->setOrientationOfTarget( this->target_->getOrientation() );
495
496
497            Vector3 diffVector = this->positionOfTarget_ - thisPosition;
498            float diffLength = diffVector.length();
499            Vector3 diffUnit = diffVector/diffLength;
500
501
502
503            //bool bThisIsLookingAtTarget = this->isLooking ( getControllableEntity(), this->target_, math::pi/4 );
504            bool bTargetIsLookingAtThis = this->isLooking ( this->target_, getControllableEntity(), math::pi/10.0f );
505           
506
507
508            //too far? well, come closer then
509            if ( diffLength > 3000 )
510            {
511                if (diffLength < 6000)
512                {
513
514                }
515                else
516                {
517                }
518                this->setTargetPosition( this->positionOfTarget_ );
519            }
520            //too close? How do u expect to dodge anything? Just attack!
521            else if ( diffLength < 500 )
522            {   
523                //at this point, just look and shoot
524                if ( diffLength < 250 )
525                {
526                    this->stopMoving();
527                    this->startLookingAtTarget();
528                }
529                else
530                {
531                    this->setTargetPosition( this->positionOfTarget_ );
532                }
533            }
534            //Good distance? Check if target looks at us. It doesn't? Go hunt!
535            else if ( !bTargetIsLookingAtThis )
536            {
537                this->setTargetPosition( this->positionOfTarget_ );
538              /*  if (maneuverCounter_ == 0)
539                {
540                    this->setTargetPosition( this->positionOfTarget_ );   
541                    return;
542                }
543                else
544                {
545                    dodge( thisPosition, diffUnit );
546                }*/
547            }
548            //That's unfortunate, he is looking and probably shooting... try to dodge what we can... 
549            else 
550            {   
551           
552                if (maneuverCounter_ == 0)
553                {
554                    this->setTargetPosition( this->positionOfTarget_ );   
555                    return;
556                }
557                dodge( thisPosition, diffUnit );
558               
559            }
560        }
561       
562        //orxout ( internal_error ) << "ManeuverType = " << this->maneuverType_ << endl;
563    }
564    ControllableEntity* CommonController::getTarget()
565    {
566        return this->target_;
567    }
568    void CommonController::dodge(Vector3& thisPosition, Vector3& diffUnit)
569    {
570        float factorX = 0, factorY = 0, factorZ = 0;
571        float rand = randomInRange (0, 1);
572        if (rand <= 0.5)
573        {
574            factorX = 1;
575        }
576        else
577        {
578            factorX = -1;
579        }
580        rand = randomInRange (0, 1);
581        if (rand <= 0.5)
582        {
583            factorY = 1;
584        }
585        else
586        {
587            factorY = -1;
588        }
589        rand = randomInRange (0, 1);
590        if (rand <= 0.5)
591        {
592            factorZ = 1;
593        }
594        else
595        {
596            factorZ = -1;
597        }
598        Vector3 target = ( diffUnit )* 8000.0f;
599        Vector3* randVector = new Vector3( 
600            factorX * randomInRange( 10000, 40000 ), 
601            factorY * randomInRange( 10000, 40000 ), 
602            factorZ * randomInRange( 10000, 40000 ) 
603        );
604        Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit;
605        *randVector -= projection;
606        target += *randVector;
607        this->setTargetPosition( thisPosition + target );
608    }
609    void CommonController::stopMoving()
610    {
611        this->bHasTargetPosition_ = false;
612    }
613    void CommonController::startLookingAtTarget()
614    {
615        this->bLookAtTarget_ = true;
616    }
617    void CommonController::stopLookingAtTarget()
618    {
619        this->bLookAtTarget_ = false;
620    }
621    void CommonController::lookAtTarget(float dt)
622    {
623
624       
625        ControllableEntity* entity = this->getControllableEntity();
626        if ( !entity )
627            return;
628        Vector2 coord = get2DViewCoordinates
629            ( entity->getPosition() , 
630            entity->getOrientation()  * WorldEntity::FRONT, 
631            entity->getOrientation()  * WorldEntity::UP, 
632            positionOfTarget_ );
633
634        //rotates should be in range [-1,+1], clamp cuts off all that is not
635        float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );
636        float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
637
638       
639   
640        //Yaw and Pitch are enough to start facing the target
641        this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );
642        this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );
643       
644           
645    }
646   
647    bool CommonController::setWingman ( CommonController* wingman )
648    {
649        return false;
650    }
651   
652    bool CommonController::hasWingman() 
653    {
654        return true;
655    }
656    void CommonController::setTarget( ControllableEntity* target )
657    {
658        this->target_ = target;
659        //orxout ( internal_error ) << " TARGET SET " << endl;
660       
661        if ( this->target_ )
662        {
663            this->setPositionOfTarget( target_->getWorldPosition() );
664
665        }
666    }
667    bool CommonController::hasTarget() 
668    {
669        if ( this->target_ )
670            return true;
671        return false;
672    }
673    void CommonController::setPositionOfTarget( const Vector3& target )
674    {
675        this->positionOfTarget_ = target;
676        this->bHasPositionOfTarget_ = true;
677    }
678    void CommonController::setOrientationOfTarget( const Quaternion& orient )
679    {
680        this->orientationOfTarget_=orient;
681        this->bHasOrientationOfTarget_=true;
682    }
683
684    void CommonController::setTargetPosition( const Vector3& target )
685    {
686        this->targetPosition_ = target;
687        this->bHasTargetPosition_ = true;
688    }
689
690    void CommonController::setTargetOrientation( const Quaternion& orient )
691    {
692        this->targetOrientation_=orient;
693        this->bHasTargetOrientation_=true;
694    }
695
696    void CommonController::setTargetOrientation( ControllableEntity* target )
697    {
698        if ( target )
699            setTargetOrientation( target->getOrientation() );
700    }
701
702
703
704    //copy the Roll orientation of given Quaternion.
705    void CommonController::copyOrientation( const Quaternion& orient, float dt )
706    {
707        //roll angle difference in radian
708        float diff=orient.getRoll( false ).valueRadians() -( this->getControllableEntity() ->getOrientation() .getRoll( false ).valueRadians() );
709        while( diff>math::twoPi )diff-=math::twoPi;
710        while( diff<-math::twoPi )diff+=math::twoPi;
711        this->getControllableEntity() ->rotateRoll( diff*ROTATEFACTOR * dt );
712    }
713    void CommonController::copyTargetOrientation( float dt )
714    {
715        if ( bHasTargetOrientation_ )
716        {   
717            copyOrientation( targetOrientation_, dt );
718        }
719    }
720
721
722
723
724    void CommonController::moveToTargetPosition( float dt )
725    {
726        this->moveToPosition( this->targetPosition_, dt );
727    }
728    void CommonController::moveToPosition( const Vector3& target, float dt )
729    {
730     
731       
732        //100 is ( so far )the smallest tolerance ( empirically found )that can be reached,
733        //with smaller distance spaceships can't reach position and go circles around it instead
734        int tolerance = 65;
735
736        ControllableEntity* entity = this->getControllableEntity();
737        Vector2 coord = get2DViewCoordinates
738            ( entity->getPosition() , 
739            entity->getOrientation()  * WorldEntity::FRONT, 
740            entity->getOrientation()  * WorldEntity::UP, 
741            target );
742
743        float distance = ( target - this->getControllableEntity() ->getPosition() ).length();
744
745        //rotates should be in range [-1,+1], clamp cuts off all that is not
746        float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );
747        float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
748
749       
750        if ( distance > tolerance )
751        {
752            //Yaw and Pitch are enough to start facing the target
753            this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );
754            this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );
755
756            //300 works, maybe less is better
757            if ( distance < 400 )
758            {
759                //Change roll when close. When Spaceship faces target, roll doesn't affect it's trajectory
760                //It's important that roll is not changed in the process of changing yaw and pitch
761                //Wingmen won't face same direction as Leaders, but when Leaders start moving
762                //Yaw and Pitch will adapt.
763                if ( bHasTargetOrientation_ )
764                {
765                    copyTargetOrientation( dt );
766                }
767            }
768
769            this->getControllableEntity() ->moveFrontBack( SPEED * dt );
770        }
771        else
772        {     
773            bHasTargetPosition_ = false;
774            bHasTargetOrientation_ = false;
775        }
776    }
777    float CommonController::randomInRange( float a, float b )
778    {
779        float random = rnd( 1.0f );
780        float diff = b - a;
781        float r = random * diff;
782        return a + r;
783    }
784   
785
786    //to be called in action
787    //PRE: relativeTargetPosition is desired position relative to the spaceship,
788    //angleRoll is the angle in degrees of Roll that should be applied by the end of the movement
789    //POST: target orientation and position are set, so that it can be used by MoveAndRoll()
790    void CommonController::moveToPoint( const Vector3& relativeTargetPosition, float angleRoll )
791    {
792        ControllableEntity* entity = this->getControllableEntity();
793        if ( !entity )
794            return;
795        Quaternion orient = entity->getWorldOrientation();
796        Quaternion rotation = Quaternion( Degree( angleRoll ), Vector3::UNIT_Z );
797
798        Vector3 target = orient * relativeTargetPosition + entity->getWorldPosition();
799        setTargetPosition( target );
800        orient = orient * rotation;
801        this->setTargetOrientation( orient );
802       
803    }
804    //to be called in tick
805    //PRE: MoveToPoint was called
806    //POST: spaceship changes its yaw and pitch to point towards targetPosition_,
807    //moves towards targetPosition_ by amount depending on dt and its speed,
808    //rolls by amount depending on the difference between angleRoll_ and angleRolled_, dt, and
809    //angular speed
810    //if position reached with a certain tolerance, and angleRolled_ = angleRoll_, returns false,
811    //otherwise returns true
812    //dt is normally around 0.02f, which makes it 1/0.02 = 50 frames/sec
813    bool CommonController::moveAndRoll( float dt )
814    {
815        float factor = 1;
816        if ( !this->getControllableEntity() )
817            return false;
818        if ( this->rank_ == Rank::DIVISIONLEADER )
819            factor = 0.8;
820        if ( this->rank_ == Rank::SECTIONLEADER )
821            factor = 0.9;
822        int tolerance = 60;
823       
824        ControllableEntity* entity = this->getControllableEntity();
825        if ( !entity )
826            return true;
827        Vector2 coord = get2DViewCoordinates
828            ( entity->getPosition() , 
829            entity->getOrientation()  * WorldEntity::FRONT, 
830            entity->getOrientation()  * WorldEntity::UP, 
831            targetPosition_ );
832
833        float distance = ( targetPosition_ - this->getControllableEntity() ->getPosition() ).length();
834
835        //rotates should be in range [-1,+1], clamp cuts off all that is not
836        float rotateX = clamp( coord.x * 10, -1.0f, 1.0f );
837        float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
838
839       
840        if ( distance > tolerance )
841        {
842            //Yaw and Pitch are enough to start facing the target
843            this->getControllableEntity() ->rotateYaw( -2.0f * ROTATEFACTOR * rotateX * dt );
844            this->getControllableEntity() ->rotatePitch( 2.0f * ROTATEFACTOR * rotateY * dt );
845           
846            //Roll
847            if ( bHasTargetOrientation_ )
848            {
849                copyTargetOrientation( dt );
850            }
851         
852            //Move
853            this->getControllableEntity() ->moveFrontBack( 1.2f * SPEED * factor * dt );
854            //if still moving, return false
855            return false;
856        }
857        else
858        {     
859           
860            //if finished, return true;
861            return true;
862        }
863    }
864
865    float CommonController::squaredDistanceToTarget()  const
866    {
867        if ( !this->getControllableEntity()  )
868            return 0;
869        if ( !this->target_ || !this->getControllableEntity() )
870            return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->targetPosition_ ) );
871        else
872            return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->positionOfTarget_ ) );
873    }
874   
875    bool CommonController::isLookingAtTarget( float angle )const
876    {
877        if ( !this->getControllableEntity()  || !this->target_ )
878            return false;
879
880        return ( getAngle( this->getControllableEntity() ->getPosition() , 
881            this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT, this->positionOfTarget_ ) < angle );
882    }
883    bool CommonController::isLooking( ControllableEntity* entityThatLooks, ControllableEntity* entityBeingLookedAt, float angle )
884    {
885        if ( !entityThatLooks || !entityBeingLookedAt )
886            return false;
887        return ( getAngle( entityThatLooks ->getPosition() , 
888            entityThatLooks->getOrientation()  * WorldEntity::FRONT, 
889            entityBeingLookedAt->getWorldPosition() ) < angle );
890    }
891
892    bool CommonController::canFire() 
893    {
894
895        //no target? why fire?
896        if ( !this->target_ )
897            return false;
898
899        Vector3 newPositionOfTarget = getPredictedPosition( this->getControllableEntity() ->getWorldPosition() , 
900            hardcoded_projectile_speed, this->target_->getWorldPosition() , this->target_->getVelocity() );
901        if ( newPositionOfTarget != Vector3::ZERO )
902        {
903            this->setPositionOfTarget( newPositionOfTarget );
904        }
905
906        float squaredDistance = squaredDistanceToTarget();
907
908        if ( squaredDistance < 9000000.0f && this->isLookingAtTarget( math::pi / 20.0f)) {
909            return true;
910        }
911        else
912        {
913            return false;
914        }
915
916    }
917    float CommonController::distance (ControllableEntity* entity1, ControllableEntity* entity2)
918    {
919        if (!entity1 || !entity2)
920            return std::numeric_limits<float>::infinity();
921        return ( entity1->getPosition() - entity2->getPosition() ).length();
922    }
923    bool CommonController::sameTeam (ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
924    {
925        /*if (!entity1 || !entity2)
926            return false;
927        return entity1->getTeam() == entity2->getTeam();*/
928        if (entity1 == entity2)
929            return true;
930
931        int team1 = entity1->getTeam();
932        int team2 = entity2->getTeam();
933
934        Controller* controller = 0;
935        if (entity1->getController())
936            controller = entity1->getController();
937        else
938            controller = entity1->getXMLController();
939        if (controller)
940        {
941            CommonController* ac = orxonox_cast<CommonController*>(controller);
942            if (ac)
943                team1 = ac->getTeam();
944        }
945
946        if (entity2->getController())
947            controller = entity2->getController();
948        else
949            controller = entity2->getXMLController();
950        if (controller)
951        {
952            CommonController* ac = orxonox_cast<CommonController*>(controller);
953            if (ac)
954                team2 = ac->getTeam();
955        }
956
957        TeamGametype* tdm = orxonox_cast<TeamGametype*>(gametype);
958        if (tdm)
959        {
960            if (entity1->getPlayer())
961                team1 = tdm->getTeam(entity1->getPlayer());
962
963            if (entity2->getPlayer())
964                team2 = tdm->getTeam(entity2->getPlayer());
965        }
966
967        TeamBaseMatchBase* base = 0;
968        base = orxonox_cast<TeamBaseMatchBase*>(entity1);
969        if (base)
970        {
971            switch (base->getState())
972            {
973                case BaseState::ControlTeam1:
974                    team1 = 0;
975                    break;
976                case BaseState::ControlTeam2:
977                    team1 = 1;
978                    break;
979                case BaseState::Uncontrolled:
980                default:
981                    team1 = -1;
982            }
983        }
984        base = orxonox_cast<TeamBaseMatchBase*>(entity2);
985        if (base)
986        {
987            switch (base->getState())
988            {
989                case BaseState::ControlTeam1:
990                    team2 = 0;
991                    break;
992                case BaseState::ControlTeam2:
993                    team2 = 1;
994                    break;
995                case BaseState::Uncontrolled:
996                default:
997                    team2 = -1;
998            }
999        }
1000
1001        DroneController* droneController = 0;
1002        droneController = orxonox_cast<DroneController*>(entity1->getController());
1003        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)
1004            return true;
1005        droneController = orxonox_cast<DroneController*>(entity2->getController());
1006        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)
1007            return true;
1008        DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController());
1009        DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController());
1010        if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner())
1011            return true;
1012
1013        Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype);
1014        if (dynamic)
1015        {
1016            if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;}
1017
1018            if (entity1->getPlayer())
1019                team1 = dynamic->getParty(entity1->getPlayer());
1020
1021            if (entity2->getPlayer())
1022                team2 = dynamic->getParty(entity2->getPlayer());
1023
1024            if (team1 ==-1 ||team2 ==-1 ) {return false;}
1025            else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;}
1026            else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;}
1027            else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;}
1028            else return true;
1029        }
1030
1031        return (team1 == team2 && team1 != -1);
1032    }
1033    void CommonController::doFire() 
1034    {
1035        if ( !this->target_ || !this->getControllableEntity() )
1036        {
1037            return;
1038        }
1039     
1040        Pawn* pawn = orxonox_cast<Pawn*>( this->getControllableEntity() );
1041
1042        if ( pawn )
1043            //pawn->setAimPosition( this->getControllableEntity() ->getWorldPosition()  + 4000*( this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT ));
1044            pawn->setAimPosition( this->positionOfTarget_ );
1045   
1046        this->getControllableEntity() ->fire( 0 );
1047    }
1048   
1049
1050}
Note: See TracBrowser for help on using the repository browser.