Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/formation/src/orxonox/controllers/AIController.cc @ 8990

Last change on this file since 8990 was 8990, checked in by jo, 13 years ago

Rough adding of both concepts. Further work on the states is needed. (single player bots are inactive at the moment)

  • Property svn:eol-style set to native
File size: 11.1 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
29#include "AIController.h"
30
31#include "util/Math.h"
32#include "core/CoreIncludes.h"
33#include "core/command/Executor.h"
34#include "worldentities/ControllableEntity.h"
35#include "worldentities/pawns/Pawn.h"
36
37namespace orxonox
38{
39    const float AIController::ACTION_INTERVAL = 1.0f;
40
41    CreateFactory(AIController);
42
43    AIController::AIController(BaseObject* creator) : ArtificialController(creator)
44    {
45        RegisterObject(AIController);
46
47        this->actionTimer_.setTimer(ACTION_INTERVAL, true, createExecutor(createFunctor(&AIController::action, this)));
48    }
49
50    AIController::~AIController()
51    {
52    }
53
54    void AIController::action()
55    {
56        float random;
57        float maxrand = 100.0f / ACTION_INTERVAL;
58
59        if (this->state_ == FREE)
60        {
61
62            if (this->formationFlight_)
63            {
64                // return to Master after being forced free
65                if (this->freedomCount_ == 1)
66                {
67                    this->state_ = SLAVE;
68                    this->freedomCount_ = 0;
69                }
70
71                random = rnd(maxrand);
72                if (random < 90 && (((!this->target_) || (random < 50 && this->target_)) && !this->forcedFree()))
73                    this->searchNewMaster();
74            }
75
76            this->defaultBehaviour(maxrand);
77
78        }
79
80        if (this->state_ == SLAVE && this->mode_ == ATTACK) //TODO: add botlevel parameter
81        {
82            // search enemy
83            random = rnd(maxrand);
84            if (random < 75 && (!this->target_))
85                this->searchNewTarget();
86
87            // next enemy
88            random = rnd(maxrand);
89            if (random < 10 && (this->target_))
90                this->searchNewTarget();
91
92            // shoot
93            random = rnd(maxrand);
94            if (!(this->passive_) && random < 75 && (this->target_ && !this->bShooting_))
95                this->bShooting_ = true;
96
97            // stop shooting
98            random = rnd(maxrand);
99            if (random < 25 && (this->bShooting_))
100                this->bShooting_ = false;
101
102        }
103
104        if (this->state_ == MASTER)
105        {
106            this->commandSlaves();
107
108            if  (this->specificMasterAction_ != NONE)
109                    this->specificMasterActionHold();
110
111            else {
112
113                 // make 180 degree turn - a specific Master Action
114                random = rnd(1000.0f);
115                if (random < 5)
116                   this->turn180Init();
117
118                // spin around - a specific Master Action
119                random = rnd(1000.0f);
120                if (random < 5)
121                   this->spinInit();
122
123                /*// follow a randomly chosen human - a specific Master Action
124                random = rnd(1000.0f);
125                if (random < 1)
126                   this->followRandomHumanInit();
127*/
128                 // lose master status (only if less than 4 slaves in formation)
129                random = rnd(maxrand);
130                if(random < 15/(this->slaves_.size()+1) && this->slaves_.size() < 4 )
131                   this->loseMasterState();
132
133                // look out for outher masters if formation is small
134                random = rnd(maxrand);
135                if(this->slaves_.size() < 3 && random < 20)
136                    this->searchNewMaster();
137
138                this->defaultBehaviour(maxrand);
139
140            }
141        }
142
143    }
144
145    void AIController::tick(float dt)
146    {
147        if (!this->isActive())
148            return;
149
150        float random;
151        float maxrand = 100.0f / ACTION_INTERVAL;
152        ControllableEntity* controllable = this->getControllableEntity();
153
154        if (controllable && this->mode_ == NORMAL)// bot is ready to move to a target // mode was DEFAULT in original implementation!
155        {
156            if (this->waypoints_.size() > 0 ) //Waypoint functionality.
157            {
158                WorldEntity* wPoint = this->waypoints_[this->waypoints_.size()-1];
159                if(wPoint)
160                {
161                    this->moveToPosition(wPoint->getWorldPosition()); //BUG ?? sometime wPoint->getWorldPosition() causes crash
162                    if (wPoint->getWorldPosition().squaredDistance(controllable->getPosition()) <= this->squaredaccuracy_)
163                        this->waypoints_.pop_back(); // if goal is reached, remove it from the list
164                }
165                else
166                    this->waypoints_.pop_back(); // remove invalid waypoints
167
168            }
169            else if(this->defaultWaypoint_ && ((this->defaultWaypoint_->getPosition()-controllable->getPosition()).length()  > 200.0f))
170            {
171                this->moveToPosition(this->defaultWaypoint_->getPosition()); // stay within a certain range of the defaultWaypoint_
172                random = rnd(maxrand);
173            }
174        }
175
176        if (this->mode_ != ROCKET)
177        {
178            if (this->state_ == MASTER)
179            {
180                if (this->specificMasterAction_ ==  NONE)
181                {
182                    if (this->target_)
183                    {
184                        if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */
185                            this->forgetTarget();
186                        else
187                        {
188                            this->aimAtTarget();
189                            random = rnd(maxrand);
190                            if(this->botlevel_*70 > random && !this->isCloseAtTarget(100))
191                                this->follow();  //If a bot is shooting a player, it shouldn't let him go away easily.
192                        }
193                    }
194
195                    if (this->bHasTargetPosition_)
196                        this->moveToTargetPosition();
197                    this->doFire();
198                }
199
200                if (this->specificMasterAction_  == TURN180)
201                    this->turn180();
202
203                if (this->specificMasterAction_ == SPIN)
204                    this->spin();
205                if (this->specificMasterAction_ == FOLLOW)
206                    this->follow();
207            }
208
209            if (this->state_ == SLAVE && this->mode_!=ATTACK)
210            {
211                if (this->bHasTargetPosition_)
212                    this->moveToTargetPosition();
213            }
214
215            if (this->state_ == FREE || (this->state_==SLAVE && this->mode_==ATTACK) )
216            {
217                if (this->target_)
218                {
219                    if (!this->target_->getRadarVisibility()) /* So AI won't shoot invisible Spaceships */
220                        this->forgetTarget();
221                    else this->aimAtTarget();
222                }
223
224                if (this->bHasTargetPosition_)
225                    this->moveToTargetPosition();
226
227                    this->doFire();
228            }
229        }
230        else if (this->mode_ == ROCKET)//Rockets do not belong to a group of bots -> bot states are not relevant.
231        {   //Vector-implementation: mode_.back() == ROCKET;
232            if(controllable)
233            {//Check wether the bot is controlling the rocket and if the timeout is over.
234                if(controllable->getIdentifier() == ClassByString("Rocket"))
235
236                {
237                    this->follow();
238                    this->timeout_ -= dt;
239                    if((timeout_< 0)||(!target_))//Check if the timeout is over or target died.
240                    {
241                       controllable->fire(0);//kill the rocket
242                       this->setPreviousMode();//get out of rocket mode
243                    }
244                }
245                else
246                    this->setPreviousMode();//no rocket entity -> get out of rocket mode
247            }
248            else
249                this->setPreviousMode();//If bot dies -> getControllableEntity == NULL -> get out of ROCKET mode
250        }//END_OF ROCKET MODE
251
252        SUPER(AIController, tick, dt);
253    }
254//**********************************************NEW
255    void AIController::defaultBehaviour(float maxrand)
256    {       float random;
257            // search enemy
258            random = rnd(maxrand);
259            if (random < (botlevel_* 100) && (!this->target_))
260                this->searchNewTarget();
261
262            // forget enemy
263            random = rnd(maxrand);
264            if (random < ((1-botlevel_)*20) && (this->target_))
265                this->forgetTarget();
266
267            // next enemy
268            random = rnd(maxrand);
269            if (random < (botlevel_*30) && (this->target_))
270                this->searchNewTarget();
271
272            // fly somewhere
273            random = rnd(maxrand);
274            if (random < 50 && (!this->bHasTargetPosition_ && !this->target_))
275                this->searchRandomTargetPosition();
276
277            // stop flying
278            random = rnd(maxrand);
279            if (random < 10 && (this->bHasTargetPosition_ && !this->target_))
280                this->bHasTargetPosition_ = false;
281
282            // fly somewhere else
283            random = rnd(maxrand);
284            if (random < 30 && (this->bHasTargetPosition_ && !this->target_))
285                this->searchRandomTargetPosition();
286
287            if (this->state_ == MASTER) // master: shoot
288            {
289                random = rnd(maxrand);
290                if (!(this->passive_) && random < (100*botlevel_) && (this->target_ && !this->bShooting_))
291                {
292                    this->bShooting_ = true;
293                    this->forceFreeSlaves();
294                }
295            }
296            else
297            {
298                // shoot
299                random = rnd(maxrand);
300                if (!(this->passive_) && random < (botlevel_*100) && (this->target_ && !this->bShooting_))
301                    this->bShooting_ = true;
302            }
303
304            // stop shooting
305            random = rnd(maxrand);
306            if (random < ((1 - botlevel_)*50) && (this->bShooting_))
307                this->bShooting_ = false;
308
309            // boost
310            random = rnd(maxrand);
311            if (random < botlevel_*50 )
312                this->boostControl();
313
314            // update Checkpoints
315            /*random = rnd(maxrand);
316            if (this->defaultWaypoint_ && random > (maxrand-10))
317                this->manageWaypoints();
318            else //if(random > maxrand-10) //CHECK USABILITY!!*/
319            if (this->waypoints_.size() == 0 )
320                this->manageWaypoints();
321    }
322
323}
Note: See TracBrowser for help on using the repository browser.