Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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