Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

I hope that you don't code today, that version is not compilable just yet

File size: 30.5 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(ControllableEntity* 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        this->actionpoints_.push_back(actionpoint);
294        if (static_cast<Actionpoint*> (actionpoint))
295        {
296            Actionpoint* ap = static_cast<Actionpoint*> (actionpoint);
297            actionName = ap->getActionXML();
298            targetName = ap->get
299            Action::Value value;
300           
301            if ( valUpper == "FIGHT" )
302            {
303                value = Action::FIGHT;
304
305            }
306            else if ( valUpper == "FLY" )
307            {
308                value = Action::FLY;
309
310            }
311            else if ( valUpper == "PROTECT" )
312            {
313                value = Action::PROTECT;
314
315            }
316            else if ( valUpper == "NONE" )
317            {
318                value = Action::NONE;
319
320            }
321            else if ( valUpper == "FIGHTALL" )
322            {
323                value = Action::FIGHTALL;
324
325            }
326            else if ( valUpper == "ATTACK" )
327            {
328                value = Action::ATTACK;
329
330            }
331            else
332                ThrowException( ParseError, std::string( "Attempting to set an unknown Action: '" )+ val + "'." );
333            this->setAction( value );
334        }
335        else
336        {
337            actionName = "FLY";
338        }
339       
340    }
341
342    WorldEntity* CommonController::getActionpoint(unsigned int index) const
343    {
344        if (index < this->actionpoints_.size())
345            return this->actionpoints_[index];
346        else
347            return 0;
348    }
349    void CommonController::setClosestTarget()
350    {
351        this->setTarget (closestTarget()); 
352    }
353    ControllableEntity* CommonController::closestTarget()
354    {
355        if (!this->getControllableEntity())
356            return 0;
357
358        Pawn* closestTarget = 0;
359        float minDistance =  std::numeric_limits<float>::infinity();
360        Gametype* gt = this->getGametype();
361        for (ObjectList<Pawn>::iterator itP = ObjectList<Pawn>::begin(); itP; ++itP)
362        {
363            if ( CommonController::sameTeam (this->getControllableEntity(), static_cast<ControllableEntity*>(*itP), gt) )
364                continue;
365
366            float distance = CommonController::distance (*itP, this->getControllableEntity());
367            if (distance < minDistance)
368            {
369                closestTarget = *itP;
370                minDistance = distance;
371            }
372        }
373        if (closestTarget)
374        {
375           return static_cast<ControllableEntity*>(closestTarget);
376        } 
377        return 0; 
378    }
379    void CommonController::maneuver() 
380    {
381        maneuverCounter_++;
382
383        if (maneuverCounter_ > 5)
384            maneuverCounter_ = 0;
385        if ( this->target_ && this->getControllableEntity())
386        {
387            Vector3 thisPosition = this->getControllableEntity()->getWorldPosition();
388            //Quaternion thisOrientation = this->getControllableEntity()->getOrientation();
389
390            this->setPositionOfTarget( getPredictedPosition( 
391                thisPosition, 
392                hardcoded_projectile_speed, 
393                this->target_->getWorldPosition() , 
394                this->target_->getVelocity() 
395                )  );
396            this->setOrientationOfTarget( this->target_->getOrientation() );
397
398
399            Vector3 diffVector = this->positionOfTarget_ - thisPosition;
400            float diffLength = diffVector.length();
401            Vector3 diffUnit = diffVector/diffLength;
402
403
404
405            //bool bThisIsLookingAtTarget = this->isLooking ( getControllableEntity(), this->target_, math::pi/4 );
406            bool bTargetIsLookingAtThis = this->isLooking ( this->target_, getControllableEntity(), math::pi/10.0f );
407           
408
409
410            //too far? well, come closer then
411            if ( diffLength > 3000 )
412            {
413                if (diffLength < 6000)
414                {
415
416                }
417                else
418                {
419                }
420                this->setTargetPosition( this->positionOfTarget_ );
421            }
422            //too close? How do u expect to dodge anything? Just attack!
423            else if ( diffLength < 500 )
424            {   
425                //at this point, just look and shoot
426                if ( diffLength < 250 )
427                {
428                    this->stopMoving();
429                    this->startLookingAtTarget();
430                }
431                else
432                {
433                    this->setTargetPosition( this->positionOfTarget_ );
434                }
435            }
436            //Good distance? Check if target looks at us. It doesn't? Go hunt!
437            else if ( !bTargetIsLookingAtThis )
438            {
439                this->setTargetPosition( this->positionOfTarget_ );
440              /*  if (maneuverCounter_ == 0)
441                {
442                    this->setTargetPosition( this->positionOfTarget_ );   
443                    return;
444                }
445                else
446                {
447                    dodge( thisPosition, diffUnit );
448                }*/
449            }
450            //That's unfortunate, he is looking and probably shooting... try to dodge what we can... 
451            else 
452            {   
453           
454                if (maneuverCounter_ == 0)
455                {
456                    this->setTargetPosition( this->positionOfTarget_ );   
457                    return;
458                }
459                dodge( thisPosition, diffUnit );
460               
461            }
462        }
463       
464        //orxout ( internal_error ) << "ManeuverType = " << this->maneuverType_ << endl;
465    }
466    ControllableEntity* CommonController::getTarget()
467    {
468        return this->target_;
469    }
470    void CommonController::dodge(Vector3& thisPosition, Vector3& diffUnit)
471    {
472        float factorX = 0, factorY = 0, factorZ = 0;
473        float rand = randomInRange (0, 1);
474        if (rand <= 0.5)
475        {
476            factorX = 1;
477        }
478        else
479        {
480            factorX = -1;
481        }
482        rand = randomInRange (0, 1);
483        if (rand <= 0.5)
484        {
485            factorY = 1;
486        }
487        else
488        {
489            factorY = -1;
490        }
491        rand = randomInRange (0, 1);
492        if (rand <= 0.5)
493        {
494            factorZ = 1;
495        }
496        else
497        {
498            factorZ = -1;
499        }
500        Vector3 target = ( diffUnit )* 8000.0f;
501        Vector3* randVector = new Vector3( 
502            factorX * randomInRange( 10000, 40000 ), 
503            factorY * randomInRange( 10000, 40000 ), 
504            factorZ * randomInRange( 10000, 40000 ) 
505        );
506        Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit;
507        *randVector -= projection;
508        target += *randVector;
509        this->setTargetPosition( thisPosition + target );
510    }
511    void CommonController::stopMoving()
512    {
513        this->bHasTargetPosition_ = false;
514    }
515    void CommonController::startLookingAtTarget()
516    {
517        this->bLookAtTarget_ = true;
518    }
519    void CommonController::stopLookingAtTarget()
520    {
521        this->bLookAtTarget_ = false;
522    }
523    void CommonController::lookAtTarget(float dt)
524    {
525
526       
527        ControllableEntity* entity = this->getControllableEntity();
528        if ( !entity )
529            return;
530        Vector2 coord = get2DViewCoordinates
531            ( entity->getPosition() , 
532            entity->getOrientation()  * WorldEntity::FRONT, 
533            entity->getOrientation()  * WorldEntity::UP, 
534            positionOfTarget_ );
535
536        //rotates should be in range [-1,+1], clamp cuts off all that is not
537        float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );
538        float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
539
540       
541   
542        //Yaw and Pitch are enough to start facing the target
543        this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );
544        this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );
545       
546           
547    }
548   
549    bool CommonController::setWingman ( CommonController* wingman )
550    {
551        return false;
552    }
553   
554    bool CommonController::hasWingman() 
555    {
556        return true;
557    }
558    void CommonController::setTarget( ControllableEntity* target )
559    {
560        this->target_ = target;
561        //orxout ( internal_error ) << " TARGET SET " << endl;
562       
563        if ( this->target_ )
564        {
565            this->setPositionOfTarget( target_->getWorldPosition() );
566
567        }
568    }
569    bool CommonController::hasTarget() 
570    {
571        if ( this->target_ )
572            return true;
573        return false;
574    }
575    void CommonController::setPositionOfTarget( const Vector3& target )
576    {
577        this->positionOfTarget_ = target;
578        this->bHasPositionOfTarget_ = true;
579    }
580    void CommonController::setOrientationOfTarget( const Quaternion& orient )
581    {
582        this->orientationOfTarget_=orient;
583        this->bHasOrientationOfTarget_=true;
584    }
585
586    void CommonController::setTargetPosition( const Vector3& target )
587    {
588        this->targetPosition_ = target;
589        this->bHasTargetPosition_ = true;
590    }
591
592    void CommonController::setTargetOrientation( const Quaternion& orient )
593    {
594        this->targetOrientation_=orient;
595        this->bHasTargetOrientation_=true;
596    }
597
598    void CommonController::setTargetOrientation( ControllableEntity* target )
599    {
600        if ( target )
601            setTargetOrientation( target->getOrientation() );
602    }
603
604
605
606    //copy the Roll orientation of given Quaternion.
607    void CommonController::copyOrientation( const Quaternion& orient, float dt )
608    {
609        //roll angle difference in radian
610        float diff=orient.getRoll( false ).valueRadians() -( this->getControllableEntity() ->getOrientation() .getRoll( false ).valueRadians() );
611        while( diff>math::twoPi )diff-=math::twoPi;
612        while( diff<-math::twoPi )diff+=math::twoPi;
613        this->getControllableEntity() ->rotateRoll( diff*ROTATEFACTOR * dt );
614    }
615    void CommonController::copyTargetOrientation( float dt )
616    {
617        if ( bHasTargetOrientation_ )
618        {   
619            copyOrientation( targetOrientation_, dt );
620        }
621    }
622
623
624
625
626    void CommonController::moveToTargetPosition( float dt )
627    {
628        this->moveToPosition( this->targetPosition_, dt );
629    }
630    void CommonController::moveToPosition( const Vector3& target, float dt )
631    {
632     
633       
634        //100 is ( so far )the smallest tolerance ( empirically found )that can be reached,
635        //with smaller distance spaceships can't reach position and go circles around it instead
636        int tolerance = 65;
637
638        ControllableEntity* entity = this->getControllableEntity();
639        Vector2 coord = get2DViewCoordinates
640            ( entity->getPosition() , 
641            entity->getOrientation()  * WorldEntity::FRONT, 
642            entity->getOrientation()  * WorldEntity::UP, 
643            target );
644
645        float distance = ( target - this->getControllableEntity() ->getPosition() ).length();
646
647        //rotates should be in range [-1,+1], clamp cuts off all that is not
648        float rotateX = -clamp( coord.x * 10, -1.0f, 1.0f );
649        float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
650
651       
652        if ( distance > tolerance )
653        {
654            //Yaw and Pitch are enough to start facing the target
655            this->getControllableEntity() ->rotateYaw( ROTATEFACTOR * rotateX * dt );
656            this->getControllableEntity() ->rotatePitch( ROTATEFACTOR * rotateY * dt );
657
658            //300 works, maybe less is better
659            if ( distance < 400 )
660            {
661                //Change roll when close. When Spaceship faces target, roll doesn't affect it's trajectory
662                //It's important that roll is not changed in the process of changing yaw and pitch
663                //Wingmen won't face same direction as Leaders, but when Leaders start moving
664                //Yaw and Pitch will adapt.
665                if ( bHasTargetOrientation_ )
666                {
667                    copyTargetOrientation( dt );
668                }
669            }
670
671            this->getControllableEntity() ->moveFrontBack( SPEED * dt );
672        }
673        else
674        {     
675            bHasTargetPosition_ = false;
676            bHasTargetOrientation_ = false;
677        }
678    }
679    float CommonController::randomInRange( float a, float b )
680    {
681        float random = rnd( 1.0f );
682        float diff = b - a;
683        float r = random * diff;
684        return a + r;
685    }
686   
687
688    //to be called in action
689    //PRE: relativeTargetPosition is desired position relative to the spaceship,
690    //angleRoll is the angle in degrees of Roll that should be applied by the end of the movement
691    //POST: target orientation and position are set, so that it can be used by MoveAndRoll()
692    void CommonController::moveToPoint( const Vector3& relativeTargetPosition, float angleRoll )
693    {
694        ControllableEntity* entity = this->getControllableEntity();
695        if ( !entity )
696            return;
697        Quaternion orient = entity->getWorldOrientation();
698        Quaternion rotation = Quaternion( Degree( angleRoll ), Vector3::UNIT_Z );
699
700        Vector3 target = orient * relativeTargetPosition + entity->getWorldPosition();
701        setTargetPosition( target );
702        orient = orient * rotation;
703        this->setTargetOrientation( orient );
704       
705    }
706    //to be called in tick
707    //PRE: MoveToPoint was called
708    //POST: spaceship changes its yaw and pitch to point towards targetPosition_,
709    //moves towards targetPosition_ by amount depending on dt and its speed,
710    //rolls by amount depending on the difference between angleRoll_ and angleRolled_, dt, and
711    //angular speed
712    //if position reached with a certain tolerance, and angleRolled_ = angleRoll_, returns false,
713    //otherwise returns true
714    //dt is normally around 0.02f, which makes it 1/0.02 = 50 frames/sec
715    bool CommonController::moveAndRoll( float dt )
716    {
717        float factor = 1;
718        if ( !this->getControllableEntity() )
719            return false;
720        if ( this->rank_ == Rank::DIVISIONLEADER )
721            factor = 0.8;
722        if ( this->rank_ == Rank::SECTIONLEADER )
723            factor = 0.9;
724        int tolerance = 60;
725       
726        ControllableEntity* entity = this->getControllableEntity();
727        if ( !entity )
728            return true;
729        Vector2 coord = get2DViewCoordinates
730            ( entity->getPosition() , 
731            entity->getOrientation()  * WorldEntity::FRONT, 
732            entity->getOrientation()  * WorldEntity::UP, 
733            targetPosition_ );
734
735        float distance = ( targetPosition_ - this->getControllableEntity() ->getPosition() ).length();
736
737        //rotates should be in range [-1,+1], clamp cuts off all that is not
738        float rotateX = clamp( coord.x * 10, -1.0f, 1.0f );
739        float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
740
741       
742        if ( distance > tolerance )
743        {
744            //Yaw and Pitch are enough to start facing the target
745            this->getControllableEntity() ->rotateYaw( -2.0f * ROTATEFACTOR * rotateX * dt );
746            this->getControllableEntity() ->rotatePitch( 2.0f * ROTATEFACTOR * rotateY * dt );
747           
748            //Roll
749            if ( bHasTargetOrientation_ )
750            {
751                copyTargetOrientation( dt );
752            }
753         
754            //Move
755            this->getControllableEntity() ->moveFrontBack( 1.2f * SPEED * factor * dt );
756            //if still moving, return false
757            return false;
758        }
759        else
760        {     
761           
762            //if finished, return true;
763            return true;
764        }
765    }
766
767    float CommonController::squaredDistanceToTarget()  const
768    {
769        if ( !this->getControllableEntity()  )
770            return 0;
771        if ( !this->target_ || !this->getControllableEntity() )
772            return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->targetPosition_ ) );
773        else
774            return ( this->getControllableEntity() ->getPosition() .squaredDistance( this->positionOfTarget_ ) );
775    }
776   
777    bool CommonController::isLookingAtTarget( float angle )const
778    {
779        if ( !this->getControllableEntity()  || !this->target_ )
780            return false;
781
782        return ( getAngle( this->getControllableEntity() ->getPosition() , 
783            this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT, this->positionOfTarget_ ) < angle );
784    }
785    bool CommonController::isLooking( ControllableEntity* entityThatLooks, ControllableEntity* entityBeingLookedAt, float angle )
786    {
787        if ( !entityThatLooks || !entityBeingLookedAt )
788            return false;
789        return ( getAngle( entityThatLooks ->getPosition() , 
790            entityThatLooks->getOrientation()  * WorldEntity::FRONT, 
791            entityBeingLookedAt->getWorldPosition() ) < angle );
792    }
793
794    bool CommonController::canFire() 
795    {
796
797        //no target? why fire?
798        if ( !this->target_ )
799            return false;
800
801        Vector3 newPositionOfTarget = getPredictedPosition( this->getControllableEntity() ->getWorldPosition() , 
802            hardcoded_projectile_speed, this->target_->getWorldPosition() , this->target_->getVelocity() );
803        if ( newPositionOfTarget != Vector3::ZERO )
804        {
805            this->setPositionOfTarget( newPositionOfTarget );
806        }
807
808        float squaredDistance = squaredDistanceToTarget();
809
810        if ( squaredDistance < 9000000.0f && this->isLookingAtTarget( math::pi / 20.0f)) {
811            return true;
812        }
813        else
814        {
815            return false;
816        }
817
818    }
819    float CommonController::distance (ControllableEntity* entity1, ControllableEntity* entity2)
820    {
821        if (!entity1 || !entity2)
822            return std::numeric_limits<float>::infinity();
823        return ( entity1->getPosition() - entity2->getPosition() ).length();
824    }
825    bool CommonController::sameTeam (ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
826    {
827        /*if (!entity1 || !entity2)
828            return false;
829        return entity1->getTeam() == entity2->getTeam();*/
830        if (entity1 == entity2)
831            return true;
832
833        int team1 = entity1->getTeam();
834        int team2 = entity2->getTeam();
835
836        Controller* controller = 0;
837        if (entity1->getController())
838            controller = entity1->getController();
839        else
840            controller = entity1->getXMLController();
841        if (controller)
842        {
843            CommonController* ac = orxonox_cast<CommonController*>(controller);
844            if (ac)
845                team1 = ac->getTeam();
846        }
847
848        if (entity2->getController())
849            controller = entity2->getController();
850        else
851            controller = entity2->getXMLController();
852        if (controller)
853        {
854            CommonController* ac = orxonox_cast<CommonController*>(controller);
855            if (ac)
856                team2 = ac->getTeam();
857        }
858
859        TeamGametype* tdm = orxonox_cast<TeamGametype*>(gametype);
860        if (tdm)
861        {
862            if (entity1->getPlayer())
863                team1 = tdm->getTeam(entity1->getPlayer());
864
865            if (entity2->getPlayer())
866                team2 = tdm->getTeam(entity2->getPlayer());
867        }
868
869        TeamBaseMatchBase* base = 0;
870        base = orxonox_cast<TeamBaseMatchBase*>(entity1);
871        if (base)
872        {
873            switch (base->getState())
874            {
875                case BaseState::ControlTeam1:
876                    team1 = 0;
877                    break;
878                case BaseState::ControlTeam2:
879                    team1 = 1;
880                    break;
881                case BaseState::Uncontrolled:
882                default:
883                    team1 = -1;
884            }
885        }
886        base = orxonox_cast<TeamBaseMatchBase*>(entity2);
887        if (base)
888        {
889            switch (base->getState())
890            {
891                case BaseState::ControlTeam1:
892                    team2 = 0;
893                    break;
894                case BaseState::ControlTeam2:
895                    team2 = 1;
896                    break;
897                case BaseState::Uncontrolled:
898                default:
899                    team2 = -1;
900            }
901        }
902
903        DroneController* droneController = 0;
904        droneController = orxonox_cast<DroneController*>(entity1->getController());
905        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity2)
906            return true;
907        droneController = orxonox_cast<DroneController*>(entity2->getController());
908        if (droneController && static_cast<ControllableEntity*>(droneController->getOwner()) == entity1)
909            return true;
910        DroneController* droneController1 = orxonox_cast<DroneController*>(entity1->getController());
911        DroneController* droneController2 = orxonox_cast<DroneController*>(entity2->getController());
912        if (droneController1 && droneController2 && droneController1->getOwner() == droneController2->getOwner())
913            return true;
914
915        Dynamicmatch* dynamic = orxonox_cast<Dynamicmatch*>(gametype);
916        if (dynamic)
917        {
918            if (dynamic->notEnoughPigs||dynamic->notEnoughKillers||dynamic->notEnoughChasers) {return false;}
919
920            if (entity1->getPlayer())
921                team1 = dynamic->getParty(entity1->getPlayer());
922
923            if (entity2->getPlayer())
924                team2 = dynamic->getParty(entity2->getPlayer());
925
926            if (team1 ==-1 ||team2 ==-1 ) {return false;}
927            else if (team1 == dynamic->chaser && team2 != dynamic->chaser) {return false;}
928            else if (team1 == dynamic->piggy && team2 == dynamic->chaser) {return false;}
929            else if (team1 == dynamic->killer && team2 == dynamic->chaser) {return false;}
930            else return true;
931        }
932
933        return (team1 == team2 && team1 != -1);
934    }
935    void CommonController::doFire() 
936    {
937        if ( !this->target_ || !this->getControllableEntity() )
938        {
939            return;
940        }
941     
942        Pawn* pawn = orxonox_cast<Pawn*>( this->getControllableEntity() );
943
944        if ( pawn )
945            //pawn->setAimPosition( this->getControllableEntity() ->getWorldPosition()  + 4000*( this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT ));
946            pawn->setAimPosition( this->positionOfTarget_ );
947   
948        this->getControllableEntity() ->fire( 0 );
949    }
950   
951
952}
Note: See TracBrowser for help on using the repository browser.