Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gui/src/orxonox/objects/gametypes/Gametype.cc @ 2848

Last change on this file since 2848 was 2848, checked in by rgrieder, 15 years ago

Exported showsGraphics, etc. to a new class named GameMode in the core.

  • Property svn:eol-style set to native
File size: 11.4 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
46#include "network/Host.h"
47
48namespace orxonox
49{
50    CreateUnloadableFactory(Gametype);
51
52    Gametype::Gametype(BaseObject* creator) : BaseObject(creator), gtinfo_(creator)
53    {
54        RegisterObject(Gametype);
55
56        this->setGametype(this);
57
58        this->defaultControllableEntity_ = Class(Spectator);
59
60        this->bAutoStart_ = false;
61        this->bForceSpawn_ = false;
62        this->numberOfBots_ = 0;
63
64        this->initialStartCountdown_ = 3;
65
66        this->setConfigValues();
67
68        this->addBots(this->numberOfBots_);
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        if (this->gtinfo_.bStartCountdownRunning_ && !this->gtinfo_.bStarted_)
95            this->gtinfo_.startCountdown_ -= dt;
96
97        if (!this->gtinfo_.bStarted_)
98            this->checkStart();
99        else
100            this->spawnDeadPlayersIfRequested();
101
102        this->assignDefaultPawnsIfNeeded();
103    }
104
105    void Gametype::start()
106    {
107        COUT(0) << "game started" << std::endl;
108        this->gtinfo_.bStarted_ = true;
109
110        this->spawnPlayersIfRequested();
111    }
112
113    void Gametype::end()
114    {
115        COUT(0) << "game ended" << std::endl;
116        this->gtinfo_.bEnded_ = true;
117    }
118
119    void Gametype::playerEntered(PlayerInfo* player)
120    {
121        this->players_[player].state_ = PlayerState::Joined;
122
123        std::string message = player->getName() + " entered the game";
124        COUT(0) << message << std::endl;
125        Host::Broadcast(message);
126    }
127
128    void Gametype::playerLeft(PlayerInfo* player)
129    {
130        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
131        if (it != this->players_.end())
132        {
133            this->players_.erase(it);
134
135            std::string message = player->getName() + " left the game";
136            COUT(0) << message << std::endl;
137            Host::Broadcast(message);
138        }
139    }
140
141    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
142    {
143    }
144
145    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
146    {
147    }
148
149    void Gametype::playerChangedName(PlayerInfo* player)
150    {
151        if (this->players_.find(player) != this->players_.end())
152        {
153            if (player->getName() != player->getOldName())
154            {
155                std::string message = player->getOldName() + " changed name to " + player->getName();
156                COUT(0) << message << std::endl;
157                Host::Broadcast(message);
158            }
159        }
160    }
161
162    void Gametype::pawnPreSpawn(Pawn* pawn)
163    {
164    }
165
166    void Gametype::pawnPostSpawn(Pawn* pawn)
167    {
168    }
169
170    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
171    {
172        if (victim && victim->getPlayer())
173        {
174            std::string message;
175            if (killer)
176            {
177                if (killer->getPlayer())
178                    message = victim->getPlayer()->getName() + " was killed by " + killer->getPlayer()->getName();
179                else
180                    message = victim->getPlayer()->getName() + " was killed";
181            }
182            else
183                message = victim->getPlayer()->getName() + " died";
184
185            COUT(0) << message << std::endl;
186            Host::Broadcast(message);
187        }
188
189        if (victim && victim->getPlayer())
190        {
191            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(victim->getPlayer());
192            if (it != this->players_.end())
193            {
194                it->second.state_ = PlayerState::Dead;
195                it->second.killed_++;
196
197                // Reward killer
198                if (killer)
199                {
200                    std::map<PlayerInfo*, Player>::iterator itKiller = this->players_.find(killer->getPlayer());
201                    if (itKiller != this->players_.end())
202                    {
203                        this->playerScored(itKiller->second);
204                    }
205                    else
206                        COUT(2) << "Warning: Killing Pawn was not in the playerlist" << std::endl;
207                }
208
209                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
210                if (victim->getCamera())
211                {
212                    entity->setPosition(victim->getCamera()->getWorldPosition());
213                    entity->setOrientation(victim->getCamera()->getWorldOrientation());
214                }
215                else
216                {
217                    entity->setPosition(victim->getWorldPosition());
218                    entity->setOrientation(victim->getWorldOrientation());
219                }
220                it->first->startControl(entity);
221            }
222            else
223                COUT(2) << "Warning: Killed Pawn was not in the playerlist" << std::endl;
224        }
225    }
226
227    void Gametype::playerScored(Player& player)
228    {
229        player.frags_++;
230    }
231
232    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
233    {
234        if (this->spawnpoints_.size() > 0)
235        {
236            unsigned int randomspawn = (unsigned int)rnd(this->spawnpoints_.size());
237            unsigned int index = 0;
238            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
239            {
240                if (index == randomspawn)
241                    return (*it);
242
243                ++index;
244            }
245        }
246        return 0;
247    }
248
249    void Gametype::assignDefaultPawnsIfNeeded()
250    {
251        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
252        {
253            if (!it->first->getControllableEntity())
254            {
255                it->second.state_ = PlayerState::Dead;
256
257                if (!it->first->isReadyToSpawn() || !this->gtinfo_.bStarted_)
258                {
259                    SpawnPoint* spawn = this->getBestSpawnPoint(it->first);
260                    if (spawn)
261                    {
262                        // force spawn at spawnpoint with default pawn
263                        ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
264                        spawn->spawn(entity);
265                        it->first->startControl(entity);
266                        it->second.state_ = PlayerState::Dead;
267                    }
268                    else
269                    {
270                        COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
271                        abort();
272                    }
273                }
274            }
275        }
276    }
277
278    void Gametype::checkStart()
279    {
280        if (!this->gtinfo_.bStarted_)
281        {
282            if (this->gtinfo_.bStartCountdownRunning_)
283            {
284                if (this->gtinfo_.startCountdown_ <= 0)
285                {
286                    this->gtinfo_.bStartCountdownRunning_ = false;
287                    this->gtinfo_.startCountdown_ = 0;
288                    this->start();
289                }
290            }
291            else if (this->players_.size() > 0)
292            {
293                if (this->bAutoStart_)
294                {
295                    this->start();
296                }
297                else
298                {
299                    bool allplayersready = true;
300                    bool hashumanplayers = false;
301                    for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
302                    {
303                        if (!it->first->isReadyToSpawn())
304                            allplayersready = false;
305                        if (it->first->isHumanPlayer())
306                            hashumanplayers = true;
307                    }
308                    if (allplayersready && hashumanplayers)
309                    {
310                        this->gtinfo_.startCountdown_ = this->initialStartCountdown_;
311                        this->gtinfo_.bStartCountdownRunning_ = true;
312                    }
313                }
314            }
315        }
316    }
317
318    void Gametype::spawnPlayersIfRequested()
319    {
320        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
321            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
322                this->spawnPlayer(it->first);
323    }
324
325    void Gametype::spawnDeadPlayersIfRequested()
326    {
327        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
328            if (it->second.state_ == PlayerState::Dead)
329                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
330                    this->spawnPlayer(it->first);
331    }
332
333    void Gametype::spawnPlayer(PlayerInfo* player)
334    {
335        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
336        if (spawnpoint)
337        {
338            player->startControl(spawnpoint->spawn());
339            this->players_[player].state_ = PlayerState::Alive;
340        }
341        else
342        {
343            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
344            abort();
345        }
346    }
347
348    void Gametype::addBots(unsigned int amount)
349    {
350        for (unsigned int i = 0; i < amount; ++i)
351            new Bot(this);
352    }
353
354    void Gametype::killBots(unsigned int amount)
355    {
356        unsigned int i = 0;
357        for (ObjectList<Bot>::iterator it = ObjectList<Bot>::begin(); (it != ObjectList<Bot>::end()) && ((amount == 0) || (i < amount)); )
358        {
359            if (it->getGametype() == this)
360            {
361                delete (*(it++));
362                ++i;
363            }
364        }
365    }
366}
Note: See TracBrowser for help on using the repository browser.