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, 10 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.