Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 9048 was 9016, checked in by jo, 12 years ago

Merging presentation2011 branch to trunk. Please check for possible bugs.

  • Property svn:eol-style set to native
File size: 16.0 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
[8706]123        if (this->gtinfo_->isStartCountdownRunning() && !this->gtinfo_->hasStarted())
124            this->gtinfo_->countdownStartCountdown(dt);
[9016]125                       
[8706]126        if (!this->gtinfo_->hasStarted())
127        {
128            for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
129            {
130                // Inform the GametypeInfo that the player is ready to spawn.
131                if(it->first->isHumanPlayer() && it->first->isReadyToSpawn())
132                    this->gtinfo_->playerReadyToSpawn(it->first);
[9016]133                   
134               
[8706]135            }
[2072]136            this->checkStart();
[8706]137        }
138        else if (!this->gtinfo_->hasEnded())
[2171]139            this->spawnDeadPlayersIfRequested();
[2072]140
141        this->assignDefaultPawnsIfNeeded();
142    }
143
144    void Gametype::start()
145    {
[9016]146         
[2826]147        this->addBots(this->numberOfBots_);
148
[8706]149        this->gtinfo_->start();
[2072]150
151        this->spawnPlayersIfRequested();
[9016]152       
153       
[2072]154    }
155
156    void Gametype::end()
157    {
[8706]158        this->gtinfo_->end();
[3033]159
160        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
161        {
162            if (it->first->getControllableEntity())
163            {
164                ControllableEntity* oldentity = it->first->getControllableEntity();
[3038]165
[5929]166                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(oldentity);
[3033]167                if (oldentity->getCamera())
168                {
169                    entity->setPosition(oldentity->getCamera()->getWorldPosition());
170                    entity->setOrientation(oldentity->getCamera()->getWorldOrientation());
171                }
172                else
173                {
174                    entity->setPosition(oldentity->getWorldPosition());
175                    entity->setOrientation(oldentity->getWorldOrientation());
176                }
177
178                it->first->startControl(entity);
179            }
180            else
181                this->spawnPlayerAsDefaultPawn(it->first);
182        }
[2072]183    }
184
185    void Gametype::playerEntered(PlayerInfo* player)
186    {
[2662]187        this->players_[player].state_ = PlayerState::Joined;
[8706]188        this->gtinfo_->playerEntered(player);
[2072]189    }
190
[2826]191    bool Gametype::playerLeft(PlayerInfo* player)
[2072]192    {
[2662]193        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
[2072]194        if (it != this->players_.end())
195        {
196            this->players_.erase(it);
[2826]197            return true;
[2072]198        }
[2826]199        return false;
[2072]200    }
201
202    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
203    {
204    }
205
206    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
207    {
208    }
209
[2826]210    bool Gametype::playerChangedName(PlayerInfo* player)
[2072]211    {
212        if (this->players_.find(player) != this->players_.end())
213        {
214            if (player->getName() != player->getOldName())
215            {
[2826]216                return true;
[2072]217            }
218        }
[2826]219        return false;
[2072]220    }
221
222    void Gametype::pawnPreSpawn(Pawn* pawn)
223    {
224    }
225
226    void Gametype::pawnPostSpawn(Pawn* pawn)
227    {
228    }
229
[2826]230    void Gametype::playerPreSpawn(PlayerInfo* player)
[2072]231    {
[2826]232    }
[2662]233
[2826]234    void Gametype::playerPostSpawn(PlayerInfo* player)
235    {
236    }
[2662]237
[2826]238    void Gametype::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
239    {
240    }
241
242    void Gametype::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
243    {
244    }
245
246    bool Gametype::allowPawnHit(Pawn* victim, Pawn* originator)
247    {
248        return true;
249    }
250
251    bool Gametype::allowPawnDamage(Pawn* victim, Pawn* originator)
252    {
253        return true;
254    }
255
256    bool Gametype::allowPawnDeath(Pawn* victim, Pawn* originator)
257    {
258        return true;
259    }
260
261    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
262    {
[2662]263        if (victim && victim->getPlayer())
264        {
265            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(victim->getPlayer());
266            if (it != this->players_.end())
267            {
268                it->second.state_ = PlayerState::Dead;
269                it->second.killed_++;
270
271                // Reward killer
[3099]272                if (killer && killer->getPlayer())
[2839]273                {
274                    std::map<PlayerInfo*, Player>::iterator it = this->players_.find(killer->getPlayer());
275                    if (it != this->players_.end())
[3099]276                    {
[2839]277                        it->second.frags_++;
[3099]278
[8327]279                        if (killer->getPlayer()->getClientID() != NETWORK_PEER_ID_UNKNOWN)
[5929]280                            this->gtinfo_->sendKillMessage("You killed " + victim->getPlayer()->getName(), killer->getPlayer()->getClientID());
[8327]281                        if (victim->getPlayer()->getClientID() != NETWORK_PEER_ID_UNKNOWN)
[5929]282                            this->gtinfo_->sendDeathMessage("You were killed by " + killer->getPlayer()->getName(), victim->getPlayer()->getClientID());
[3099]283                    }
[2839]284                }
[2662]285
[8706]286                if(victim->getPlayer()->isHumanPlayer())
287                    this->gtinfo_->pawnKilled(victim->getPlayer());
288
[2662]289                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
290                if (victim->getCamera())
291                {
292                    entity->setPosition(victim->getCamera()->getWorldPosition());
293                    entity->setOrientation(victim->getCamera()->getWorldOrientation());
294                }
295                else
296                {
297                    entity->setPosition(victim->getWorldPosition());
298                    entity->setOrientation(victim->getWorldOrientation());
299                }
300                it->first->startControl(entity);
301            }
302            else
[8858]303                orxout(internal_warning) << "Killed Pawn was not in the playerlist" << endl;
[2662]304        }
[2072]305    }
306
[2826]307    void Gametype::playerScored(PlayerInfo* player)
[2072]308    {
[2826]309        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
310        if (it != this->players_.end())
311            it->second.frags_++;
[2072]312    }
313
[2890]314    int Gametype::getScore(PlayerInfo* player) const
315    {
316        std::map<PlayerInfo*, Player>::const_iterator it = this->players_.find(player);
317        if (it != this->players_.end())
318            return it->second.frags_;
319        else
320            return 0;
321    }
322
[2072]323    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
324    {
[8706]325        // If there is at least one SpawnPoint.
[2072]326        if (this->spawnpoints_.size() > 0)
327        {
[8706]328            // Fallback spawn point if there is no active one, choose a random one.
[7163]329            SpawnPoint* fallbackSpawnPoint = NULL;
[3196]330            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
[2072]331            unsigned int index = 0;
[8706]332            std::vector<SpawnPoint*> activeSpawnPoints;
[2072]333            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
334            {
335                if (index == randomspawn)
[7163]336                    fallbackSpawnPoint = (*it);
337
[8706]338                if (*it != NULL && (*it)->isActive())
339                    activeSpawnPoints.push_back(*it);
[7163]340
341                ++index;
342            }
343
[8706]344            if(activeSpawnPoints.size() > 0)
[7163]345            {
[8706]346                randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(activeSpawnPoints.size())));
347                return activeSpawnPoints[randomspawn];
[2072]348            }
[7163]349
[8858]350            orxout(internal_warning) << "Fallback SpawnPoint was used because there were no active SpawnPoints." << endl;
[7163]351            return fallbackSpawnPoint;
[2072]352        }
353        return 0;
354    }
355
[2171]356    void Gametype::assignDefaultPawnsIfNeeded()
[2072]357    {
[2662]358        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
[2072]359        {
[2662]360            if (!it->first->getControllableEntity())
[2072]361            {
[2662]362                it->second.state_ = PlayerState::Dead;
363
[8706]364                if (!it->first->isReadyToSpawn() || !this->gtinfo_->hasStarted())
[2072]365                {
[3033]366                    this->spawnPlayerAsDefaultPawn(it->first);
367                    it->second.state_ = PlayerState::Dead;
[2072]368                }
369            }
370        }
371    }
372
373    void Gametype::checkStart()
374    {
[8706]375        if (!this->gtinfo_->hasStarted())
[2072]376        {
[8706]377            if (this->gtinfo_->isStartCountdownRunning())
[2072]378            {
[8706]379                if (this->gtinfo_->getStartCountdown() <= 0.0f)
[2072]380                {
[8706]381                    this->gtinfo_->stopStartCountdown();
[9016]382                    this->gtinfo_->setStartCountdown(0.0f);
[2072]383                    this->start();
384                }
385            }
386            else if (this->players_.size() > 0)
387            {
388                if (this->bAutoStart_)
389                {
390                    this->start();
391                }
392                else
393                {
394                    bool allplayersready = true;
[2662]395                    bool hashumanplayers = false;
396                    for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
[2072]397                    {
[2171]398                        if (!it->first->isReadyToSpawn())
[2072]399                            allplayersready = false;
[2662]400                        if (it->first->isHumanPlayer())
401                            hashumanplayers = true;
[2072]402                    }
[9016]403                         
[2662]404                    if (allplayersready && hashumanplayers)
[2072]405                    {
[8079]406                        // If in developer's mode, there is no start countdown.
407                        if(Core::getInstance().inDevMode())
[8706]408                            this->start();
[8079]409                        else
[8706]410                            this->gtinfo_->setStartCountdown(this->initialStartCountdown_);
411                        this->gtinfo_->startStartCountdown();
[2072]412                    }
413                }
414            }
[9016]415           
[2072]416        }
417    }
418
419    void Gametype::spawnPlayersIfRequested()
420    {
[2662]421        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
[8706]422        {
[2171]423            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
424                this->spawnPlayer(it->first);
[8706]425        }
[2072]426    }
427
428    void Gametype::spawnDeadPlayersIfRequested()
429    {
[2662]430        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
431            if (it->second.state_ == PlayerState::Dead)
[2171]432                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
433                    this->spawnPlayer(it->first);
[2072]434    }
435
436    void Gametype::spawnPlayer(PlayerInfo* player)
437    {
438        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
439        if (spawnpoint)
440        {
[2826]441            this->playerPreSpawn(player);
[2072]442            player->startControl(spawnpoint->spawn());
[2662]443            this->players_[player].state_ = PlayerState::Alive;
[8706]444
445            if(player->isHumanPlayer())
446                this->gtinfo_->playerSpawned(player);
[9016]447
[2826]448            this->playerPostSpawn(player);
[2072]449        }
450        else
451        {
[8858]452            orxout(user_error) << "No SpawnPoints in current Gametype" << endl;
[2072]453            abort();
454        }
455    }
[2662]456
[3033]457    void Gametype::spawnPlayerAsDefaultPawn(PlayerInfo* player)
458    {
459        SpawnPoint* spawn = this->getBestSpawnPoint(player);
460        if (spawn)
461        {
462            // force spawn at spawnpoint with default pawn
463            ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
464            spawn->spawn(entity);
465            player->startControl(entity);
466        }
467        else
468        {
[8858]469            orxout(user_error) << "No SpawnPoints in current Gametype" << endl;
[3033]470            abort();
471        }
472    }
473
[2662]474    void Gametype::addBots(unsigned int amount)
475    {
476        for (unsigned int i = 0; i < amount; ++i)
[2839]477            this->botclass_.fabricate(this);
[2662]478    }
479
480    void Gametype::killBots(unsigned int amount)
481    {
482        unsigned int i = 0;
483        for (ObjectList<Bot>::iterator it = ObjectList<Bot>::begin(); (it != ObjectList<Bot>::end()) && ((amount == 0) || (i < amount)); )
484        {
485            if (it->getGametype() == this)
486            {
[5929]487                (it++)->destroy();
[2662]488                ++i;
489            }
[5929]490            else
491                ++it;
[2662]492        }
493    }
[3033]494
495    void Gametype::addTime(float t)
[3038]496    {
[3033]497        if (this->timeLimit_ == 0)
498          this->time_ -= t;
499        else
500          this->time_ += t;
501    }
502
503    void Gametype::removeTime(float t)
[3038]504    {
[3033]505        if (this->timeLimit_ == 0)
506          this->time_ += t;
507        else
508          this->time_ -= t;
509    }
510
511    void Gametype::resetTimer()
[3038]512    {
[3033]513        this->resetTimer(timeLimit_);
514    }
515
516    void Gametype::resetTimer(float t)
[3038]517    {
[3033]518        this->timeLimit_ = t;
519        this->time_ = t;
520    }
[2072]521}
Note: See TracBrowser for help on using the repository browser.