Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/orxonox/gametypes/Gametype.cc @ 8631

Last change on this file since 8631 was 8631, checked in by dafrick, 13 years ago

Merging spacerace branch into presentation branch.

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