Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/presentation/src/orxonox/objects/gametypes/Gametype.cc @ 2501

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