Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10737 was 10737, checked in by gania, 9 years ago

nothing really changed

File size: 9.4 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/*
30#include "weaponsystem/WeaponMode.h"
31#include "weaponsystem/WeaponPack.h"
32#include "weaponsystem/Weapon.h"
33#include "weaponsystem/WeaponSlot.h"
34#include "weaponsystem/WeaponSlot.h"
35#include "worldentities/pawns/SpaceShip.h"
36*/
37
38namespace orxonox
39{
40
41    RegisterClass(CommonController);
42    static const float SPEED = 0.6f;
43    static const float ROTATEFACTOR = 0.2f;
44
45    CommonController::CommonController(Context* context) : Controller(context)
46    {
47        //this->bSetupWorked = false;
48
49        RegisterObject(CommonController);
50    }
51
52
53    CommonController::~CommonController()
54    {
55    }
56
57
58
59
60    bool CommonController::setWingman (CommonController* wingman)
61    {
62        return false;
63    }
64   
65    bool CommonController::hasWingman()
66    {
67        return true;
68    }
69
70
71
72
73    void CommonController::setTargetPosition(const Vector3& target)
74    {
75        this->targetPosition_ = target;
76        this->bHasTargetPosition_ = true;
77    }
78
79    void CommonController::setTargetOrientation(const Quaternion& orient)
80    {
81        this->targetOrientation_=orient;
82        this->bHasTargetOrientation_=true;
83    }
84
85    void CommonController::setTargetOrientation(ControllableEntity* target)
86    {
87        if (target)
88            setTargetOrientation(target->getOrientation());
89    }
90
91    /*void CommonController::spin()
92    {
93        this->moveToTargetPosition();
94        this->getControllableEntity()->rotateRoll(8.0f);
95    }
96    void CommonController::turn180()
97    {
98        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, this->targetPosition_);
99
100        this->getControllableEntity()->rotateYaw(-2.0f * sgn(coord.x) * coord.x*coord.x);
101        this->getControllableEntity()->rotatePitch(2.0f * sgn(coord.y) * coord.y*coord.y);
102
103        this->getControllableEntity()->moveFrontBack(SPEED);
104    }*/
105
106
107
108    //copy the Roll orientation of given Quaternion.
109    void CommonController::copyOrientation(const Quaternion& orient)
110    {
111        //roll angle difference in radian
112        float diff=orient.getRoll(false).valueRadians()-(this->getControllableEntity()->getOrientation().getRoll(false).valueRadians());
113        while(diff>math::twoPi) diff-=math::twoPi;
114        while(diff<-math::twoPi) diff+=math::twoPi;
115        this->getControllableEntity()->rotateRoll(-diff);
116    }
117    void CommonController::copyTargetOrientation()
118    {
119        if (bHasTargetOrientation_)
120        {   
121            copyOrientation(targetOrientation_);
122        }
123    }
124
125
126
127
128    void CommonController::moveToTargetPosition()
129    {
130        this->moveToPosition(this->targetPosition_);
131    }
132    void CommonController::moveToPosition(const Vector3& target)
133    {
134        if (!this->getControllableEntity())
135            return;
136       
137        //100 is (so far) the smallest tolerance (empirically found) that can be reached,
138        //with smaller distance spaceships can't reach position and go circles around it instead
139        int tolerance = 100;
140
141        ControllableEntity* entity = this->getControllableEntity();
142        Vector2 coord = get2DViewCoordinates
143            (entity->getPosition(), 
144            entity->getOrientation() * WorldEntity::FRONT, 
145            entity->getOrientation() * WorldEntity::UP, 
146            target);
147
148        float distance = (target - this->getControllableEntity()->getPosition()).length();
149
150        //rotates should be in range [-1,+1], clamp cuts off all that is not
151        float rotateX = clamp(coord.x * 10, -1.0f, 1.0f);
152        float rotateY = clamp(coord.y * 10, -1.0f, 1.0f);
153
154       
155        if (distance > tolerance)
156        {
157            //Yaw and Pitch are enough to start facing the target
158            this->getControllableEntity()->rotateYaw(-2.0f * ROTATEFACTOR * rotateX);
159            this->getControllableEntity()->rotatePitch(2.0f * ROTATEFACTOR * rotateY);
160
161            //300 works, maybe less is better
162            if (distance < 300)
163            {
164                //Change roll when close. When Spaceship faces target, roll doesn't affect it's trajectory
165                //It's important that roll is not changed in the process of changing yaw and pitch
166                //Wingmen won't face same direction as Leaders, but when Leaders start moving
167                //Yaw and Pitch will adapt.
168                if (bHasTargetOrientation_)
169                {
170                    copyTargetOrientation();
171                }
172            }
173            this->getControllableEntity()->moveFrontBack(1.2f*SPEED);
174        }
175        else
176        {     
177            bHasTargetPosition_ = false;
178            bHasTargetOrientation_ = false;
179        }
180    }
181
182/*
183    int CommonController::getFiremode(std::string name)
184    {
185        for (std::map< std::string, int >::iterator it = this->weaponModes_.begin(); it != this->weaponModes_.end(); ++it)
186        {
187            if (it->first == name)
188                return it->second;
189        }
190        return -1;
191    }
192    bool CommonController::isCloseAtTarget(float distance) const
193    {
194        if (!this->getControllableEntity())
195            return false;
196
197        if (!this->target_)
198            return (this->getControllableEntity()->getPosition().squaredDistance(this->targetPosition_) < distance*distance);
199        else
200            return (this->getControllableEntity()->getPosition().squaredDistance(this->target_->getPosition()) < distance*distance);
201    }
202    void CommonController::setupWeapons() //TODO: Make this function generic!! (at the moment is is based on conventions)
203    {
204        this->bSetupWorked = false;
205        if(this->getControllableEntity())
206        {
207            Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
208            if(pawn && pawn->isA(Class(SpaceShip))) //fix for First Person Mode: check for SpaceShip
209            {
210                this->weaponModes_.clear(); // reset previous weapon information
211                WeaponSlot* wSlot = 0;
212                for(int l=0; (wSlot = pawn->getWeaponSlot(l)) ; l++)
213                {
214                    WeaponMode* wMode = 0;
215                    for(int i=0; (wMode = wSlot->getWeapon()->getWeaponmode(i)) ; i++)
216                    {
217                        std::string wName = wMode->getIdentifier()->getName();
218                        if(this->getFiremode(wName) == -1) //only add a weapon, if it is "new"
219                            weaponModes_[wName] = wMode->getMode();
220                    }
221                }
222                if(weaponModes_.size())//at least one weapon detected
223                    this->bSetupWorked = true;
224            }//pawn->weaponSystem_->getMunition(SubclassIdentifier< Munition > *identifier)->getNumMunition (WeaponMode *user);
225        }
226    }
227    void CommonController::doFire()
228    {
229        if(!this->bSetupWorked)//setup: find out which weapons are active ! hard coded: laser is "0", lens flare is "1", ...
230        {
231            this->setupWeapons();
232        }
233        else if(this->getControllableEntity() &&
234            weaponModes_.size()&&
235            this->bShooting_ &&
236            this->isCloseAtTarget((3)*1000) &&
237            this->isLookingAtTarget(math::pi / 20.0f))
238        {
239            int firemode;
240            float random = rnd(1);//
241            if (this->isCloseAtTarget(130) && (firemode = getFiremode("LightningGun")) > -1 )
242            {//LENSFLARE: short range weapon
243                this->getControllableEntity()->fire(firemode); //ai uses lens flare if they're close enough to the target
244            }
245           
246            else if ((firemode = getFiremode("HsW01")) > -1 ) //LASER: default weapon
247                this->getControllableEntity()->fire(firemode);
248        }
249    }
250    bool CommonController::isLookingAtTarget(float angle) const
251    {
252        if (!this->getControllableEntity())
253            return false;
254
255        return (getAngle(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->targetPosition_) < angle);
256    }
257
258    void CommonController::aimAtTarget()
259    {
260        if (!this->target_ || !this->getControllableEntity())
261            return;
262
263        static const float hardcoded_projectile_speed = 750;
264
265        Vector3 aimPosition = getPredictedPosition(this->getControllableEntity()->getWorldPosition(),
266            hardcoded_projectile_speed, this->target_->getWorldPosition(), this->target_->getVelocity());
267
268        Pawn* pawn = orxonox_cast<Pawn*>(this->getControllableEntity());
269        if (pawn)
270            pawn->setAimPosition(aimPosition);
271    }*/
272   
273 
274
275}
Note: See TracBrowser for help on using the repository browser.