Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2361 was 2361, checked in by landauf, 15 years ago
  • Fixed a problem with SUPER in combination with a pure-virtual base-function when called from a direct child of the base-class.
  • Added random number generator initialization to Core (configurable)
  • Fixed a bug in Convert.h
  • Property svn:eol-style set to native
File size: 7.5 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() && (!it->first->isReadyToSpawn() || !this->bStarted_))
172            {
173                SpawnPoint* spawn = this->getBestSpawnPoint(it->first);
174                if (spawn)
175                {
176                    // force spawn at spawnpoint with default pawn
177                    ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
178                    spawn->spawn(entity);
179                    it->first->startControl(entity);
180                    it->second = PlayerState::Dead;
181                }
182                else
183                {
184                    COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
185                    abort();
186                }
187            }
188        }
189    }
190
191    void Gametype::checkStart()
192    {
193        if (!this->bStarted_)
194        {
195            if (this->bStartCountdownRunning_)
196            {
197                if (this->startCountdown_ <= 0)
198                {
199                    this->bStartCountdownRunning_ = false;
200                    this->startCountdown_ = 0;
201                    this->start();
202                }
203            }
204            else if (this->players_.size() > 0)
205            {
206                if (this->bAutoStart_)
207                {
208                    this->start();
209                }
210                else
211                {
212                    bool allplayersready = true;
213                    for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
214                    {
215                        if (!it->first->isReadyToSpawn())
216                            allplayersready = false;
217                    }
218                    if (allplayersready)
219                    {
220                        this->startCountdown_ = this->initialStartCountdown_;
221                        this->bStartCountdownRunning_ = true;
222                    }
223                }
224            }
225        }
226    }
227
228    void Gametype::spawnPlayersIfRequested()
229    {
230        for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
231            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
232                this->spawnPlayer(it->first);
233    }
234
235    void Gametype::spawnDeadPlayersIfRequested()
236    {
237        for (std::map<PlayerInfo*, PlayerState::Enum>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
238            if (it->second == PlayerState::Dead)
239                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
240                    this->spawnPlayer(it->first);
241    }
242
243    void Gametype::spawnPlayer(PlayerInfo* player)
244    {
245        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
246        if (spawnpoint)
247        {
248            player->startControl(spawnpoint->spawn());
249            this->players_[player] = PlayerState::Alive;
250        }
251        else
252        {
253            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
254            abort();
255        }
256    }
257}
Note: See TracBrowser for help on using the repository browser.