Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy2/src/orxonox/objects/gametypes/Gametype.cc @ 2378

Last change on this file since 2378 was 2369, checked in by landauf, 16 years ago
  • Added a health bar
  • Some changes in CameraManager to handle the case when no camera exists after removing the last one, but this is still somehow buggy (freezes and later crashes reproducible but inexplicable after a few respawns)
  • Added PawnManager to handle destruction of Pawns without using delete within tick()
  • Property svn:eol-style set to native
File size: 7.9 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 "objects/infos/PlayerInfo.h"
37#include "objects/worldentities/pawns/Spectator.h"
38#include "objects/worldentities/SpawnPoint.h"
39
40#include "network/Host.h"
41
42namespace orxonox
43{
44    CreateUnloadableFactory(Gametype);
45
46    Gametype::Gametype(BaseObject* creator) : BaseObject(creator)
47    {
48        RegisterObject(Gametype);
49
50        this->defaultControllableEntity_ = Class(Spectator);
51
52        this->bStarted_ = false;
53        this->bEnded_ = false;
54        this->bAutoStart_ = false;
55        this->bForceSpawn_ = false;
56
57        this->initialStartCountdown_ = 3;
58        this->startCountdown_ = 0;
59        this->bStartCountdownRunning_ = false;
60    }
61
62    void Gametype::tick(float dt)
63    {
64        SUPER(Gametype, tick, dt);
65
66        if (this->bStartCountdownRunning_ && !this->bStarted_)
67            this->startCountdown_ -= dt;
68
69        if (!this->bStarted_)
70            this->checkStart();
71        else
72            this->spawnDeadPlayersIfRequested();
73
74        this->assignDefaultPawnsIfNeeded();
75    }
76
77    void Gametype::start()
78    {
79        COUT(0) << "game started" << std::endl;
80        this->bStarted_ = true;
81
82        this->spawnPlayersIfRequested();
83    }
84
85    void Gametype::end()
86    {
87        COUT(0) << "game ended" << std::endl;
88        this->bEnded_ = true;
89    }
90
91    void Gametype::playerEntered(PlayerInfo* player)
92    {
93        this->players_[player] = PlayerState::Joined;
94
95        std::string message = player->getName() + " entered the game";
96        COUT(0) << message << std::endl;
97        Host::Broadcast(message);
98    }
99
100    void Gametype::playerLeft(PlayerInfo* player)
101    {
102        std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.find(player);
103        if (it != this->players_.end())
104        {
105            this->players_.erase(it);
106
107            std::string message = player->getName() + " left the game";
108            COUT(0) << message << std::endl;
109            Host::Broadcast(message);
110        }
111    }
112
113    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
114    {
115    }
116
117    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
118    {
119    }
120
121    void Gametype::playerChangedName(PlayerInfo* player)
122    {
123        if (this->players_.find(player) != this->players_.end())
124        {
125            if (player->getName() != player->getOldName())
126            {
127                std::string message = player->getOldName() + " changed name to " + player->getName();
128                COUT(0) << message << std::endl;
129                Host::Broadcast(message);
130            }
131        }
132    }
133
134    void Gametype::pawnPreSpawn(Pawn* pawn)
135    {
136    }
137
138    void Gametype::pawnPostSpawn(Pawn* pawn)
139    {
140    }
141
142    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
143    {
144    }
145
146    void Gametype::playerScored(PlayerInfo* player)
147    {
148    }
149
150    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
151    {
152        if (this->spawnpoints_.size() > 0)
153        {
154            unsigned int randomspawn = (unsigned int)rnd(this->spawnpoints_.size());
155            unsigned int index = 0;
156            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
157            {
158                if (index == randomspawn)
159                    return (*it);
160
161                ++index;
162            }
163        }
164        return 0;
165    }
166
167    void Gametype::assignDefaultPawnsIfNeeded()
168    {
169        for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
170        {
171            if (!it->first->getControllableEntity())
172            {
173                it->second = PlayerState::Dead;
174
175                if (!it->first->isReadyToSpawn() || !this->bStarted_)
176                {
177                    SpawnPoint* spawn = this->getBestSpawnPoint(it->first);
178                    if (spawn)
179                    {
180                        // force spawn at spawnpoint with default pawn
181                        ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
182                        spawn->spawn(entity);
183                        it->first->startControl(entity);
184                        it->second = PlayerState::Dead;
185                    }
186                    else
187                    {
188                        COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
189                        abort();
190                    }
191                }
192            }
193        }
194    }
195
196    void Gametype::checkStart()
197    {
198        if (!this->bStarted_)
199        {
200            if (this->bStartCountdownRunning_)
201            {
202                if (this->startCountdown_ <= 0)
203                {
204                    this->bStartCountdownRunning_ = false;
205                    this->startCountdown_ = 0;
206                    this->start();
207                }
208            }
209            else if (this->players_.size() > 0)
210            {
211                if (this->bAutoStart_)
212                {
213                    this->start();
214                }
215                else
216                {
217                    bool allplayersready = true;
218                    bool hashumanplayers = false;
219                    for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
220                    {
221                        if (!it->first->isReadyToSpawn())
222                            allplayersready = false;
223                        if (it->first->isHumanPlayer())
224                            hashumanplayers = true;
225                    }
226                    if (allplayersready && hashumanplayers)
227                    {
228                        this->startCountdown_ = this->initialStartCountdown_;
229                        this->bStartCountdownRunning_ = true;
230                    }
231                }
232            }
233        }
234    }
235
236    void Gametype::spawnPlayersIfRequested()
237    {
238        for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
239            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
240                this->spawnPlayer(it->first);
241    }
242
243    void Gametype::spawnDeadPlayersIfRequested()
244    {
245        for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
246            if (it->second == PlayerState::Dead)
247                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
248                    this->spawnPlayer(it->first);
249    }
250
251    void Gametype::spawnPlayer(PlayerInfo* player)
252    {
253        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
254        if (spawnpoint)
255        {
256            player->startControl(spawnpoint->spawn());
257            this->players_[player] = PlayerState::Alive;
258        }
259        else
260        {
261            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
262            abort();
263        }
264    }
265}
Note: See TracBrowser for help on using the repository browser.