Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2952 was 2952, checked in by mockm, 15 years ago

new revision of gametype UnderAttack: Ship is now moving

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