Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/miniprojects/src/orxonox/objects/gametypes/Gametype.cc @ 2818

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

added two new functions to Gametype

  • Property svn:eol-style set to native
File size: 12.1 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/Core.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        // load the corresponding score board
69        if (Core::showsGraphics() && this->scoreboardTemplate_ != "")
70        {
71            this->scoreboard_ = new OverlayGroup(this);
72            this->scoreboard_->addTemplate(this->scoreboardTemplate_);
73            this->scoreboard_->setGametype(this);
74        }
75        else
76            this->scoreboard_ = 0;
77    }
78
79    void Gametype::setConfigValues()
80    {
81        SetConfigValue(initialStartCountdown_, 3.0f);
82        SetConfigValue(bAutoStart_, false);
83        SetConfigValue(bForceSpawn_, false);
84        SetConfigValue(numberOfBots_, 0);
85        SetConfigValue(scoreboardTemplate_, "defaultScoreboard");
86    }
87
88    void Gametype::tick(float dt)
89    {
90        SUPER(Gametype, tick, dt);
91
92        if (this->gtinfo_.bStartCountdownRunning_ && !this->gtinfo_.bStarted_)
93            this->gtinfo_.startCountdown_ -= dt;
94
95        if (!this->gtinfo_.bStarted_)
96            this->checkStart();
97        else
98            this->spawnDeadPlayersIfRequested();
99
100        this->assignDefaultPawnsIfNeeded();
101    }
102
103    void Gametype::start()
104    {
105        this->addBots(this->numberOfBots_);
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::playerPreSpawn(PlayerInfo* player)
171    {
172    }
173
174    void Gametype::playerPostSpawn(PlayerInfo* player)
175    {
176    }
177
178    void Gametype::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
179    {
180    }
181
182    void Gametype::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
183    {
184    }
185
186    bool Gametype::allowPawnHit(Pawn* victim, Pawn* originator)
187    {
188        return true;
189    }
190
191    bool Gametype::allowPawnDamage(Pawn* victim, Pawn* originator)
192    {
193        return true;
194    }
195
196    bool Gametype::allowPawnDeath(Pawn* victim, Pawn* originator)
197    {
198        return true;
199    }
200
201    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
202    {
203        if (victim && victim->getPlayer())
204        {
205            std::string message;
206            if (killer)
207            {
208                if (killer->getPlayer())
209                    message = victim->getPlayer()->getName() + " was killed by " + killer->getPlayer()->getName();
210                else
211                    message = victim->getPlayer()->getName() + " was killed";
212            }
213            else
214                message = victim->getPlayer()->getName() + " died";
215
216            COUT(0) << message << std::endl;
217            Host::Broadcast(message);
218        }
219
220        if (victim && victim->getPlayer())
221        {
222            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(victim->getPlayer());
223            if (it != this->players_.end())
224            {
225                it->second.state_ = PlayerState::Dead;
226                it->second.killed_++;
227
228                // Reward killer
229                if (killer)
230                {
231                    std::map<PlayerInfo*, Player>::iterator itKiller = this->players_.find(killer->getPlayer());
232                    if (itKiller != this->players_.end())
233                    {
234                        this->playerScored(itKiller->second);
235                    }
236                    else
237                        COUT(2) << "Warning: Killing Pawn was not in the playerlist" << std::endl;
238                }
239
240                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
241                if (victim->getCamera())
242                {
243                    entity->setPosition(victim->getCamera()->getWorldPosition());
244                    entity->setOrientation(victim->getCamera()->getWorldOrientation());
245                }
246                else
247                {
248                    entity->setPosition(victim->getWorldPosition());
249                    entity->setOrientation(victim->getWorldOrientation());
250                }
251                it->first->startControl(entity);
252            }
253            else
254                COUT(2) << "Warning: Killed Pawn was not in the playerlist" << std::endl;
255        }
256    }
257
258    void Gametype::playerScored(Player& player)
259    {
260        player.frags_++;
261    }
262
263    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
264    {
265        if (this->spawnpoints_.size() > 0)
266        {
267            unsigned int randomspawn = (unsigned int)rnd(this->spawnpoints_.size());
268            unsigned int index = 0;
269            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
270            {
271                if (index == randomspawn)
272                    return (*it);
273
274                ++index;
275            }
276        }
277        return 0;
278    }
279
280    void Gametype::assignDefaultPawnsIfNeeded()
281    {
282        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
283        {
284            if (!it->first->getControllableEntity())
285            {
286                it->second.state_ = PlayerState::Dead;
287
288                if (!it->first->isReadyToSpawn() || !this->gtinfo_.bStarted_)
289                {
290                    SpawnPoint* spawn = this->getBestSpawnPoint(it->first);
291                    if (spawn)
292                    {
293                        // force spawn at spawnpoint with default pawn
294                        ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
295                        spawn->spawn(entity);
296                        it->first->startControl(entity);
297                        it->second.state_ = PlayerState::Dead;
298                    }
299                    else
300                    {
301                        COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
302                        abort();
303                    }
304                }
305            }
306        }
307    }
308
309    void Gametype::checkStart()
310    {
311        if (!this->gtinfo_.bStarted_)
312        {
313            if (this->gtinfo_.bStartCountdownRunning_)
314            {
315                if (this->gtinfo_.startCountdown_ <= 0)
316                {
317                    this->gtinfo_.bStartCountdownRunning_ = false;
318                    this->gtinfo_.startCountdown_ = 0;
319                    this->start();
320                }
321            }
322            else if (this->players_.size() > 0)
323            {
324                if (this->bAutoStart_)
325                {
326                    this->start();
327                }
328                else
329                {
330                    bool allplayersready = true;
331                    bool hashumanplayers = false;
332                    for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
333                    {
334                        if (!it->first->isReadyToSpawn())
335                            allplayersready = false;
336                        if (it->first->isHumanPlayer())
337                            hashumanplayers = true;
338                    }
339                    if (allplayersready && hashumanplayers)
340                    {
341                        this->gtinfo_.startCountdown_ = this->initialStartCountdown_;
342                        this->gtinfo_.bStartCountdownRunning_ = true;
343                    }
344                }
345            }
346        }
347    }
348
349    void Gametype::spawnPlayersIfRequested()
350    {
351        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
352            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
353                this->spawnPlayer(it->first);
354    }
355
356    void Gametype::spawnDeadPlayersIfRequested()
357    {
358        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
359            if (it->second.state_ == PlayerState::Dead)
360                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
361                    this->spawnPlayer(it->first);
362    }
363
364    void Gametype::spawnPlayer(PlayerInfo* player)
365    {
366        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
367        if (spawnpoint)
368        {
369            this->playerPreSpawn(player);
370            player->startControl(spawnpoint->spawn());
371            this->players_[player].state_ = PlayerState::Alive;
372            this->playerPostSpawn(player);
373        }
374        else
375        {
376            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
377            abort();
378        }
379    }
380
381    void Gametype::addBots(unsigned int amount)
382    {
383        for (unsigned int i = 0; i < amount; ++i)
384            new Bot(this);
385    }
386
387    void Gametype::killBots(unsigned int amount)
388    {
389        unsigned int i = 0;
390        for (ObjectList<Bot>::iterator it = ObjectList<Bot>::begin(); (it != ObjectList<Bot>::end()) && ((amount == 0) || (i < amount)); )
391        {
392            if (it->getGametype() == this)
393            {
394                delete (*(it++));
395                ++i;
396            }
397        }
398    }
399}
Note: See TracBrowser for help on using the repository browser.