Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Merging presentation2 branch back to trunk.

  • Property svn:eol-style set to native
File size: 14.9 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;
[7801]81
82        /* HACK HACK HACK */
83        this->dedicatedAddBots_ = createConsoleCommand( "dedicatedAddBots", createExecutor( createFunctor(&Gametype::addBots, this) ) );
84        this->dedicatedKillBots_ = createConsoleCommand( "dedicatedKillBots", createExecutor( createFunctor(&Gametype::killBots, this) ) );
85        /* HACK HACK HACK */
[2072]86    }
[6417]87
[5929]88    Gametype::~Gametype()
89    {
90        if (this->isInitialized())
91        {
92            this->gtinfo_->destroy();
[7801]93            if( this->dedicatedAddBots_ )
94                delete this->dedicatedAddBots_;
95            if( this->dedicatedKillBots_ )
96                delete this->dedicatedKillBots_;
[5929]97        }
98    }
[2072]99
[2662]100    void Gametype::setConfigValues()
101    {
102        SetConfigValue(initialStartCountdown_, 3.0f);
103        SetConfigValue(bAutoStart_, false);
104        SetConfigValue(bForceSpawn_, false);
105        SetConfigValue(numberOfBots_, 0);
106        SetConfigValue(scoreboardTemplate_, "defaultScoreboard");
107    }
108
[2072]109    void Gametype::tick(float dt)
110    {
[2662]111        SUPER(Gametype, tick, dt);
[2072]112
[3033]113        //count timer
114        if (timerIsActive_)
115        {
116            if (this->timeLimit_ == 0)
117                this->time_ += dt;
118            else
119                this->time_ -= dt;
120        }
121
[5929]122        if (this->gtinfo_->bStartCountdownRunning_ && !this->gtinfo_->bStarted_)
123            this->gtinfo_->startCountdown_ -= dt;
[2662]124
[5929]125        if (!this->gtinfo_->bStarted_)
[2072]126            this->checkStart();
[5929]127        else if (!this->gtinfo_->bEnded_)
[2171]128            this->spawnDeadPlayersIfRequested();
[2072]129
130        this->assignDefaultPawnsIfNeeded();
131    }
132
133    void Gametype::start()
134    {
[2826]135        this->addBots(this->numberOfBots_);
136
[5929]137        this->gtinfo_->bStarted_ = true;
[2072]138
139        this->spawnPlayersIfRequested();
140    }
141
142    void Gametype::end()
143    {
[5929]144        this->gtinfo_->bEnded_ = true;
[3033]145
146        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
147        {
148            if (it->first->getControllableEntity())
149            {
150                ControllableEntity* oldentity = it->first->getControllableEntity();
[3038]151
[5929]152                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(oldentity);
[3033]153                if (oldentity->getCamera())
154                {
155                    entity->setPosition(oldentity->getCamera()->getWorldPosition());
156                    entity->setOrientation(oldentity->getCamera()->getWorldOrientation());
157                }
158                else
159                {
160                    entity->setPosition(oldentity->getWorldPosition());
161                    entity->setOrientation(oldentity->getWorldOrientation());
162                }
163
164                it->first->startControl(entity);
165            }
166            else
167                this->spawnPlayerAsDefaultPawn(it->first);
168        }
[2072]169    }
170
171    void Gametype::playerEntered(PlayerInfo* player)
172    {
[2662]173        this->players_[player].state_ = PlayerState::Joined;
[2072]174    }
175
[2826]176    bool Gametype::playerLeft(PlayerInfo* player)
[2072]177    {
[2662]178        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
[2072]179        if (it != this->players_.end())
180        {
181            this->players_.erase(it);
[2826]182            return true;
[2072]183        }
[2826]184        return false;
[2072]185    }
186
187    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
188    {
189    }
190
191    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
192    {
193    }
194
[2826]195    bool Gametype::playerChangedName(PlayerInfo* player)
[2072]196    {
197        if (this->players_.find(player) != this->players_.end())
198        {
199            if (player->getName() != player->getOldName())
200            {
[2826]201                return true;
[2072]202            }
203        }
[2826]204        return false;
[2072]205    }
206
207    void Gametype::pawnPreSpawn(Pawn* pawn)
208    {
209    }
210
211    void Gametype::pawnPostSpawn(Pawn* pawn)
212    {
213    }
214
[2826]215    void Gametype::playerPreSpawn(PlayerInfo* player)
[2072]216    {
[2826]217    }
[2662]218
[2826]219    void Gametype::playerPostSpawn(PlayerInfo* player)
220    {
221    }
[2662]222
[2826]223    void Gametype::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
224    {
225    }
226
227    void Gametype::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
228    {
229    }
230
231    bool Gametype::allowPawnHit(Pawn* victim, Pawn* originator)
232    {
233        return true;
234    }
235
236    bool Gametype::allowPawnDamage(Pawn* victim, Pawn* originator)
237    {
238        return true;
239    }
240
241    bool Gametype::allowPawnDeath(Pawn* victim, Pawn* originator)
242    {
243        return true;
244    }
245
246    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
247    {
[2662]248        if (victim && victim->getPlayer())
249        {
250            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(victim->getPlayer());
251            if (it != this->players_.end())
252            {
253                it->second.state_ = PlayerState::Dead;
254                it->second.killed_++;
255
256                // Reward killer
[3099]257                if (killer && killer->getPlayer())
[2839]258                {
259                    std::map<PlayerInfo*, Player>::iterator it = this->players_.find(killer->getPlayer());
260                    if (it != this->players_.end())
[3099]261                    {
[2839]262                        it->second.frags_++;
[3099]263
264                        if (killer->getPlayer()->getClientID() != CLIENTID_UNKNOWN)
[5929]265                            this->gtinfo_->sendKillMessage("You killed " + victim->getPlayer()->getName(), killer->getPlayer()->getClientID());
[3099]266                        if (victim->getPlayer()->getClientID() != CLIENTID_UNKNOWN)
[5929]267                            this->gtinfo_->sendDeathMessage("You were killed by " + killer->getPlayer()->getName(), victim->getPlayer()->getClientID());
[3099]268                    }
[2839]269                }
[2662]270
271                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
272                if (victim->getCamera())
273                {
274                    entity->setPosition(victim->getCamera()->getWorldPosition());
275                    entity->setOrientation(victim->getCamera()->getWorldOrientation());
276                }
277                else
278                {
279                    entity->setPosition(victim->getWorldPosition());
280                    entity->setOrientation(victim->getWorldOrientation());
281                }
282                it->first->startControl(entity);
283            }
284            else
285                COUT(2) << "Warning: Killed Pawn was not in the playerlist" << std::endl;
286        }
[2072]287    }
288
[2826]289    void Gametype::playerScored(PlayerInfo* player)
[2072]290    {
[2826]291        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
292        if (it != this->players_.end())
293            it->second.frags_++;
[2072]294    }
295
[2890]296    int Gametype::getScore(PlayerInfo* player) const
297    {
298        std::map<PlayerInfo*, Player>::const_iterator it = this->players_.find(player);
299        if (it != this->players_.end())
300            return it->second.frags_;
301        else
302            return 0;
303    }
304
[2072]305    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
306    {
307        if (this->spawnpoints_.size() > 0)
308        {
[7163]309            SpawnPoint* fallbackSpawnPoint = NULL;
[3196]310            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
[2072]311            unsigned int index = 0;
[7163]312            std::set<SpawnPoint*> activeSpawnPoints = this->spawnpoints_;
[2072]313            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
314            {
315                if (index == randomspawn)
[7163]316                    fallbackSpawnPoint = (*it);
317
318                if (!(*it)->isActive())
319                    activeSpawnPoints.erase(*it);
320
321                ++index;
322            }
323
324            randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
325            index = 0;
326            for (std::set<SpawnPoint*>::const_iterator it = activeSpawnPoints.begin(); it != activeSpawnPoints.end(); ++it)
327            {
328                if (index == randomspawn)
[2072]329                    return (*it);
330
331                ++index;
332            }
[7163]333
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                    {
[5929]388                        this->gtinfo_->startCountdown_ = this->initialStartCountdown_;
389                        this->gtinfo_->bStartCountdownRunning_ = true;
[2072]390                    }
391                }
392            }
393        }
394    }
395
396    void Gametype::spawnPlayersIfRequested()
397    {
[2662]398        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
[2171]399            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
400                this->spawnPlayer(it->first);
[2072]401    }
402
403    void Gametype::spawnDeadPlayersIfRequested()
404    {
[2662]405        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
406            if (it->second.state_ == PlayerState::Dead)
[2171]407                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
408                    this->spawnPlayer(it->first);
[2072]409    }
410
411    void Gametype::spawnPlayer(PlayerInfo* player)
412    {
413        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
414        if (spawnpoint)
415        {
[2826]416            this->playerPreSpawn(player);
[2072]417            player->startControl(spawnpoint->spawn());
[2662]418            this->players_[player].state_ = PlayerState::Alive;
[2826]419            this->playerPostSpawn(player);
[2072]420        }
421        else
422        {
423            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
424            abort();
425        }
426    }
[2662]427
[3033]428    void Gametype::spawnPlayerAsDefaultPawn(PlayerInfo* player)
429    {
430        SpawnPoint* spawn = this->getBestSpawnPoint(player);
431        if (spawn)
432        {
433            // force spawn at spawnpoint with default pawn
434            ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
435            spawn->spawn(entity);
436            player->startControl(entity);
437        }
438        else
439        {
440            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
441            abort();
442        }
443    }
444
[2662]445    void Gametype::addBots(unsigned int amount)
446    {
447        for (unsigned int i = 0; i < amount; ++i)
[2839]448            this->botclass_.fabricate(this);
[2662]449    }
450
451    void Gametype::killBots(unsigned int amount)
452    {
453        unsigned int i = 0;
454        for (ObjectList<Bot>::iterator it = ObjectList<Bot>::begin(); (it != ObjectList<Bot>::end()) && ((amount == 0) || (i < amount)); )
455        {
456            if (it->getGametype() == this)
457            {
[5929]458                (it++)->destroy();
[2662]459                ++i;
460            }
[5929]461            else
462                ++it;
[2662]463        }
464    }
[3033]465
466    void Gametype::addTime(float t)
[3038]467    {
[3033]468        if (this->timeLimit_ == 0)
469          this->time_ -= t;
470        else
471          this->time_ += t;
472    }
473
474    void Gametype::removeTime(float t)
[3038]475    {
[3033]476        if (this->timeLimit_ == 0)
477          this->time_ += t;
478        else
479          this->time_ -= t;
480    }
481
482    void Gametype::resetTimer()
[3038]483    {
[3033]484        this->resetTimer(timeLimit_);
485    }
486
487    void Gametype::resetTimer(float t)
[3038]488    {
[3033]489        this->timeLimit_ = t;
490        this->time_ = t;
491    }
[2072]492}
Note: See TracBrowser for help on using the repository browser.