Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7163 was 7163, checked in by dafrick, 14 years ago

Merged presentation3 branch into trunk.

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