Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/objects/gametypes/Gametype.cc @ 3049

Last change on this file since 3049 was 3038, checked in by landauf, 15 years ago

Cleaned up setPlayer/removePlayer interface between PlayerInfo and ControllableEntity. The whole control is now up to the PlayerInfo, the respective functions in ControllableEntity are now protected.

  • Property svn:eol-style set to native
File size: 13.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 "OrxonoxStableHeaders.h"
30#include "Gametype.h"
31
32#include <cstdlib>
33#include <ctime>
34
35#include "core/CoreIncludes.h"
36#include "core/ConfigValueIncludes.h"
37#include "core/Template.h"
38#include "core/GameMode.h"
39#include "overlays/OverlayGroup.h"
40#include "objects/infos/PlayerInfo.h"
41#include "objects/infos/Bot.h"
42#include "objects/worldentities/pawns/Spectator.h"
43#include "objects/worldentities/SpawnPoint.h"
44#include "objects/worldentities/Camera.h"
45
46namespace orxonox
47{
48    CreateUnloadableFactory(Gametype);
49
50    Gametype::Gametype(BaseObject* creator) : BaseObject(creator), gtinfo_(creator)
51    {
52        RegisterObject(Gametype);
53
54        this->setGametype(this);
55
56        this->defaultControllableEntity_ = Class(Spectator);
57
58        this->bAutoStart_ = false;
59        this->bForceSpawn_ = false;
60        this->numberOfBots_ = 0;
61
62        this->timeLimit_ = 0;
63        this->time_ = 0;
64        this->timerIsActive_ = false;
65
66        this->initialStartCountdown_ = 3;
67
68        this->setConfigValues();
69
70        // load the corresponding score board
71        if (GameMode::showsGraphics() && this->scoreboardTemplate_ != "")
72        {
73            this->scoreboard_ = new OverlayGroup(this);
74            this->scoreboard_->addTemplate(this->scoreboardTemplate_);
75            this->scoreboard_->setGametype(this);
76        }
77        else
78            this->scoreboard_ = 0;
79    }
80
81    void Gametype::setConfigValues()
82    {
83        SetConfigValue(initialStartCountdown_, 3.0f);
84        SetConfigValue(bAutoStart_, false);
85        SetConfigValue(bForceSpawn_, false);
86        SetConfigValue(numberOfBots_, 0);
87        SetConfigValue(scoreboardTemplate_, "defaultScoreboard");
88    }
89
90    void Gametype::tick(float dt)
91    {
92        SUPER(Gametype, tick, dt);
93
94        //count timer
95        if (timerIsActive_)
96        {
97            if (this->timeLimit_ == 0)
98                this->time_ += dt;
99            else
100                this->time_ -= dt;
101        }
102
103        if (this->gtinfo_.bStartCountdownRunning_ && !this->gtinfo_.bStarted_)
104            this->gtinfo_.startCountdown_ -= dt;
105
106        if (!this->gtinfo_.bStarted_)
107            this->checkStart();
108        else if (!this->gtinfo_.bEnded_)
109            this->spawnDeadPlayersIfRequested();
110
111        this->assignDefaultPawnsIfNeeded();
112    }
113
114    void Gametype::start()
115    {
116        this->addBots(this->numberOfBots_);
117
118        this->gtinfo_.bStarted_ = true;
119
120        this->spawnPlayersIfRequested();
121    }
122
123    void Gametype::end()
124    {
125        this->gtinfo_.bEnded_ = true;
126
127        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
128        {
129            if (it->first->getControllableEntity())
130            {
131                ControllableEntity* oldentity = it->first->getControllableEntity();
132
133                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(oldentity->getCreator());
134                if (oldentity->getCamera())
135                {
136                    entity->setPosition(oldentity->getCamera()->getWorldPosition());
137                    entity->setOrientation(oldentity->getCamera()->getWorldOrientation());
138                }
139                else
140                {
141                    entity->setPosition(oldentity->getWorldPosition());
142                    entity->setOrientation(oldentity->getWorldOrientation());
143                }
144
145                it->first->startControl(entity);
146            }
147            else
148                this->spawnPlayerAsDefaultPawn(it->first);
149        }
150    }
151
152    void Gametype::playerEntered(PlayerInfo* player)
153    {
154        this->players_[player].state_ = PlayerState::Joined;
155    }
156
157    bool Gametype::playerLeft(PlayerInfo* player)
158    {
159        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
160        if (it != this->players_.end())
161        {
162            this->players_.erase(it);
163            return true;
164        }
165        return false;
166    }
167
168    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
169    {
170    }
171
172    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
173    {
174    }
175
176    bool Gametype::playerChangedName(PlayerInfo* player)
177    {
178        if (this->players_.find(player) != this->players_.end())
179        {
180            if (player->getName() != player->getOldName())
181            {
182                return true;
183            }
184        }
185        return false;
186    }
187
188    void Gametype::pawnPreSpawn(Pawn* pawn)
189    {
190    }
191
192    void Gametype::pawnPostSpawn(Pawn* pawn)
193    {
194    }
195
196    void Gametype::playerPreSpawn(PlayerInfo* player)
197    {
198    }
199
200    void Gametype::playerPostSpawn(PlayerInfo* player)
201    {
202    }
203
204    void Gametype::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
205    {
206    }
207
208    void Gametype::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
209    {
210    }
211
212    bool Gametype::allowPawnHit(Pawn* victim, Pawn* originator)
213    {
214        return true;
215    }
216
217    bool Gametype::allowPawnDamage(Pawn* victim, Pawn* originator)
218    {
219        return true;
220    }
221
222    bool Gametype::allowPawnDeath(Pawn* victim, Pawn* originator)
223    {
224        return true;
225    }
226
227    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
228    {
229        if (victim && victim->getPlayer())
230        {
231            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(victim->getPlayer());
232            if (it != this->players_.end())
233            {
234                it->second.state_ = PlayerState::Dead;
235                it->second.killed_++;
236
237                // Reward killer
238                if (killer)
239                {
240                    std::map<PlayerInfo*, Player>::iterator it = this->players_.find(killer->getPlayer());
241                    if (it != this->players_.end())
242                        it->second.frags_++;
243                }
244
245                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
246                if (victim->getCamera())
247                {
248                    entity->setPosition(victim->getCamera()->getWorldPosition());
249                    entity->setOrientation(victim->getCamera()->getWorldOrientation());
250                }
251                else
252                {
253                    entity->setPosition(victim->getWorldPosition());
254                    entity->setOrientation(victim->getWorldOrientation());
255                }
256                it->first->startControl(entity);
257            }
258            else
259                COUT(2) << "Warning: Killed Pawn was not in the playerlist" << std::endl;
260        }
261    }
262
263    void Gametype::playerScored(PlayerInfo* player)
264    {
265        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
266        if (it != this->players_.end())
267            it->second.frags_++;
268    }
269
270    int Gametype::getScore(PlayerInfo* player) const
271    {
272        std::map<PlayerInfo*, Player>::const_iterator it = this->players_.find(player);
273        if (it != this->players_.end())
274            return it->second.frags_;
275        else
276            return 0;
277    }
278
279    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
280    {
281        if (this->spawnpoints_.size() > 0)
282        {
283            unsigned int randomspawn = (unsigned int)rnd(this->spawnpoints_.size());
284            unsigned int index = 0;
285            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
286            {
287                if (index == randomspawn)
288                    return (*it);
289
290                ++index;
291            }
292        }
293        return 0;
294    }
295
296    void Gametype::assignDefaultPawnsIfNeeded()
297    {
298        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
299        {
300            if (!it->first->getControllableEntity())
301            {
302                it->second.state_ = PlayerState::Dead;
303
304                if (!it->first->isReadyToSpawn() || !this->gtinfo_.bStarted_)
305                {
306                    this->spawnPlayerAsDefaultPawn(it->first);
307                    it->second.state_ = PlayerState::Dead;
308                }
309            }
310        }
311    }
312
313    void Gametype::checkStart()
314    {
315        if (!this->gtinfo_.bStarted_)
316        {
317            if (this->gtinfo_.bStartCountdownRunning_)
318            {
319                if (this->gtinfo_.startCountdown_ <= 0)
320                {
321                    this->gtinfo_.bStartCountdownRunning_ = false;
322                    this->gtinfo_.startCountdown_ = 0;
323                    this->start();
324                }
325            }
326            else if (this->players_.size() > 0)
327            {
328                if (this->bAutoStart_)
329                {
330                    this->start();
331                }
332                else
333                {
334                    bool allplayersready = true;
335                    bool hashumanplayers = false;
336                    for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
337                    {
338                        if (!it->first->isReadyToSpawn())
339                            allplayersready = false;
340                        if (it->first->isHumanPlayer())
341                            hashumanplayers = true;
342                    }
343                    if (allplayersready && hashumanplayers)
344                    {
345                        this->gtinfo_.startCountdown_ = this->initialStartCountdown_;
346                        this->gtinfo_.bStartCountdownRunning_ = true;
347                    }
348                }
349            }
350        }
351    }
352
353    void Gametype::spawnPlayersIfRequested()
354    {
355        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
356            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
357                this->spawnPlayer(it->first);
358    }
359
360    void Gametype::spawnDeadPlayersIfRequested()
361    {
362        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
363            if (it->second.state_ == PlayerState::Dead)
364                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
365                    this->spawnPlayer(it->first);
366    }
367
368    void Gametype::spawnPlayer(PlayerInfo* player)
369    {
370        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
371        if (spawnpoint)
372        {
373            this->playerPreSpawn(player);
374            player->startControl(spawnpoint->spawn());
375            this->players_[player].state_ = PlayerState::Alive;
376            this->playerPostSpawn(player);
377        }
378        else
379        {
380            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
381            abort();
382        }
383    }
384
385    void Gametype::spawnPlayerAsDefaultPawn(PlayerInfo* player)
386    {
387        SpawnPoint* spawn = this->getBestSpawnPoint(player);
388        if (spawn)
389        {
390            // force spawn at spawnpoint with default pawn
391            ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
392            spawn->spawn(entity);
393            player->startControl(entity);
394        }
395        else
396        {
397            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
398            abort();
399        }
400    }
401
402    void Gametype::addBots(unsigned int amount)
403    {
404        for (unsigned int i = 0; i < amount; ++i)
405            this->botclass_.fabricate(this);
406    }
407
408    void Gametype::killBots(unsigned int amount)
409    {
410        unsigned int i = 0;
411        for (ObjectList<Bot>::iterator it = ObjectList<Bot>::begin(); (it != ObjectList<Bot>::end()) && ((amount == 0) || (i < amount)); )
412        {
413            if (it->getGametype() == this)
414            {
415                delete (*(it++));
416                ++i;
417            }
418        }
419    }
420
421    void Gametype::addTime(float t)
422    {
423        if (this->timeLimit_ == 0)
424          this->time_ -= t;
425        else
426          this->time_ += t;
427    }
428
429    void Gametype::removeTime(float t)
430    {
431        if (this->timeLimit_ == 0)
432          this->time_ += t;
433        else
434          this->time_ -= t;
435    }
436
437    void Gametype::resetTimer()
438    {
439        this->resetTimer(timeLimit_);
440    }
441
442    void Gametype::resetTimer(float t)
443    {
444        this->timeLimit_ = t;
445        this->time_ = t;
446    }
447}
Note: See TracBrowser for help on using the repository browser.