Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/ai/src/orxonox/controllers/ArtificialController.cc @ 6640

Last change on this file since 6640 was 6640, checked in by solex, 14 years ago

first bot master/slave behavior

  • Property svn:eol-style set to native
File size: 11.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 *      ...
26 *
27 */
28
29#include "ArtificialController.h"
30
31#include "core/CoreIncludes.h"
32#include "core/XMLPort.h"
33#include "worldentities/ControllableEntity.h"
34#include "worldentities/pawns/Pawn.h"
35#include "worldentities/pawns/TeamBaseMatchBase.h"
36#include "gametypes/TeamDeathmatch.h"
37#include "controllers/WaypointPatrolController.h"
38
39namespace orxonox
40{
41    ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator)
42    {
43        RegisterObject(ArtificialController);
44
45        this->target_ = 0;
46        this->team_ = -1;//new
47        this->state_ = 0;//new
48        this->bShooting_ = false;
49        this->bHasTargetPosition_ = false;
50        this->targetPosition_ = Vector3::ZERO;
51
52        this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this));
53    }
54
55    ArtificialController::~ArtificialController()
56    {
57    }
58
59    void ArtificialController::XMLPort(Element& xmlelement, XMLPort::Mode mode)
60    {
61        SUPER(ArtificialController, XMLPort, xmlelement, mode);
62
63        XMLPortParam(ArtificialController, "team", setTeam, getTeam, xmlelement, mode).defaultValues(0);
64    }
65
66    void ArtificialController::moveToPosition(const Vector3& target)
67    {
68        if (!this->getControllableEntity())
69            return;
70
71        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
72        float distance = (target - this->getControllableEntity()->getPosition()).length();
73
74        if (this->target_ || distance > 10)
75        {
76            // Multiply with 0.8 to make them a bit slower
77            this->getControllableEntity()->rotateYaw(-0.8f * sgn(coord.x) * coord.x*coord.x);
78            this->getControllableEntity()->rotatePitch(0.8f * sgn(coord.y) * coord.y*coord.y);
79        }
80
81        if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
82            this->getControllableEntity()->moveFrontBack(-0.5f); // They don't brake with full power to give the player a chance
83        else
84            this->getControllableEntity()->moveFrontBack(0.8f);
85    }
86
87    void ArtificialController::moveToTargetPosition()
88    {
89        this->moveToPosition(this->targetPosition_);
90    }
91
92    int ArtificialController::getState()
93    {
94        return this->state_;
95    }
96
97    void ArtificialController::searchNewMaster()
98    {
99        if (!this->getControllableEntity())
100            return;
101
102        this->targetPosition_ = this->getControllableEntity()->getPosition();
103        this->forgetTarget();
104
105        //go through all pawns
106        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
107        {
108            //same team? no: continue
109            if (!ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
110                continue;
111
112            //has it an ArtificialController and is it a master? no: continue
113
114            ArtificialController *controller = static_cast<ArtificialController*>(it->getController());
115            if (controller && controller->getState()!=1)
116                continue;
117
118            //is pawn oneself? && is pawn in range?
119            if (static_cast<ControllableEntity*>(*it) != this->getControllableEntity() /*&& it->getPosition().squaredDistance(this->getControllableEntity()->getPosition()) < 1000 */)
120            {
121                //this->target_ = (*it);
122                //this->targetPosition_ = it->getPosition();
123                this->state_ = -1;
124
125            }
126        }//for
127
128        //hasn't encountered any masters in range? -> become a master
129        if (state_!=-1) state_=1; // keep in mind: what happens when two masters encounter eache other? -> has to be evaluated in the for loop of within master mode in AIcontroller...
130    }
131
132    void ArtificialController::setTargetPosition(const Vector3& target)
133    {
134        this->targetPosition_ = target;
135        this->bHasTargetPosition_ = true;
136    }
137
138    void ArtificialController::searchRandomTargetPosition()
139    {
140        this->targetPosition_ = Vector3(rnd(-2000,2000), rnd(-2000,2000), rnd(-2000,2000));
141        this->bHasTargetPosition_ = true;
142    }
143
144    void ArtificialController::setTarget(Pawn* target)
145    {
146        this->target_ = target;
147
148        if (target)
149            this->targetPosition_ = target->getPosition();
150    }
151
152    void ArtificialController::searchNewTarget()
153    {
154        if (!this->getControllableEntity())
155            return;
156
157        this->targetPosition_ = this->getControllableEntity()->getPosition();
158        this->forgetTarget();
159
160        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
161        {
162            if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
163                continue;
164
165            if (static_cast<ControllableEntity*>(*it) != this->getControllableEntity())
166            {
167                float speed = this->getControllableEntity()->getVelocity().length();
168                Vector3 distanceCurrent = this->targetPosition_ - this->getControllableEntity()->getPosition();
169                Vector3 distanceNew = it->getPosition() - this->getControllableEntity()->getPosition();
170                if (!this->target_ || it->getPosition().squaredDistance(this->getControllableEntity()->getPosition()) * (1.5f + acos((this->getControllableEntity()->getOrientation() * WorldEntity::FRONT).dotProduct(distanceNew) / speed / distanceNew.length()) / (2 * Ogre::Math::PI))
171                        < this->targetPosition_.squaredDistance(this->getControllableEntity()->getPosition()) * (1.5f + acos((this->getControllableEntity()->getOrientation() * WorldEntity::FRONT).dotProduct(distanceCurrent) / speed / distanceCurrent.length()) / (2 * Ogre::Math::PI)) + rnd(-250, 250))
172                {
173                    this->target_ = (*it);
174                    this->targetPosition_ = it->getPosition();
175                }
176            }
177        }
178    }
179
180    void ArtificialController::forgetTarget()
181    {
182        this->target_ = 0;
183        this->bShooting_ = false;
184    }
185
186    void ArtificialController::aimAtTarget()
187    {
188        if (!this->target_ || !this->getControllableEntity())
189            return;
190
191        static const float hardcoded_projectile_speed = 1250;
192
193        this->targetPosition_ = getPredictedPosition(this->getControllableEntity()->getPosition(), hardcoded_projectile_speed, this->target_->getPosition(), this->target_->getVelocity());
194        this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO);
195
196        Pawn* pawn = dynamic_cast<Pawn*>(this->getControllableEntity());
197        if (pawn)
198            pawn->setAimPosition(this->targetPosition_);
199    }
200
201    bool ArtificialController::isCloseAtTarget(float distance) const
202    {
203        if (!this->getControllableEntity())
204            return false;
205
206        if (!this->target_)
207            return (this->getControllableEntity()->getPosition().squaredDistance(this->targetPosition_) < distance*distance);
208        else
209            return (this->getControllableEntity()->getPosition().squaredDistance(this->target_->getPosition()) < distance*distance);
210    }
211
212    bool ArtificialController::isLookingAtTarget(float angle) const
213    {
214        if (!this->getControllableEntity())
215            return false;
216
217        return (getAngle(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->targetPosition_) < angle);
218    }
219
220    void ArtificialController::abandonTarget(Pawn* target)
221    {
222        if (target == this->target_)
223            this->targetDied();
224    }
225
226    void ArtificialController::targetDied()
227    {
228        this->forgetTarget();
229        this->searchRandomTargetPosition();
230    }
231
232    bool ArtificialController::sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
233    {
234        if (entity1 == entity2)
235            return true;
236
237        int team1 = -1;
238        int team2 = -1;
239
240        Controller* controller = 0;
241        if (entity1->getController())
242            controller = entity1->getController();
243        else
244            controller = entity1->getXMLController();
245        if (controller)
246        {
247            ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
248            if (ac)
249                team1 = ac->getTeam();
250        }
251
252        if (entity1->getController())
253            controller = entity1->getController();
254        else
255            controller = entity1->getXMLController();
256        if (controller)
257        {
258            ArtificialController* ac = orxonox_cast<ArtificialController*>(controller);
259            if (ac)
260                team2 = ac->getTeam();
261        }
262
263        TeamDeathmatch* tdm = orxonox_cast<TeamDeathmatch*>(gametype);
264        if (tdm)
265        {
266            if (entity1->getPlayer())
267                team1 = tdm->getTeam(entity1->getPlayer());
268
269            if (entity2->getPlayer())
270                team2 = tdm->getTeam(entity2->getPlayer());
271        }
272
273        TeamBaseMatchBase* base = 0;
274        base = orxonox_cast<TeamBaseMatchBase*>(entity1);
275        if (base)
276        {
277            switch (base->getState())
278            {
279                case BaseState::ControlTeam1:
280                    team1 = 0;
281                    break;
282                case BaseState::ControlTeam2:
283                    team1 = 1;
284                    break;
285                case BaseState::Uncontrolled:
286                default:
287                    team1 = -1;
288            }
289        }
290        base = orxonox_cast<TeamBaseMatchBase*>(entity2);
291        if (base)
292        {
293            switch (base->getState())
294            {
295                case BaseState::ControlTeam1:
296                    team2 = 0;
297                    break;
298                case BaseState::ControlTeam2:
299                    team2 = 1;
300                    break;
301                case BaseState::Uncontrolled:
302                default:
303                    team2 = -1;
304            }
305        }
306
307        return (team1 == team2 && team1 != -1);
308    }
309}
Note: See TracBrowser for help on using the repository browser.