Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation2011/src/orxonox/gametypes/Gametype.cc @ 8997

Last change on this file since 8997 was 8980, checked in by jo, 12 years ago

teamgametype merged into trunk

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