Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/miniprojects/src/orxonox/objects/gametypes/Gametype.cc @ 2821

Last change on this file since 2821 was 2820, checked in by landauf, 15 years ago

Split Gametype into Gametype+Deathmatch. The only difference is output like "player x killed player y" which only appears in Deathmatch now. TeamGametype inherits from Deathmatch (and will shortly be renamed into TeamDeathmatch).

  • Property svn:eol-style set to native
File size: 11.0 KB
RevLine 
[2072]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 "OrxonoxStableHeaders.h"
30#include "Gametype.h"
31
32#include <cstdlib>
33#include <ctime>
34
35#include "core/CoreIncludes.h"
[2662]36#include "core/ConfigValueIncludes.h"
37#include "core/Template.h"
38#include "core/Core.h"
39#include "overlays/OverlayGroup.h"
[2072]40#include "objects/infos/PlayerInfo.h"
[2662]41#include "objects/infos/Bot.h"
[2072]42#include "objects/worldentities/pawns/Spectator.h"
43#include "objects/worldentities/SpawnPoint.h"
[2662]44#include "objects/worldentities/Camera.h"
[2072]45
46namespace orxonox
47{
48    CreateUnloadableFactory(Gametype);
49
[2662]50    Gametype::Gametype(BaseObject* creator) : BaseObject(creator), gtinfo_(creator)
[2072]51    {
52        RegisterObject(Gametype);
53
[2662]54        this->setGametype(this);
55
[2072]56        this->defaultControllableEntity_ = Class(Spectator);
57
58        this->bAutoStart_ = false;
59        this->bForceSpawn_ = false;
[2662]60        this->numberOfBots_ = 0;
[2072]61
62        this->initialStartCountdown_ = 3;
[2662]63
64        this->setConfigValues();
65
66        // load the corresponding score board
67        if (Core::showsGraphics() && this->scoreboardTemplate_ != "")
68        {
69            this->scoreboard_ = new OverlayGroup(this);
70            this->scoreboard_->addTemplate(this->scoreboardTemplate_);
71            this->scoreboard_->setGametype(this);
72        }
73        else
74            this->scoreboard_ = 0;
[2072]75    }
76
[2662]77    void Gametype::setConfigValues()
78    {
79        SetConfigValue(initialStartCountdown_, 3.0f);
80        SetConfigValue(bAutoStart_, false);
81        SetConfigValue(bForceSpawn_, false);
82        SetConfigValue(numberOfBots_, 0);
83        SetConfigValue(scoreboardTemplate_, "defaultScoreboard");
84    }
85
[2072]86    void Gametype::tick(float dt)
87    {
[2662]88        SUPER(Gametype, tick, dt);
[2072]89
[2662]90        if (this->gtinfo_.bStartCountdownRunning_ && !this->gtinfo_.bStarted_)
91            this->gtinfo_.startCountdown_ -= dt;
92
93        if (!this->gtinfo_.bStarted_)
[2072]94            this->checkStart();
[2171]95        else
96            this->spawnDeadPlayersIfRequested();
[2072]97
98        this->assignDefaultPawnsIfNeeded();
99    }
100
101    void Gametype::start()
102    {
[2768]103        this->addBots(this->numberOfBots_);
104
[2662]105        this->gtinfo_.bStarted_ = true;
[2072]106
107        this->spawnPlayersIfRequested();
108    }
109
110    void Gametype::end()
111    {
[2662]112        this->gtinfo_.bEnded_ = true;
[2072]113    }
114
115    void Gametype::playerEntered(PlayerInfo* player)
116    {
[2662]117        this->players_[player].state_ = PlayerState::Joined;
[2072]118    }
119
[2820]120    bool Gametype::playerLeft(PlayerInfo* player)
[2072]121    {
[2662]122        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
[2072]123        if (it != this->players_.end())
124        {
125            this->players_.erase(it);
[2820]126            return true;
[2072]127        }
[2820]128        return false;
[2072]129    }
130
131    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
132    {
133    }
134
135    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
136    {
137    }
138
[2820]139    bool Gametype::playerChangedName(PlayerInfo* player)
[2072]140    {
141        if (this->players_.find(player) != this->players_.end())
142        {
143            if (player->getName() != player->getOldName())
144            {
[2820]145                return true;
[2072]146            }
147        }
[2820]148        return false;
[2072]149    }
150
151    void Gametype::pawnPreSpawn(Pawn* pawn)
152    {
153    }
154
155    void Gametype::pawnPostSpawn(Pawn* pawn)
156    {
157    }
158
[2768]159    void Gametype::playerPreSpawn(PlayerInfo* player)
160    {
161    }
162
163    void Gametype::playerPostSpawn(PlayerInfo* player)
164    {
165    }
166
[2818]167    void Gametype::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
168    {
169    }
170
171    void Gametype::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
172    {
173    }
174
[2768]175    bool Gametype::allowPawnHit(Pawn* victim, Pawn* originator)
176    {
177        return true;
178    }
179
180    bool Gametype::allowPawnDamage(Pawn* victim, Pawn* originator)
181    {
182        return true;
183    }
184
185    bool Gametype::allowPawnDeath(Pawn* victim, Pawn* originator)
186    {
187        return true;
188    }
189
[2072]190    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
191    {
[2662]192        if (victim && victim->getPlayer())
193        {
194            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(victim->getPlayer());
195            if (it != this->players_.end())
196            {
197                it->second.state_ = PlayerState::Dead;
198                it->second.killed_++;
199
200                // Reward killer
201                if (killer)
202                {
203                    std::map<PlayerInfo*, Player>::iterator itKiller = this->players_.find(killer->getPlayer());
204                    if (itKiller != this->players_.end())
205                    {
206                        this->playerScored(itKiller->second);
207                    }
208                    else
209                        COUT(2) << "Warning: Killing Pawn was not in the playerlist" << std::endl;
210                }
211
212                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
213                if (victim->getCamera())
214                {
215                    entity->setPosition(victim->getCamera()->getWorldPosition());
216                    entity->setOrientation(victim->getCamera()->getWorldOrientation());
217                }
218                else
219                {
220                    entity->setPosition(victim->getWorldPosition());
221                    entity->setOrientation(victim->getWorldOrientation());
222                }
223                it->first->startControl(entity);
224            }
225            else
226                COUT(2) << "Warning: Killed Pawn was not in the playerlist" << std::endl;
227        }
[2072]228    }
229
[2662]230    void Gametype::playerScored(Player& player)
[2072]231    {
[2662]232        player.frags_++;
[2072]233    }
234
235    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
236    {
237        if (this->spawnpoints_.size() > 0)
238        {
239            unsigned int randomspawn = (unsigned int)rnd(this->spawnpoints_.size());
240            unsigned int index = 0;
241            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
242            {
243                if (index == randomspawn)
244                    return (*it);
245
246                ++index;
247            }
248        }
249        return 0;
250    }
251
[2171]252    void Gametype::assignDefaultPawnsIfNeeded()
[2072]253    {
[2662]254        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
[2072]255        {
[2662]256            if (!it->first->getControllableEntity())
[2072]257            {
[2662]258                it->second.state_ = PlayerState::Dead;
259
260                if (!it->first->isReadyToSpawn() || !this->gtinfo_.bStarted_)
[2072]261                {
[2662]262                    SpawnPoint* spawn = this->getBestSpawnPoint(it->first);
263                    if (spawn)
264                    {
265                        // force spawn at spawnpoint with default pawn
266                        ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
267                        spawn->spawn(entity);
268                        it->first->startControl(entity);
269                        it->second.state_ = PlayerState::Dead;
270                    }
271                    else
272                    {
273                        COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
274                        abort();
275                    }
[2072]276                }
277            }
278        }
279    }
280
281    void Gametype::checkStart()
282    {
[2662]283        if (!this->gtinfo_.bStarted_)
[2072]284        {
[2662]285            if (this->gtinfo_.bStartCountdownRunning_)
[2072]286            {
[2662]287                if (this->gtinfo_.startCountdown_ <= 0)
[2072]288                {
[2662]289                    this->gtinfo_.bStartCountdownRunning_ = false;
290                    this->gtinfo_.startCountdown_ = 0;
[2072]291                    this->start();
292                }
293            }
294            else if (this->players_.size() > 0)
295            {
296                if (this->bAutoStart_)
297                {
298                    this->start();
299                }
300                else
301                {
302                    bool allplayersready = true;
[2662]303                    bool hashumanplayers = false;
304                    for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
[2072]305                    {
[2171]306                        if (!it->first->isReadyToSpawn())
[2072]307                            allplayersready = false;
[2662]308                        if (it->first->isHumanPlayer())
309                            hashumanplayers = true;
[2072]310                    }
[2662]311                    if (allplayersready && hashumanplayers)
[2072]312                    {
[2662]313                        this->gtinfo_.startCountdown_ = this->initialStartCountdown_;
314                        this->gtinfo_.bStartCountdownRunning_ = true;
[2072]315                    }
316                }
317            }
318        }
319    }
320
321    void Gametype::spawnPlayersIfRequested()
322    {
[2662]323        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
[2171]324            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
325                this->spawnPlayer(it->first);
[2072]326    }
327
328    void Gametype::spawnDeadPlayersIfRequested()
329    {
[2662]330        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
331            if (it->second.state_ == PlayerState::Dead)
[2171]332                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
333                    this->spawnPlayer(it->first);
[2072]334    }
335
336    void Gametype::spawnPlayer(PlayerInfo* player)
337    {
338        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
339        if (spawnpoint)
340        {
[2768]341            this->playerPreSpawn(player);
[2072]342            player->startControl(spawnpoint->spawn());
[2662]343            this->players_[player].state_ = PlayerState::Alive;
[2768]344            this->playerPostSpawn(player);
[2072]345        }
346        else
347        {
348            COUT(1) << "Error: No SpawnPoints in current Gametype" << std::endl;
349            abort();
350        }
351    }
[2662]352
353    void Gametype::addBots(unsigned int amount)
354    {
355        for (unsigned int i = 0; i < amount; ++i)
356            new Bot(this);
357    }
358
359    void Gametype::killBots(unsigned int amount)
360    {
361        unsigned int i = 0;
362        for (ObjectList<Bot>::iterator it = ObjectList<Bot>::begin(); (it != ObjectList<Bot>::end()) && ((amount == 0) || (i < amount)); )
363        {
364            if (it->getGametype() == this)
365            {
366                delete (*(it++));
367                ++i;
368            }
369        }
370    }
[2072]371}
Note: See TracBrowser for help on using the repository browser.