Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/network5/src/orxonox/gametypes/Gametype.cc @ 7777

Last change on this file since 7777 was 7777, checked in by scheusso, 13 years ago

some () structural changes
some functional changes (GamestateClient replaced through GamestateManager on client)
reliable packets get buffered until a recent gamestate arrived and got processed

  • 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/command/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->dedicatedAddBots_ = createConsoleCommand( "dedicatedAddBots", createExecutor( createFunctor(&Gametype::addBots, this) ) );
84        this->dedicatedKillBots_ = createConsoleCommand( "dedicatedKillBots", createExecutor( createFunctor(&Gametype::killBots, this) ) );
85        /* HACK HACK HACK */
86    }
87
88    Gametype::~Gametype()
89    {
90        if (this->isInitialized())
91        {
92            this->gtinfo_->destroy();
93            if( this->dedicatedAddBots_ )
94                delete this->dedicatedAddBots_;
95            if( this->dedicatedKillBots_ )
96                delete this->dedicatedKillBots_;
97        }
98    }
99
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
109    void Gametype::tick(float dt)
110    {
111        SUPER(Gametype, tick, dt);
112
113        //count timer
114        if (timerIsActive_)
115        {
116            if (this->timeLimit_ == 0)
117                this->time_ += dt;
118            else
119                this->time_ -= dt;
120        }
121
122        if (this->gtinfo_->bStartCountdownRunning_ && !this->gtinfo_->bStarted_)
123            this->gtinfo_->startCountdown_ -= dt;
124
125        if (!this->gtinfo_->bStarted_)
126            this->checkStart();
127        else if (!this->gtinfo_->bEnded_)
128            this->spawnDeadPlayersIfRequested();
129
130        this->assignDefaultPawnsIfNeeded();
131    }
132
133    void Gametype::start()
134    {
135        this->addBots(this->numberOfBots_);
136
137        this->gtinfo_->bStarted_ = true;
138
139        this->spawnPlayersIfRequested();
140    }
141
142    void Gametype::end()
143    {
144        this->gtinfo_->bEnded_ = true;
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();
151
152                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(oldentity);
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        }
169    }
170
171    void Gametype::playerEntered(PlayerInfo* player)
172    {
173      COUT(0) << "Gametype: playerentered" << endl;
174        this->players_[player].state_ = PlayerState::Joined;
175    }
176
177    bool Gametype::playerLeft(PlayerInfo* player)
178    {
179        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
180        if (it != this->players_.end())
181        {
182            this->players_.erase(it);
183            return true;
184        }
185        return false;
186    }
187
188    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
189    {
190    }
191
192    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
193    {
194    }
195
196    bool Gametype::playerChangedName(PlayerInfo* player)
197    {
198        if (this->players_.find(player) != this->players_.end())
199        {
200            if (player->getName() != player->getOldName())
201            {
202                return true;
203            }
204        }
205        return false;
206    }
207
208    void Gametype::pawnPreSpawn(Pawn* pawn)
209    {
210    }
211
212    void Gametype::pawnPostSpawn(Pawn* pawn)
213    {
214    }
215
216    void Gametype::playerPreSpawn(PlayerInfo* player)
217    {
218    }
219
220    void Gametype::playerPostSpawn(PlayerInfo* player)
221    {
222    }
223
224    void Gametype::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
225    {
226    }
227
228    void Gametype::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
229    {
230    }
231
232    bool Gametype::allowPawnHit(Pawn* victim, Pawn* originator)
233    {
234        return true;
235    }
236
237    bool Gametype::allowPawnDamage(Pawn* victim, Pawn* originator)
238    {
239        return true;
240    }
241
242    bool Gametype::allowPawnDeath(Pawn* victim, Pawn* originator)
243    {
244        return true;
245    }
246
247    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
248    {
249        if (victim && victim->getPlayer())
250        {
251            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(victim->getPlayer());
252            if (it != this->players_.end())
253            {
254                it->second.state_ = PlayerState::Dead;
255                it->second.killed_++;
256
257                // Reward killer
258                if (killer && killer->getPlayer())
259                {
260                    std::map<PlayerInfo*, Player>::iterator it = this->players_.find(killer->getPlayer());
261                    if (it != this->players_.end())
262                    {
263                        it->second.frags_++;
264
265                        if (killer->getPlayer()->getClientID() != CLIENTID_UNKNOWN)
266                            this->gtinfo_->sendKillMessage("You killed " + victim->getPlayer()->getName(), killer->getPlayer()->getClientID());
267                        if (victim->getPlayer()->getClientID() != CLIENTID_UNKNOWN)
268                            this->gtinfo_->sendDeathMessage("You were killed by " + killer->getPlayer()->getName(), victim->getPlayer()->getClientID());
269                    }
270                }
271
272                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
273                if (victim->getCamera())
274                {
275                    entity->setPosition(victim->getCamera()->getWorldPosition());
276                    entity->setOrientation(victim->getCamera()->getWorldOrientation());
277                }
278                else
279                {
280                    entity->setPosition(victim->getWorldPosition());
281                    entity->setOrientation(victim->getWorldOrientation());
282                }
283                it->first->startControl(entity);
284            }
285            else
286                COUT(2) << "Warning: Killed Pawn was not in the playerlist" << std::endl;
287        }
288    }
289
290    void Gametype::playerScored(PlayerInfo* player)
291    {
292        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
293        if (it != this->players_.end())
294            it->second.frags_++;
295    }
296
297    int Gametype::getScore(PlayerInfo* player) const
298    {
299        std::map<PlayerInfo*, Player>::const_iterator it = this->players_.find(player);
300        if (it != this->players_.end())
301            return it->second.frags_;
302        else
303            return 0;
304    }
305
306    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
307    {
308        if (this->spawnpoints_.size() > 0)
309        {
310            SpawnPoint* fallbackSpawnPoint = NULL;
311            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
312            unsigned int index = 0;
313            std::set<SpawnPoint*> activeSpawnPoints = this->spawnpoints_;
314            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
315            {
316                if (index == randomspawn)
317                    fallbackSpawnPoint = (*it);
318
319                if (!(*it)->isActive())
320                    activeSpawnPoints.erase(*it);
321
322                ++index;
323            }
324
325            randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
326            index = 0;
327            for (std::set<SpawnPoint*>::const_iterator it = activeSpawnPoints.begin(); it != activeSpawnPoints.end(); ++it)
328            {
329                if (index == randomspawn)
330                    return (*it);
331
332                ++index;
333            }
334
335            return fallbackSpawnPoint;
336        }
337        return 0;
338    }
339
340    void Gametype::assignDefaultPawnsIfNeeded()
341    {
342        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
343        {
344            if (!it->first->getControllableEntity())
345            {
346                it->second.state_ = PlayerState::Dead;
347
348                if (!it->first->isReadyToSpawn() || !this->gtinfo_->bStarted_)
349                {
350                    this->spawnPlayerAsDefaultPawn(it->first);
351                    it->second.state_ = PlayerState::Dead;
352                }
353            }
354        }
355    }
356
357    void Gametype::checkStart()
358    {
359        if (!this->gtinfo_->bStarted_)
360        {
361            if (this->gtinfo_->bStartCountdownRunning_)
362            {
363                if (this->gtinfo_->startCountdown_ <= 0)
364                {
365                    this->gtinfo_->bStartCountdownRunning_ = false;
366                    this->gtinfo_->startCountdown_ = 0;
367                    this->start();
368                }
369            }
370            else if (this->players_.size() > 0)
371            {
372                if (this->bAutoStart_)
373                {
374                    this->start();
375                }
376                else
377                {
378                    bool allplayersready = true;
379                    bool hashumanplayers = false;
380                    for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
381                    {
382                        if (!it->first->isReadyToSpawn())
383                            allplayersready = false;
384                        if (it->first->isHumanPlayer())
385                            hashumanplayers = true;
386                    }
387                    if (allplayersready && hashumanplayers)
388                    {
389                        this->gtinfo_->startCountdown_ = this->initialStartCountdown_;
390                        this->gtinfo_->bStartCountdownRunning_ = true;
391                    }
392                }
393            }
394        }
395    }
396
397    void Gametype::spawnPlayersIfRequested()
398    {
399        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
400            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
401                this->spawnPlayer(it->first);
402    }
403
404    void Gametype::spawnDeadPlayersIfRequested()
405    {
406        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
407            if (it->second.state_ == PlayerState::Dead)
408                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
409                    this->spawnPlayer(it->first);
410    }
411
412    void Gametype::spawnPlayer(PlayerInfo* player)
413    {
414      COUT(0) << "Gametype: spawnPlayer" << endl;
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.