Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gamecontent/src/orxonox/controllers/AIController.cc @ 8923

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

Tutorial level enhancements (quest work, better texts are still needed), reverted old rocket hack, reworked configurable botlevel for the ai.

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