Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

ok, now you can use attack and protect just like in my level, but I only updated DivsionController, will finish others some time soon. Anyways, Actionpoints are to be inserted in DivisionController only.

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