Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Gani changed something

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