Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

prettier now

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