Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/storymodeHS14/src/orxonox/gametypes/Gametype.cc @ 10251

Last change on this file since 10251 was 9984, checked in by landauf, 10 years ago

tab → spaces

  • Property svn:eol-style set to native
File size: 16.4 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 "Gametype.h"
30
31#include "util/Math.h"
32#include "core/Core.h"
33#include "core/CoreIncludes.h"
34#include "core/config/ConfigValueIncludes.h"
35#include "core/GameMode.h"
36#include "core/command/ConsoleCommand.h"
37#include "gamestates/GSLevel.h"
38
39#include "infos/PlayerInfo.h"
40#include "infos/Bot.h"
41#include "graphics/Camera.h"
42#include "worldentities/ControllableEntity.h"
43#include "worldentities/SpawnPoint.h"
44#include "worldentities/pawns/Spectator.h"
45#include "worldentities/pawns/Pawn.h"
46#include "overlays/OverlayGroup.h"
47
48namespace orxonox
49{
50    RegisterUnloadableClass(Gametype);
51
52    Gametype::Gametype(Context* context) : BaseObject(context)
53    {
54        RegisterObject(Gametype);
55
56        this->gtinfo_ = new GametypeInfo(context);
57
58        this->setGametype(SmartPtr<Gametype>(this, false));
59
60        this->defaultControllableEntity_ = Class(Spectator);
61
62        this->bAutoStart_ = false;
63        this->bForceSpawn_ = false;
64        this->bAutoEnd_ = true;
65        this->numberOfBots_ = 0;
66
67        this->timeLimit_ = 0;
68        this->time_ = 0;
69        this->timerIsActive_ = false;
70
71        this->initialStartCountdown_ = 3;
72
73        this->setConfigValues();
74
75        // load the corresponding score board
76        if (GameMode::showsGraphics() && !this->scoreboardTemplate_.empty())
77        {
78            this->scoreboard_ = new OverlayGroup(context);
79            this->scoreboard_->addTemplate(this->scoreboardTemplate_);
80            this->scoreboard_->setGametype(this);
81        }
82        else
83            this->scoreboard_ = 0;
84
85        /* HACK HACK HACK */
86        this->dedicatedAddBots_ = createConsoleCommand( "dedicatedAddBots", createExecutor( createFunctor(&Gametype::addBots, this) ) );
87        this->dedicatedKillBots_ = createConsoleCommand( "dedicatedKillBots", createExecutor( createFunctor(&Gametype::killBots, this) ) );
88        /* HACK HACK HACK */
89    }
90
91    Gametype::~Gametype()
92    {
93        if (this->isInitialized())
94        {
95            this->gtinfo_->destroy();
96            if( this->dedicatedAddBots_ )
97                delete this->dedicatedAddBots_;
98            if( this->dedicatedKillBots_ )
99                delete this->dedicatedKillBots_;
100        }
101    }
102
103    void Gametype::setConfigValues()
104    {
105        SetConfigValue(initialStartCountdown_, 3.0f);
106        SetConfigValue(bAutoStart_, false);
107        SetConfigValue(bForceSpawn_, false);
108        SetConfigValue(bAutoEnd_, true);
109        SetConfigValue(numberOfBots_, 0);
110        SetConfigValue(scoreboardTemplate_, "defaultScoreboard");
111    }
112
113    void Gametype::tick(float dt)
114    {
115        SUPER(Gametype, tick, dt);
116
117        //count timer
118        if (timerIsActive_)
119        {
120            if (this->timeLimit_ == 0)
121                this->time_ += dt;
122            else
123                this->time_ -= dt;
124        }
125
126        if (this->gtinfo_->isStartCountdownRunning() && !this->gtinfo_->hasStarted())
127            this->gtinfo_->countdownStartCountdown(dt);
128
129        if (!this->gtinfo_->hasStarted())
130        {
131            for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
132            {
133                // Inform the GametypeInfo that the player is ready to spawn.
134                if(it->first->isHumanPlayer() && it->first->isReadyToSpawn())
135                    this->gtinfo_->playerReadyToSpawn(it->first);
136            }
137
138            this->checkStart();
139        }
140        else if (!this->gtinfo_->hasEnded())
141            this->spawnDeadPlayersIfRequested();
142
143        this->assignDefaultPawnsIfNeeded();
144    }
145
146    void Gametype::start()
147    {
148        this->addBots(this->numberOfBots_);
149        this->gtinfo_->start();
150        this->spawnPlayersIfRequested();
151    }
152
153    void Gametype::end()
154    {
155        this->gtinfo_->end();
156        if (this->bAutoEnd_)
157        {
158            this->showMenuTimer_.setTimer(3.0f, true, createExecutor(createFunctor(&Gametype::showMenu, this)));
159        }
160
161        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
162        {
163            if (it->first->getControllableEntity())
164            {
165                ControllableEntity* oldentity = it->first->getControllableEntity();
166
167                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(oldentity->getContext());
168                if (oldentity->getCamera())
169                {
170                    entity->setPosition(oldentity->getCamera()->getWorldPosition());
171                    entity->setOrientation(oldentity->getCamera()->getWorldOrientation());
172                }
173                else
174                {
175                    entity->setPosition(oldentity->getWorldPosition());
176                    entity->setOrientation(oldentity->getWorldOrientation());
177                }
178                it->first->startControl(entity);
179            }
180            else
181                this->spawnPlayerAsDefaultPawn(it->first);
182        }
183    }
184
185    void Gametype::playerEntered(PlayerInfo* player)
186    {
187        this->players_[player].state_ = PlayerState::Joined;
188        this->gtinfo_->playerEntered(player);
189    }
190
191    bool Gametype::playerLeft(PlayerInfo* player)
192    {
193        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
194        if (it != this->players_.end())
195        {
196            this->players_.erase(it);
197            return true;
198        }
199        return false;
200    }
201
202    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
203    {
204    }
205
206    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
207    {
208    }
209
210    bool Gametype::playerChangedName(PlayerInfo* player)
211    {
212        if (this->players_.find(player) != this->players_.end())
213        {
214            if (player->getName() != player->getOldName())
215            {
216                return true;
217            }
218        }
219        return false;
220    }
221
222    void Gametype::pawnPreSpawn(Pawn* pawn)
223    {
224    }
225
226    void Gametype::pawnPostSpawn(Pawn* pawn)
227    {
228    }
229
230    void Gametype::playerPreSpawn(PlayerInfo* player)
231    {
232    }
233
234    void Gametype::playerPostSpawn(PlayerInfo* player)
235    {
236    }
237
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    {
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
272                if (killer && killer->getPlayer())
273                {
274                    std::map<PlayerInfo*, Player>::iterator it = this->players_.find(killer->getPlayer());
275                    if (it != this->players_.end())
276                    {
277                        it->second.frags_++;
278
279                        if (killer->getPlayer()->getClientID() != NETWORK_PEER_ID_UNKNOWN)
280                            this->gtinfo_->sendKillMessage("You killed " + victim->getPlayer()->getName(), killer->getPlayer()->getClientID());
281                        if (victim->getPlayer()->getClientID() != NETWORK_PEER_ID_UNKNOWN)
282                            this->gtinfo_->sendDeathMessage("You were killed by " + killer->getPlayer()->getName(), victim->getPlayer()->getClientID());
283                    }
284                }
285
286                if(victim->getPlayer()->isHumanPlayer())
287                    this->gtinfo_->pawnKilled(victim->getPlayer());
288
289                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getContext());
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
303                orxout(internal_warning) << "Killed Pawn was not in the playerlist" << endl;
304        }
305    }
306
307    void Gametype::playerScored(PlayerInfo* player, int score)
308    {
309        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
310        if (it != this->players_.end())
311            it->second.frags_ += score;
312    }
313
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
323    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
324    {
325        // If there is at least one SpawnPoint.
326        if (this->spawnpoints_.size() > 0)
327        {
328            // Fallback spawn point if there is no active one, choose a random one.
329            SpawnPoint* fallbackSpawnPoint = NULL;
330            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
331            unsigned int index = 0;
332            std::vector<SpawnPoint*> activeSpawnPoints;
333            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
334            {
335                if (index == randomspawn)
336                    fallbackSpawnPoint = (*it);
337
338                if (*it != NULL && (*it)->isActive())
339                    activeSpawnPoints.push_back(*it);
340
341                ++index;
342            }
343
344            if(activeSpawnPoints.size() > 0)
345            {
346                randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(activeSpawnPoints.size())));
347                return activeSpawnPoints[randomspawn];
348            }
349
350            orxout(internal_warning) << "Fallback SpawnPoint was used because there were no active SpawnPoints." << endl;
351            return fallbackSpawnPoint;
352        }
353        return 0;
354    }
355
356    void Gametype::assignDefaultPawnsIfNeeded()
357    {
358        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
359        {
360            if (!it->first->getControllableEntity())
361            {
362                it->second.state_ = PlayerState::Dead;
363
364                if (!it->first->isReadyToSpawn() || !this->gtinfo_->hasStarted())
365                {
366                    this->spawnPlayerAsDefaultPawn(it->first);
367                    it->second.state_ = PlayerState::Dead;
368                }
369            }
370        }
371    }
372
373    void Gametype::checkStart()
374    {
375        if (!this->gtinfo_->hasStarted())
376        {
377            if (this->gtinfo_->isStartCountdownRunning())
378            {
379                if (this->gtinfo_->getStartCountdown() <= 0.0f)
380                {
381                    this->gtinfo_->stopStartCountdown();
382                    this->gtinfo_->setStartCountdown(0.0f);
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;
395                    bool hashumanplayers = false;
396                    for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
397                    {
398                        if (!it->first->isReadyToSpawn())
399                            allplayersready = false;
400                        if (it->first->isHumanPlayer())
401                            hashumanplayers = true;
402                    }
403
404                    if (allplayersready && hashumanplayers)
405                    {
406                        // If in developer's mode, there is no start countdown.
407                        if(Core::getInstance().inDevMode())
408                            this->start();
409                        else
410                        {
411                            this->gtinfo_->setStartCountdown(this->initialStartCountdown_);
412                            this->gtinfo_->startStartCountdown();
413                        }
414                    }
415                }
416            }
417        }
418    }
419
420    void Gametype::spawnPlayersIfRequested()
421    {
422        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
423        {
424            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
425                this->spawnPlayer(it->first);
426        }
427    }
428
429    void Gametype::spawnDeadPlayersIfRequested()
430    {
431        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
432            if (it->second.state_ == PlayerState::Dead)
433                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
434                    this->spawnPlayer(it->first);
435    }
436
437    void Gametype::spawnPlayer(PlayerInfo* player)
438    {
439        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
440        if (spawnpoint)
441        {
442            this->playerPreSpawn(player);
443            player->startControl(spawnpoint->spawn());
444            this->players_[player].state_ = PlayerState::Alive;
445
446            if(player->isHumanPlayer())
447                this->gtinfo_->playerSpawned(player);
448
449            this->playerPostSpawn(player);
450        }
451        else
452        {
453            orxout(user_error) << "No SpawnPoints in current Gametype" << endl;
454            abort();
455        }
456    }
457
458    void Gametype::spawnPlayerAsDefaultPawn(PlayerInfo* player)
459    {
460        SpawnPoint* spawn = this->getBestSpawnPoint(player);
461        if (spawn)
462        {
463            // force spawn at spawnpoint with default pawn
464            ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn->getContext());
465            spawn->spawn(entity);
466            player->startControl(entity);
467        }
468        else
469        {
470            orxout(user_error) << "No SpawnPoints in current Gametype" << endl;
471            abort();
472        }
473    }
474
475    void Gametype::addBots(unsigned int amount)
476    {
477        for (unsigned int i = 0; i < amount; ++i)
478            this->botclass_.fabricate(this->getContext());
479    }
480
481    void Gametype::killBots(unsigned int amount)
482    {
483        unsigned int i = 0;
484        for (ObjectList<Bot>::iterator it = ObjectList<Bot>::begin(); (it != ObjectList<Bot>::end()) && ((amount == 0) || (i < amount)); )
485        {
486            if (it->getGametype() == this)
487            {
488                (it++)->destroy();
489                ++i;
490            }
491            else
492                ++it;
493        }
494    }
495
496    void Gametype::addTime(float t)
497    {
498        if (this->timeLimit_ == 0)
499          this->time_ -= t;
500        else
501          this->time_ += t;
502    }
503
504    void Gametype::removeTime(float t)
505    {
506        if (this->timeLimit_ == 0)
507          this->time_ += t;
508        else
509          this->time_ -= t;
510    }
511
512    void Gametype::resetTimer()
513    {
514        this->resetTimer(timeLimit_);
515    }
516
517    void Gametype::resetTimer(float t)
518    {
519        this->timeLimit_ = t;
520        this->time_ = t;
521    }
522
523    void Gametype::showMenu()
524    {
525        GSLevel::startMainMenu();
526    }
527}
Note: See TracBrowser for help on using the repository browser.