Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/AI_HS15/src/orxonox/controllers/CommonController.cc @ 10800

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

compilable

File size: 29.7 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#include <OgreRay.h>
41#include <OgreSceneQuery.h>
42#include <OgreCamera.h>
43#include <OgreSceneManager.h>
44namespace orxonox
45{
46
47    RegisterClass( CommonController );
48    float SPEED = 0.9f/0.02f;
49    float ROTATEFACTOR = 0.5f/0.02f;
50
51    CommonController::CommonController( Context* context ): Controller( context )
52    {
53        this->bSetupWorked = false;
54
55        this->executingManeuver_ = false;
56        this->executingMoveToPoint_ = false;
57
58        this->maneuverType_ = ManeuverType::NONE;
59        RegisterObject( CommonController );
60    }
61
62
63    CommonController::~CommonController() 
64    {
65    }
66
67    void CommonController::XMLPort( Element& xmlelement, XMLPort::Mode mode )
68    {
69        SUPER( CommonController, XMLPort, xmlelement, mode );
70        XMLPortParam( CommonController, "formationMode", setFormationModeXML, getFormationModeXML,  xmlelement, mode );
71
72    }
73    void CommonController::setFormationModeXML( std::string val )
74    {
75        const std::string valUpper = getUppercase( val );
76        FormationMode::Value value;
77        if ( valUpper == "VEE" )
78            value = FormationMode::VEE;
79        else if ( valUpper == "WALL" )
80            value = FormationMode::WALL;
81        else if ( valUpper == "FINGER4" )
82            value = FormationMode::FINGER4;
83        else if ( valUpper == "DIAMOND" )
84            value = FormationMode::DIAMOND;
85        else
86            ThrowException( ParseError, std::string( "Attempting to set an unknown FormationMode: '" )+ val + "'." );
87        this->setFormationMode( value );
88       
89    }
90    std::string CommonController::getFormationModeXML() 
91    {
92        switch ( this->formationMode_ )
93        {
94            case FormationMode::VEE:
95            {
96                return "VEE";
97                break;
98            }
99            case FormationMode::WALL:
100            {
101                return "WALL";
102                break;
103            }
104            case FormationMode::FINGER4:
105            {
106                return "FINGER4";
107                break;
108            }
109            case FormationMode::DIAMOND:
110            {
111                return "DIAMOND";
112                break;
113            }
114            default:
115                return "DIAMOND";
116                break;
117
118        }
119    }
120    void CommonController::maneuver() 
121    {
122
123        if ( this->target_ && this->bHasPositionOfTarget_ && this->getControllableEntity() )
124        {
125            Vector3 thisPosition = this->getControllableEntity() ->getWorldPosition();
126            Quaternion thisOrientation = this->getControllableEntity() ->getOrientation();
127
128            /*this->setPositionOfTarget( getPredictedPosition(
129                thisPosition,
130                hardcoded_projectile_speed,
131                this->target_->getWorldPosition() ,
132                this->target_->getVelocity() 
133                ) );*/
134            this->setPositionOfTarget( this->target_->getWorldPosition()  );
135            this->setOrientationOfTarget( this->target_->getOrientation() );
136
137
138            Vector3 diffVector = this->positionOfTarget_ - thisPosition;
139            float diffLength = diffVector.length();
140            Vector3 diffUnit = diffVector/diffLength;
141
142            Vector3 thisForwardVector = thisOrientation * WorldEntity::FRONT;
143            float thisDotProduct = diffVector.dotProduct( thisForwardVector );
144
145            Vector3 targetForwardVector = this->orientationOfTarget_ * WorldEntity::FRONT;
146            float targetDotProduct = diffVector.dotProduct( targetForwardVector );           
147
148            float thisAngle = getAngle( thisPosition, thisForwardVector, this->positionOfTarget_ ); 
149            float targetAngle = getAngle( this->positionOfTarget_, targetForwardVector, thisPosition ); 
150
151
152            bool bThisIsLookingAtTarget = ( thisAngle/( diffLength*diffLength ) < math::pi/8000000.0f );
153            bool bTargetIsLookingAtThis = ( targetAngle/( diffLength*diffLength ) < math::pi/8000000.0f );
154           
155            float angleDiff = targetAngle - thisAngle;
156
157            //if his angle is bigger than mine
158            if ( angleDiff > 0 )
159            {
160                //if diff is insignificant
161                if ( bThisIsLookingAtTarget && bTargetIsLookingAtThis )
162                {
163                    //no way to dodge
164                    if ( diffLength < 400 )
165                    {
166                        Vector3* target = new Vector3 ( 0, -200, -200 );
167                        this->setTargetPosition( this->positionOfTarget_ );
168
169
170                    }
171                    //do scissors
172                    else
173                    {
174                        Vector3 target = ( diffUnit )* 150.0f;
175                        Vector3* randVector = new Vector3( 
176                            randomInRange( -300, 300 ), 
177                            randomInRange( -300, 300 ), 
178                            randomInRange( -300, 300 ) 
179                        );
180                        Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit;
181                        *randVector -= projection;
182                        target += *randVector;
183                        this->setTargetPosition( this->getControllableEntity() ->getWorldPosition() + target );
184
185                    }
186                }
187                //this has advantage
188                else
189                {
190                    //if too close
191                    if ( diffLength < 300 )
192                    {
193                        this->setTargetPosition( this->getControllableEntity() ->getWorldPosition()  );
194                    }
195                    //move closer
196                    else
197                    {
198                        this->setTargetPosition( this->positionOfTarget_ - 0.6f*diffVector );
199                    }
200                }
201            }
202            else
203            {
204                //if diff is insignificant
205                if ( bThisIsLookingAtTarget && bTargetIsLookingAtThis )
206                {
207                    //no way to dodge
208                    if ( diffLength < 400 )
209                    {
210                        Vector3* target = new Vector3 ( 0, -200, -200 );
211                        this->setTargetPosition( this->positionOfTarget_ );
212
213                    }
214                    //do scissors
215                    else
216                    {
217                        Vector3 target = ( diffUnit )* 150.0f;
218                        Vector3* randVector = new Vector3( 
219                            randomInRange( -300, 300 ), 
220                            randomInRange( -300, 300 ), 
221                            randomInRange( -300, 300 ) 
222                        );
223                        Vector3 projection = randVector->dotProduct( diffUnit )* diffUnit;
224                        *randVector -= projection;
225                        target += *randVector;
226                        this->setTargetPosition( this->getControllableEntity() ->getWorldPosition() + target );
227
228                    }
229                }
230                //target has advantage
231                else
232                {
233                    //if too close
234                    if ( diffLength < 300 )
235                    {
236                        this->setTargetPosition( this->getControllableEntity() ->getWorldPosition()  );
237                    }
238                    //move closer
239                    else
240                    {
241                        this->setTargetPosition( this->positionOfTarget_ - 0.6f*diffVector );
242                    }
243                }
244            }
245            this->bShooting_ = true;
246           
247        }
248        if ( this->getControllableEntity()  && !this->target_ )
249        {
250            this->maneuverType_ = ManeuverType::NONE;
251        }
252        orxout ( internal_error ) << "ManeuverType = " << this->maneuverType_ << endl;
253    }
254    void CommonController::chooseManeuverType() 
255    {
256
257        if ( this->target_ && this->bHasPositionOfTarget_ && this->getControllableEntity() )
258        {
259            Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity() ->getWorldPosition();
260            Vector3 thisForwardVector = this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT;
261            float thisDotProduct = diffVector.dotProduct( thisForwardVector );
262
263            Vector3 targetForwardVector = this->target_->getOrientation()  * WorldEntity::FRONT;
264            float targetDotProduct = diffVector.dotProduct( targetForwardVector );           
265
266
267            switch ( ( thisDotProduct > 0 )- ( thisDotProduct < 0 ))
268            {
269                case 1:
270                {
271                    switch ( ( targetDotProduct > 0 )- ( targetDotProduct < 0 ))
272                    {
273                        case 1:
274                        {
275                            this->maneuverType_ = ManeuverType::OFFENSIVE;
276                            break;
277                        }
278                        case 0:
279                        {
280                            this->maneuverType_ = ManeuverType::OFFENSIVE;
281                            break;
282                        }
283                        case -1:
284                        {
285                            this->maneuverType_ = ManeuverType::NEUTRAL;
286                            break;
287                        }
288                    }
289                    break;
290                }
291                case 0:
292                {
293                    switch ( ( targetDotProduct > 0 )- ( targetDotProduct < 0 ))
294                    {
295                        case 1:
296                        {
297                            this->maneuverType_ = ManeuverType::OFFENSIVE;
298                            break;
299                        }
300                        case 0:
301                        {
302                            this->maneuverType_ = ManeuverType::NEUTRAL;
303                            break;
304                        }
305                        case -1:
306                        {
307                            this->maneuverType_ = ManeuverType::DEFENCIVE;
308                            break;
309                        }
310                    }
311
312                    break;
313                }
314                case -1:
315                {
316                    switch ( ( targetDotProduct > 0 )- ( targetDotProduct < 0 ))
317                    {
318                        case 1:
319                        {
320                            this->maneuverType_ = ManeuverType::NEUTRAL;
321                            break;
322                        }
323                        case 0:
324                        {
325                            this->maneuverType_ = ManeuverType::DEFENCIVE;
326                            break;
327                        }
328                        case -1:
329                        {
330                            this->maneuverType_ = ManeuverType::DEFENCIVE;
331                            break;
332                        }
333                    }
334                    break;
335                }
336            }
337        }
338        if ( this->getControllableEntity()  && !this->target_ )
339        {
340            this->maneuverType_ = ManeuverType::NONE;
341        }
342        orxout ( internal_error ) << "ManeuverType = " << this->maneuverType_ << endl;
343    }
344    bool CommonController::setWingman ( CommonController* wingman )
345    {
346        return false;
347    }
348   
349    bool CommonController::hasWingman() 
350    {
351        return true;
352    }
353    void CommonController::setTarget( ControllableEntity* target )
354    {
355        this->target_ = target;
356        orxout ( internal_error ) << " TARGET SET " << endl;
357       
358        if ( this->target_ )
359        {
360            this->setPositionOfTarget( target_->getWorldPosition() );
361
362        }
363    }
364    bool CommonController::hasTarget() 
365    {
366        if ( this->target_ )
367            return true;
368        return false;
369    }
370    void CommonController::setPositionOfTarget( const Vector3& target )
371    {
372        this->positionOfTarget_ = target;
373        this->bHasPositionOfTarget_ = true;
374    }
375    void CommonController::setOrientationOfTarget( const Quaternion& orient )
376    {
377        this->orientationOfTarget_=orient;
378        this->bHasOrientationOfTarget_=true;
379    }
380
381    void CommonController::setTargetPosition( const Vector3& target )
382    {
383        this->targetPosition_ = target;
384        this->bHasTargetPosition_ = true;
385    }
386
387    void CommonController::setTargetOrientation( const Quaternion& orient )
388    {
389        this->targetOrientation_=orient;
390        this->bHasTargetOrientation_=true;
391    }
392
393    void CommonController::setTargetOrientation( ControllableEntity* target )
394    {
395        if ( target )
396            setTargetOrientation( target->getOrientation() );
397    }
398
399    /*void CommonController::spin()
400    {
401        this->moveToTargetPosition();
402        this->getControllableEntity() ->rotateRoll( 8.0f );
403    }
404    void CommonController::turn180()
405    {
406        Vector2 coord = get2DViewdirection( this->getControllableEntity() ->getPosition() , this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT, this->getControllableEntity() ->getOrientation()  * WorldEntity::UP, this->targetPosition_ );
407
408        this->getControllableEntity() ->rotateYaw( -2.0f * sgn( coord.x )* coord.x*coord.x );
409        this->getControllableEntity() ->rotatePitch( 2.0f * sgn( coord.y )* coord.y*coord.y );
410
411        this->getControllableEntity() ->moveFrontBack( SPEED );
412    }*/
413
414
415
416    //copy the Roll orientation of given Quaternion.
417    void CommonController::copyOrientation( const Quaternion& orient, float dt )
418    {
419        //roll angle difference in radian
420        float diff=orient.getRoll( false ).valueRadians() -( this->getControllableEntity() ->getOrientation() .getRoll( false ).valueRadians() );
421        while( diff>math::twoPi )diff-=math::twoPi;
422        while( diff<-math::twoPi )diff+=math::twoPi;
423        this->getControllableEntity() ->rotateRoll( diff*ROTATEFACTOR * dt );
424    }
425    void CommonController::copyTargetOrientation( float dt )
426    {
427        if ( bHasTargetOrientation_ )
428        {   
429            copyOrientation( targetOrientation_, dt );
430        }
431    }
432
433
434
435
436    void CommonController::moveToTargetPosition( float dt )
437    {
438        this->moveToPosition( this->targetPosition_, dt );
439    }
440    void CommonController::moveToPosition( const Vector3& target, float dt )
441    {
442        float factor = 1;
443        if ( !this->getControllableEntity() )
444            return;
445        if ( this->rank_ == Rank::DIVISIONLEADER )
446            factor = 0.8;
447        if ( this->rank_ == Rank::SECTIONLEADER )
448            factor = 0.9;
449       
450        //100 is ( so far )the smallest tolerance ( empirically found )that can be reached,
451        //with smaller distance spaceships can't reach position and go circles around it instead
452        int tolerance = 60;
453
454        ControllableEntity* entity = this->getControllableEntity();
455        Vector2 coord = get2DViewCoordinates
456            ( entity->getPosition() , 
457            entity->getOrientation()  * WorldEntity::FRONT, 
458            entity->getOrientation()  * WorldEntity::UP, 
459            target );
460
461        float distance = ( target - this->getControllableEntity() ->getPosition() ).length();
462
463        //rotates should be in range [-1,+1], clamp cuts off all that is not
464        float rotateX = clamp( coord.x * 10, -1.0f, 1.0f );
465        float rotateY = clamp( coord.y * 10, -1.0f, 1.0f );
466
467       
468        if ( distance > tolerance )
469        {
470            //Yaw and Pitch are enough to start facing the target
471            this->getControllableEntity() ->rotateYaw( -2.0f * ROTATEFACTOR * rotateX * dt );
472            this->getControllableEntity() ->rotatePitch( 2.0f * ROTATEFACTOR * rotateY * dt );
473
474            //300 works, maybe less is better
475            if ( distance < 400 )
476            {
477                //Change roll when close. When Spaceship faces target, roll doesn't affect it's trajectory
478                //It's important that roll is not changed in the process of changing yaw and pitch
479                //Wingmen won't face same direction as Leaders, but when Leaders start moving
480                //Yaw and Pitch will adapt.
481                if ( bHasTargetOrientation_ )
482                {
483                    copyTargetOrientation( dt );
484                }
485            }
486
487            this->getControllableEntity() ->moveFrontBack( 1.2f*SPEED*factor * dt );
488        }
489        else
490        {     
491            bHasTargetPosition_ = false;
492            bHasTargetOrientation_ = false;
493        }
494    }
495    float CommonController::randomInRange( float a, float b )
496    {
497        float random = rnd( 1.0f );
498        float diff = b - a;
499        float r = random * diff;
500        return a + r;
501    }
502    void CommonController::attack() 
503    {
504        if ( !this->getControllableEntity()  )
505            return;
506        if ( this->target_ )
507        {
508            this->positionOfTarget_ = getPredictedPosition( 
509                this->getControllableEntity() ->getWorldPosition() , 
510                hardcoded_projectile_speed, 
511                this->target_->getWorldPosition() , 
512                this->target_->getVelocity() 
513                );
514            Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity() ->getWorldPosition();
515            float diffLength = diffVector.length();
516            if ( diffLength < 100 )
517            {
518                Vector3* targetPosition;
519                targetPosition = new Vector3 ( 
520                    //randomInRange( 200, 300 ),
521                    0,
522                    //randomInRange( -300, -200 ),
523                    0,
524                    randomInRange( -300, -400 )
525                    );
526                Quaternion rotationToTarget = ( this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT ).getRotationTo( diffVector );
527                Vector3 target = rotationToTarget * ( *targetPosition );
528                moveToPoint( 
529                    target, 
530                    randomInRange( 45, 180 )
531                    );
532                executingMoveToPoint_ = true; 
533                return;
534            }
535            this->bShooting_ = true;
536            this->positionOfTarget_ = getPredictedPosition( 
537                this->getControllableEntity() ->getWorldPosition() , 
538                hardcoded_projectile_speed, 
539                this->target_->getWorldPosition() , 
540                this->target_->getVelocity() 
541                );
542            this->targetPosition_ = positionOfTarget_;
543
544        }   
545        else
546        {
547            this->chooseManeuverType();
548        }
549    }
550    void CommonController::scissors() 
551    {
552        if ( !this->getControllableEntity()  )
553            return;
554        if ( this->target_ )
555        {
556            this->positionOfTarget_ = getPredictedPosition( 
557                this->getControllableEntity() ->getWorldPosition() , 
558                hardcoded_projectile_speed, 
559                this->target_->getWorldPosition() , 
560                this->target_->getVelocity() 
561                );
562            Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity() ->getWorldPosition();
563            float diffLength = diffVector.length();
564            Vector3 targetForwardVector = this->target_->getOrientation()  * WorldEntity::FRONT;
565            float targetDotProduct = diffVector.dotProduct( targetForwardVector );           
566           
567            int f = ( int )rnd( 100.0f );
568            f = ( f % 2 == 0 ? 1 : -1 );
569
570            if( !this->executingMoveToPoint_ )
571            {
572                Vector3* targetPosition;
573                if ( diffLength < 100 )
574                {
575                    targetPosition = new Vector3 ( 
576                        //f * randomInRange( 200, 300 ),
577                        0,
578                        //f * randomInRange( -300, -200 ),
579                        0,
580                        //randomInRange( -300, -400 )
581                        0
582                        );
583                }
584                else
585                {
586                    if ( targetDotProduct < 0 )
587                    {
588                        targetPosition = new Vector3 ( 
589                        //f * randomInRange( 200, 300 ),
590                        0,
591                        //f * randomInRange( -300, -200 ),
592                        0,
593                        //randomInRange( -300, -400 )
594                        -300
595                        );
596                    }
597                    else
598                    {
599                        targetPosition = new Vector3 ( 
600                        //f * randomInRange( 200, 300 ),
601                        0,
602                        //f * randomInRange( -300, -200 ),
603                        0,
604                        //randomInRange( -300, -400 )
605                        300
606                        );
607                    }
608                }
609                Quaternion rotationToTarget = ( this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT ).getRotationTo( diffVector );
610                Vector3 target = rotationToTarget * ( *targetPosition );
611                moveToPoint( 
612                    target, 
613                    randomInRange( 45, 180 )
614                    );
615                executingMoveToPoint_ = true; 
616            }
617        }
618       
619        else
620        {
621            this->chooseManeuverType();
622        }
623    }
624    void CommonController::gunsD() 
625    {
626        if ( !this->getControllableEntity()  )
627            return;
628        if ( this->target_ )
629        {
630            this->positionOfTarget_ = getPredictedPosition( 
631                this->getControllableEntity() ->getWorldPosition() , 
632                hardcoded_projectile_speed, 
633                this->target_->getWorldPosition() , 
634                this->target_->getVelocity() 
635                );
636            Vector3 diffVector = this->positionOfTarget_ - this->getControllableEntity() ->getWorldPosition();
637            float diffLength = diffVector.length();
638            if( !this->executingMoveToPoint_ )
639            {
640                Vector3* targetPosition;
641                if ( diffLength < 200 )
642                {
643                    targetPosition = new Vector3 ( 
644                        //f * randomInRange( 200, 300 ),
645                        0,
646                        //f * randomInRange( -300, -200 ),
647                        0,
648                        //randomInRange( -300, -400 )
649                        0
650                        );
651                }
652                else if ( diffLength < 500 )
653                {
654                    targetPosition = new Vector3 ( 
655                        //randomInRange( 100, 200 ),
656                        0,
657                        //randomInRange( -200, -100 ),
658                        0,
659                        //randomInRange( -400, -600 )
660                        500
661                        );
662                }
663                else
664                {
665                    targetPosition = new Vector3 ( 
666                        //randomInRange( 200, 300 ),
667                        0,
668                        //randomInRange( -300, -200 ),
669                        0,
670                        //randomInRange( -400, -600 )
671                        500
672                        );
673                }
674                Quaternion rotationToTarget = ( this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT ).getRotationTo( diffVector );
675                Vector3 target = rotationToTarget * ( *targetPosition );
676                moveToPoint( 
677                    target, 
678                    randomInRange( 45, 180 )
679                    );
680                executingMoveToPoint_ = true; 
681            }
682        }
683        else
684        {
685            this->chooseManeuverType();
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_ )
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() )
780            return false;
781
782        return ( getAngle( this->getControllableEntity() ->getPosition() , this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT, this->positionOfTarget_ ) < angle );
783    }
784
785    bool CommonController::canFire() 
786    {
787        float squaredDistance = squaredDistanceToTarget();
788        this->setPositionOfTarget( this->target_->getPosition() );
789
790        if ( this->bShooting_ && squaredDistance < 9000000 && squaredDistance > 10000 && this->isLookingAtTarget( math::pi /( 0.0002f*squaredDistance )) )
791        {
792            return true;
793        }
794        else
795        {
796            return false;
797        }
798
799    }
800    void CommonController::doFire() 
801    {
802        if ( !this->target_ || !this->getControllableEntity() )
803            return;
804        static const float hardcoded_projectile_speed = 750;
805
806        this->positionOfTarget_ = getPredictedPosition( this->getControllableEntity() ->getWorldPosition() , hardcoded_projectile_speed, this->target_->getWorldPosition() , this->target_->getVelocity() );
807        this->bHasPositionOfTarget_ = ( this->positionOfTarget_ != Vector3::ZERO );
808
809        Pawn* pawn = orxonox_cast<Pawn*>( this->getControllableEntity() );
810
811        if ( pawn )
812            //pawn->setAimPosition( this->getControllableEntity() ->getWorldPosition()  + 4000*( this->getControllableEntity() ->getOrientation()  * WorldEntity::FRONT ));
813            pawn->setAimPosition( this->positionOfTarget_ );
814   
815        this->getControllableEntity() ->fire( 0 );
816    }
817   
818
819}
Note: See TracBrowser for help on using the repository browser.