Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/controllers/ArtificialController.cc @ 6072

Last change on this file since 6072 was 5929, checked in by rgrieder, 15 years ago

Merged core5 branch back to the trunk.
Key features include clean level unloading and an extended XML event system.

Two important notes:
Delete your keybindings.ini files! * or you will still get parser errors when loading the key bindings.
Delete build_dir/lib/modules/libgamestates.module! * or orxonox won't start.
Best thing to do is to delete the build folder ;)

  • Property svn:eol-style set to native
File size: 8.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 *      ...
26 *
27 */
28
29#include "ArtificialController.h"
30
31#include "core/CoreIncludes.h"
32#include "worldentities/ControllableEntity.h"
33#include "worldentities/pawns/Pawn.h"
34#include "worldentities/pawns/TeamBaseMatchBase.h"
35#include "gametypes/TeamDeathmatch.h"
36#include "controllers/WaypointPatrolController.h"
37
38namespace orxonox
39{
40    ArtificialController::ArtificialController(BaseObject* creator) : Controller(creator)
41    {
42        RegisterObject(ArtificialController);
43
44        this->target_ = 0;
45        this->bShooting_ = false;
46        this->bHasTargetPosition_ = false;
47        this->targetPosition_ = Vector3::ZERO;
48       
49        this->target_.setCallback(createFunctor(&ArtificialController::targetDied, this));
50    }
51
52    ArtificialController::~ArtificialController()
53    {
54    }
55
56    void ArtificialController::moveToPosition(const Vector3& target)
57    {
58        if (!this->getControllableEntity())
59            return;
60
61        Vector2 coord = get2DViewdirection(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->getControllableEntity()->getOrientation() * WorldEntity::UP, target);
62        float distance = (target - this->getControllableEntity()->getPosition()).length();
63
64        if (this->target_ || distance > 10)
65        {
66            // Multiply with 0.8 to make them a bit slower
67            this->getControllableEntity()->rotateYaw(-0.8 * sgn(coord.x) * coord.x*coord.x);
68            this->getControllableEntity()->rotatePitch(0.8 * sgn(coord.y) * coord.y*coord.y);
69        }
70
71        if (this->target_ && distance < 200 && this->getControllableEntity()->getVelocity().squaredLength() > this->target_->getVelocity().squaredLength())
72            this->getControllableEntity()->moveFrontBack(-0.5); // They don't brake with full power to give the player a chance
73        else
74            this->getControllableEntity()->moveFrontBack(0.8);
75    }
76
77    void ArtificialController::moveToTargetPosition()
78    {
79        this->moveToPosition(this->targetPosition_);
80    }
81
82    void ArtificialController::setTargetPosition(const Vector3& target)
83    {
84        this->targetPosition_ = target;
85        this->bHasTargetPosition_ = true;
86    }
87
88    void ArtificialController::searchRandomTargetPosition()
89    {
90        this->targetPosition_ = Vector3(rnd(-2000,2000), rnd(-2000,2000), rnd(-2000,2000));
91        this->bHasTargetPosition_ = true;
92    }
93
94    void ArtificialController::setTarget(Pawn* target)
95    {
96        this->target_ = target;
97
98        if (target)
99            this->targetPosition_ = target->getPosition();
100    }
101
102    void ArtificialController::searchNewTarget()
103    {
104        if (!this->getControllableEntity())
105            return;
106
107        this->targetPosition_ = this->getControllableEntity()->getPosition();
108        this->forgetTarget();
109
110        for (ObjectList<Pawn>::iterator it = ObjectList<Pawn>::begin(); it; ++it)
111        {
112            if (ArtificialController::sameTeam(this->getControllableEntity(), static_cast<ControllableEntity*>(*it), this->getGametype()))
113                continue;
114
115            if (static_cast<ControllableEntity*>(*it) != this->getControllableEntity())
116            {
117                float speed = this->getControllableEntity()->getVelocity().length();
118                Vector3 distanceCurrent = this->targetPosition_ - this->getControllableEntity()->getPosition();
119                Vector3 distanceNew = it->getPosition() - this->getControllableEntity()->getPosition();
120                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))
121                        < 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))
122                {
123                    this->target_ = (*it);
124                    this->targetPosition_ = it->getPosition();
125                }
126            }
127        }
128    }
129
130    void ArtificialController::forgetTarget()
131    {
132        this->target_ = 0;
133        this->bShooting_ = false;
134    }
135
136    void ArtificialController::aimAtTarget()
137    {
138        if (!this->target_ || !this->getControllableEntity())
139            return;
140
141        static const float hardcoded_projectile_speed = 1250;
142
143        this->targetPosition_ = getPredictedPosition(this->getControllableEntity()->getPosition(), hardcoded_projectile_speed, this->target_->getPosition(), this->target_->getVelocity());
144        this->bHasTargetPosition_ = (this->targetPosition_ != Vector3::ZERO);
145    }
146
147    bool ArtificialController::isCloseAtTarget(float distance) const
148    {
149        if (!this->getControllableEntity())
150            return false;
151
152        if (!this->target_)
153            return (this->getControllableEntity()->getPosition().squaredDistance(this->targetPosition_) < distance*distance);
154        else
155            return (this->getControllableEntity()->getPosition().squaredDistance(this->target_->getPosition()) < distance*distance);
156    }
157
158    bool ArtificialController::isLookingAtTarget(float angle) const
159    {
160        if (!this->getControllableEntity())
161            return false;
162
163        return (getAngle(this->getControllableEntity()->getPosition(), this->getControllableEntity()->getOrientation() * WorldEntity::FRONT, this->targetPosition_) < angle);
164    }
165
166    void ArtificialController::abandonTarget(Pawn* target)
167    {
168        if (target == this->target_)
169            this->targetDied();
170    }
171
172    void ArtificialController::targetDied()
173    {
174        this->forgetTarget();
175        this->searchRandomTargetPosition();
176    }
177
178    bool ArtificialController::sameTeam(ControllableEntity* entity1, ControllableEntity* entity2, Gametype* gametype)
179    {
180        if (entity1 == entity2)
181            return true;
182
183        int team1 = -1;
184        int team2 = -1;
185
186        if (entity1->getXMLController())
187        {
188            WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity1->getXMLController());
189            if (wpc)
190                team1 = wpc->getTeam();
191        }
192        if (entity2->getXMLController())
193        {
194            WaypointPatrolController* wpc = orxonox_cast<WaypointPatrolController*>(entity2->getXMLController());
195            if (wpc)
196                team2 = wpc->getTeam();
197        }
198
199        TeamDeathmatch* tdm = orxonox_cast<TeamDeathmatch*>(gametype);
200        if (tdm)
201        {
202            if (entity1->getPlayer())
203                team1 = tdm->getTeam(entity1->getPlayer());
204
205            if (entity2->getPlayer())
206                team2 = tdm->getTeam(entity2->getPlayer());
207        }
208
209        TeamBaseMatchBase* base = 0;
210        base = orxonox_cast<TeamBaseMatchBase*>(entity1);
211        if (base)
212        {
213            switch (base->getState())
214            {
215                case BaseState::ControlTeam1:
216                    team1 = 0;
217                    break;
218                case BaseState::ControlTeam2:
219                    team1 = 1;
220                    break;
221                case BaseState::Uncontrolled:
222                default:
223                    team1 = -1;
224            }
225        }
226        base = orxonox_cast<TeamBaseMatchBase*>(entity2);
227        if (base)
228        {
229            switch (base->getState())
230            {
231                case BaseState::ControlTeam1:
232                    team2 = 0;
233                    break;
234                case BaseState::ControlTeam2:
235                    team2 = 1;
236                    break;
237                case BaseState::Uncontrolled:
238                default:
239                    team2 = -1;
240            }
241        }
242
243        return (team1 == team2 && team1 != -1);
244    }
245}
Note: See TracBrowser for help on using the repository browser.