Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation3/src/orxonox/gametypes/Gametype.cc @ 6996

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

Loads of changes.
1) PickupInventory should now be working even for extreme cases.
2) Added support for inactive Spawnpoints in Gametype.
3) Made Pickupable rewardble. meaning from now on any Pickupable can be given as a reward for completing Quests.
4) Added some keybinds to KeybindMenu, such as PickupInventory, QuestGUI and Chat.

  • 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.