Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

added TeamGametype

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