Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/gametypes/Gametype.cc @ 7496

Last change on this file since 7496 was 7284, checked in by landauf, 14 years ago

merged consolecommands3 branch back to trunk.

note: the console command interface has changed completely, but the documentation is not yet up to date. just copy an existing command and change it to your needs, it's pretty self-explanatory. also the include files related to console commands are now located in core/command/. in the game it should work exactly like before, except for some changes in the auto-completion.

  • Property svn:eol-style set to native
File size: 14.4 KB
RevLine 
[2072]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 "Gametype.h"
30
[3196]31#include "util/Math.h"
[2072]32#include "core/CoreIncludes.h"
[2662]33#include "core/ConfigValueIncludes.h"
[2896]34#include "core/GameMode.h"
[7284]35#include "core/command/ConsoleCommand.h"
[3196]36
[5735]37#include "infos/PlayerInfo.h"
38#include "infos/Bot.h"
[5737]39#include "graphics/Camera.h"
[5735]40#include "worldentities/ControllableEntity.h"
41#include "worldentities/SpawnPoint.h"
42#include "worldentities/pawns/Spectator.h"
43#include "worldentities/pawns/Pawn.h"
[3196]44#include "overlays/OverlayGroup.h"
[2072]45
46namespace orxonox
47{
48    CreateUnloadableFactory(Gametype);
49
[5929]50    Gametype::Gametype(BaseObject* creator) : BaseObject(creator)
[2072]51    {
52        RegisterObject(Gametype);
[6417]53
[5929]54        this->gtinfo_ = new GametypeInfo(creator);
[2072]55
[5929]56        this->setGametype(SmartPtr<Gametype>(this, false));
[2662]57
[2072]58        this->defaultControllableEntity_ = Class(Spectator);
59
60        this->bAutoStart_ = false;
61        this->bForceSpawn_ = false;
[2662]62        this->numberOfBots_ = 0;
[2072]63
[3033]64        this->timeLimit_ = 0;
65        this->time_ = 0;
66        this->timerIsActive_ = false;
67
[2072]68        this->initialStartCountdown_ = 3;
[2662]69
70        this->setConfigValues();
71
72        // load the corresponding score board
[6417]73        if (GameMode::showsGraphics() && !this->scoreboardTemplate_.empty())
[2662]74        {
75            this->scoreboard_ = new OverlayGroup(this);
76            this->scoreboard_->addTemplate(this->scoreboardTemplate_);
77            this->scoreboard_->setGametype(this);
78        }
79        else
80            this->scoreboard_ = 0;
[2072]81    }
[6417]82
[5929]83    Gametype::~Gametype()
84    {
85        if (this->isInitialized())
86        {
87            this->gtinfo_->destroy();
88        }
89    }
[2072]90
[2662]91    void Gametype::setConfigValues()
92    {
93        SetConfigValue(initialStartCountdown_, 3.0f);
94        SetConfigValue(bAutoStart_, false);
95        SetConfigValue(bForceSpawn_, false);
96        SetConfigValue(numberOfBots_, 0);
97        SetConfigValue(scoreboardTemplate_, "defaultScoreboard");
98    }
99
[2072]100    void Gametype::tick(float dt)
101    {
[2662]102        SUPER(Gametype, tick, dt);
[2072]103
[3033]104        //count timer
105        if (timerIsActive_)
106        {
107            if (this->timeLimit_ == 0)
108                this->time_ += dt;
109            else
110                this->time_ -= dt;
111        }
112
[5929]113        if (this->gtinfo_->bStartCountdownRunning_ && !this->gtinfo_->bStarted_)
114            this->gtinfo_->startCountdown_ -= dt;
[2662]115
[5929]116        if (!this->gtinfo_->bStarted_)
[2072]117            this->checkStart();
[5929]118        else if (!this->gtinfo_->bEnded_)
[2171]119            this->spawnDeadPlayersIfRequested();
[2072]120
121        this->assignDefaultPawnsIfNeeded();
122    }
123
124    void Gametype::start()
125    {
[2826]126        this->addBots(this->numberOfBots_);
127
[5929]128        this->gtinfo_->bStarted_ = true;
[2072]129
130        this->spawnPlayersIfRequested();
131    }
132
133    void Gametype::end()
134    {
[5929]135        this->gtinfo_->bEnded_ = true;
[3033]136
137        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
138        {
139            if (it->first->getControllableEntity())
140            {
141                ControllableEntity* oldentity = it->first->getControllableEntity();
[3038]142
[5929]143                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(oldentity);
[3033]144                if (oldentity->getCamera())
145                {
146                    entity->setPosition(oldentity->getCamera()->getWorldPosition());
147                    entity->setOrientation(oldentity->getCamera()->getWorldOrientation());
148                }
149                else
150                {
151                    entity->setPosition(oldentity->getWorldPosition());
152                    entity->setOrientation(oldentity->getWorldOrientation());
153                }
154
155                it->first->startControl(entity);
156            }
157            else
158                this->spawnPlayerAsDefaultPawn(it->first);
159        }
[2072]160    }
161
162    void Gametype::playerEntered(PlayerInfo* player)
163    {
[2662]164        this->players_[player].state_ = PlayerState::Joined;
[2072]165    }
166
[2826]167    bool Gametype::playerLeft(PlayerInfo* player)
[2072]168    {
[2662]169        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
[2072]170        if (it != this->players_.end())
171        {
172            this->players_.erase(it);
[2826]173            return true;
[2072]174        }
[2826]175        return false;
[2072]176    }
177
178    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
179    {
180    }
181
182    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
183    {
184    }
185
[2826]186    bool Gametype::playerChangedName(PlayerInfo* player)
[2072]187    {
188        if (this->players_.find(player) != this->players_.end())
189        {
190            if (player->getName() != player->getOldName())
191            {
[2826]192                return true;
[2072]193            }
194        }
[2826]195        return false;
[2072]196    }
197
198    void Gametype::pawnPreSpawn(Pawn* pawn)
199    {
200    }
201
202    void Gametype::pawnPostSpawn(Pawn* pawn)
203    {
204    }
205
[2826]206    void Gametype::playerPreSpawn(PlayerInfo* player)
[2072]207    {
[2826]208    }
[2662]209
[2826]210    void Gametype::playerPostSpawn(PlayerInfo* player)
211    {
212    }
[2662]213
[2826]214    void Gametype::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
215    {
216    }
217
218    void Gametype::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
219    {
220    }
221
222    bool Gametype::allowPawnHit(Pawn* victim, Pawn* originator)
223    {
224        return true;
225    }
226
227    bool Gametype::allowPawnDamage(Pawn* victim, Pawn* originator)
228    {
229        return true;
230    }
231
232    bool Gametype::allowPawnDeath(Pawn* victim, Pawn* originator)
233    {
234        return true;
235    }
236
237    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
238    {
[2662]239        if (victim && victim->getPlayer())
240        {
241            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(victim->getPlayer());
242            if (it != this->players_.end())
243            {
244                it->second.state_ = PlayerState::Dead;
245                it->second.killed_++;
246
247                // Reward killer
[3099]248                if (killer && killer->getPlayer())
[2839]249                {
250                    std::map<PlayerInfo*, Player>::iterator it = this->players_.find(killer->getPlayer());
251                    if (it != this->players_.end())
[3099]252                    {
[2839]253                        it->second.frags_++;
[3099]254
255                        if (killer->getPlayer()->getClientID() != CLIENTID_UNKNOWN)
[5929]256                            this->gtinfo_->sendKillMessage("You killed " + victim->getPlayer()->getName(), killer->getPlayer()->getClientID());
[3099]257                        if (victim->getPlayer()->getClientID() != CLIENTID_UNKNOWN)
[5929]258                            this->gtinfo_->sendDeathMessage("You were killed by " + killer->getPlayer()->getName(), victim->getPlayer()->getClientID());
[3099]259                    }
[2839]260                }
[2662]261
262                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
263                if (victim->getCamera())
264                {
265                    entity->setPosition(victim->getCamera()->getWorldPosition());
266                    entity->setOrientation(victim->getCamera()->getWorldOrientation());
267                }
268                else
269                {
270                    entity->setPosition(victim->getWorldPosition());
271                    entity->setOrientation(victim->getWorldOrientation());
272                }
273                it->first->startControl(entity);
274            }
275            else
276                COUT(2) << "Warning: Killed Pawn was not in the playerlist" << std::endl;
277        }
[2072]278    }
279
[2826]280    void Gametype::playerScored(PlayerInfo* player)
[2072]281    {
[2826]282        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
283        if (it != this->players_.end())
284            it->second.frags_++;
[2072]285    }
286
[2890]287    int Gametype::getScore(PlayerInfo* player) const
288    {
289        std::map<PlayerInfo*, Player>::const_iterator it = this->players_.find(player);
290        if (it != this->players_.end())
291            return it->second.frags_;
292        else
293            return 0;
294    }
295
[2072]296    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
297    {
298        if (this->spawnpoints_.size() > 0)
299        {
[7163]300            SpawnPoint* fallbackSpawnPoint = NULL;
[3196]301            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
[2072]302            unsigned int index = 0;
[7163]303            std::set<SpawnPoint*> activeSpawnPoints = this->spawnpoints_;
[2072]304            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
305            {
306                if (index == randomspawn)
[7163]307                    fallbackSpawnPoint = (*it);
308
309                if (!(*it)->isActive())
310                    activeSpawnPoints.erase(*it);
311
312                ++index;
313            }
314
315            randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
316            index = 0;
317            for (std::set<SpawnPoint*>::const_iterator it = activeSpawnPoints.begin(); it != activeSpawnPoints.end(); ++it)
318            {
319                if (index == randomspawn)
[2072]320                    return (*it);
321
322                ++index;
323            }
[7163]324
325            return fallbackSpawnPoint;
[2072]326        }
327        return 0;
328    }
329
[2171]330    void Gametype::assignDefaultPawnsIfNeeded()
[2072]331    {
[2662]332        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
[2072]333        {
[2662]334            if (!it->first->getControllableEntity())
[2072]335            {
[2662]336                it->second.state_ = PlayerState::Dead;
337
[5929]338                if (!it->first->isReadyToSpawn() || !this->gtinfo_->bStarted_)
[2072]339                {
[3033]340                    this->spawnPlayerAsDefaultPawn(it->first);
341                    it->second.state_ = PlayerState::Dead;
[2072]342                }
343            }
344        }
345    }
346
347    void Gametype::checkStart()
348    {
[5929]349        if (!this->gtinfo_->bStarted_)
[2072]350        {
[5929]351            if (this->gtinfo_->bStartCountdownRunning_)
[2072]352            {
[5929]353                if (this->gtinfo_->startCountdown_ <= 0)
[2072]354                {
[5929]355                    this->gtinfo_->bStartCountdownRunning_ = false;
356                    this->gtinfo_->startCountdown_ = 0;
[2072]357                    this->start();
358                }
359            }
360            else if (this->players_.size() > 0)
361            {
362                if (this->bAutoStart_)
363                {
364                    this->start();
365                }
366                else
367                {
368                    bool allplayersready = true;
[2662]369                    bool hashumanplayers = false;
370                    for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
[2072]371                    {
[2171]372                        if (!it->first->isReadyToSpawn())
[2072]373                            allplayersready = false;
[2662]374                        if (it->first->isHumanPlayer())
375                            hashumanplayers = true;
[2072]376                    }
[2662]377                    if (allplayersready && hashumanplayers)
[2072]378                    {
[5929]379                        this->gtinfo_->startCountdown_ = this->initialStartCountdown_;
380                        this->gtinfo_->bStartCountdownRunning_ = true;
[2072]381                    }
382                }
383            }
384        }
385    }
386
387    void Gametype::spawnPlayersIfRequested()
388    {
[2662]389        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
[2171]390            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
391                this->spawnPlayer(it->first);
[2072]392    }
393
394    void Gametype::spawnDeadPlayersIfRequested()
395    {
[2662]396        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
397            if (it->second.state_ == PlayerState::Dead)
[2171]398                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
399                    this->spawnPlayer(it->first);
[2072]400    }
401
402    void Gametype::spawnPlayer(PlayerInfo* player)
403    {
404        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
405        if (spawnpoint)
406        {
[2826]407            this->playerPreSpawn(player);
[2072]408            player->startControl(spawnpoint->spawn());
[2662]409            this->players_[player].state_ = PlayerState::Alive;
[2826]410            this->playerPostSpawn(player);
[2072]411        }
412        else
413        {
414            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
415            abort();
416        }
417    }
[2662]418
[3033]419    void Gametype::spawnPlayerAsDefaultPawn(PlayerInfo* player)
420    {
421        SpawnPoint* spawn = this->getBestSpawnPoint(player);
422        if (spawn)
423        {
424            // force spawn at spawnpoint with default pawn
425            ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
426            spawn->spawn(entity);
427            player->startControl(entity);
428        }
429        else
430        {
431            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
432            abort();
433        }
434    }
435
[2662]436    void Gametype::addBots(unsigned int amount)
437    {
438        for (unsigned int i = 0; i < amount; ++i)
[2839]439            this->botclass_.fabricate(this);
[2662]440    }
441
442    void Gametype::killBots(unsigned int amount)
443    {
444        unsigned int i = 0;
445        for (ObjectList<Bot>::iterator it = ObjectList<Bot>::begin(); (it != ObjectList<Bot>::end()) && ((amount == 0) || (i < amount)); )
446        {
447            if (it->getGametype() == this)
448            {
[5929]449                (it++)->destroy();
[2662]450                ++i;
451            }
[5929]452            else
453                ++it;
[2662]454        }
455    }
[3033]456
457    void Gametype::addTime(float t)
[3038]458    {
[3033]459        if (this->timeLimit_ == 0)
460          this->time_ -= t;
461        else
462          this->time_ += t;
463    }
464
465    void Gametype::removeTime(float t)
[3038]466    {
[3033]467        if (this->timeLimit_ == 0)
468          this->time_ += t;
469        else
470          this->time_ -= t;
471    }
472
473    void Gametype::resetTimer()
[3038]474    {
[3033]475        this->resetTimer(timeLimit_);
476    }
477
478    void Gametype::resetTimer(float t)
[3038]479    {
[3033]480        this->timeLimit_ = t;
481        this->time_ = t;
482    }
[2072]483}
Note: See TracBrowser for help on using the repository browser.