Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/gametypes/Gametype.cc @ 8858

Last change on this file since 8858 was 8858, checked in by landauf, 13 years ago

merged output branch back to trunk.

Changes:

  • you have to include util/Output.h instead of util/Debug.h
  • COUT(x) is now called orxout(level)
  • output levels are now defined by an enum instead of numbers. see util/Output.h for the definition
  • it's possible to use output contexts with orxout(level, context). see util/Output.h for some common contexts. you can define more contexts
  • you must use 'endl' at the end of an output message, '\n' does not flush the message

Output levels:

  • instead of COUT(0) use orxout()
  • instead of COUT(1) use orxout(user_error) or orxout(internal_error)
  • instead of COUT(2) use orxout(user_warning) or orxout(internal_warning)
  • instead of COUT(3) use orxout(user_status/user_info) or orxout(internal_status/internal_info)
  • instead of COUT(4) use orxout(verbose)
  • instead of COUT(5) use orxout(verbose_more)
  • instead of COUT(6) use orxout(verbose_ultra)

Guidelines:

  • user_* levels are for the user, visible in the console and the log-file
  • internal_* levels are for developers, visible in the log-file
  • verbose_* levels are for debugging, only visible if the context of the output is activated

Usage in C++:

  • orxout() << "message" << endl;
  • orxout(level) << "message" << endl;
  • orxout(level, context) << "message" << endl;

Usage in Lua:

  • orxout("message")
  • orxout(orxonox.level.levelname, "message")
  • orxout(orxonox.level.levelname, "context", "message")

Usage in Tcl (and in the in-game-console):

  • orxout levelname message
  • orxout_context levelname context message
  • shortcuts: log message, error message, warning message, status message, info message, debug message
  • Property svn:eol-style set to native
File size: 16.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/Core.h"
33#include "core/CoreIncludes.h"
34#include "core/ConfigValueIncludes.h"
35#include "core/GameMode.h"
36#include "core/command/ConsoleCommand.h"
37
38#include "infos/PlayerInfo.h"
39#include "infos/Bot.h"
40#include "graphics/Camera.h"
41#include "worldentities/ControllableEntity.h"
42#include "worldentities/SpawnPoint.h"
43#include "worldentities/pawns/Spectator.h"
44#include "worldentities/pawns/Pawn.h"
45#include "overlays/OverlayGroup.h"
46
47namespace orxonox
48{
49    CreateUnloadableFactory(Gametype);
50
51    Gametype::Gametype(BaseObject* creator) : BaseObject(creator)
52    {
53        RegisterObject(Gametype);
54
55        this->gtinfo_ = new GametypeInfo(creator);
56
57        this->setGametype(SmartPtr<Gametype>(this, false));
58
59        this->defaultControllableEntity_ = Class(Spectator);
60
61        this->bAutoStart_ = false;
62        this->bForceSpawn_ = false;
63        this->numberOfBots_ = 0;
64
65        this->timeLimit_ = 0;
66        this->time_ = 0;
67        this->timerIsActive_ = false;
68
69        this->initialStartCountdown_ = 3;
70
71        this->setConfigValues();
72
73        // load the corresponding score board
74        if (GameMode::showsGraphics() && !this->scoreboardTemplate_.empty())
75        {
76            this->scoreboard_ = new OverlayGroup(this);
77            this->scoreboard_->addTemplate(this->scoreboardTemplate_);
78            this->scoreboard_->setGametype(this);
79        }
80        else
81            this->scoreboard_ = 0;
82
83        /* HACK HACK HACK */
84        this->dedicatedAddBots_ = createConsoleCommand( "dedicatedAddBots", createExecutor( createFunctor(&Gametype::addBots, this) ) );
85        this->dedicatedKillBots_ = createConsoleCommand( "dedicatedKillBots", createExecutor( createFunctor(&Gametype::killBots, this) ) );
86        /* HACK HACK HACK */
87    }
88
89    Gametype::~Gametype()
90    {
91        if (this->isInitialized())
92        {
93            this->gtinfo_->destroy();
94            if( this->dedicatedAddBots_ )
95                delete this->dedicatedAddBots_;
96            if( this->dedicatedKillBots_ )
97                delete this->dedicatedKillBots_;
98        }
99    }
100
101    void Gametype::setConfigValues()
102    {
103        SetConfigValue(initialStartCountdown_, 3.0f);
104        SetConfigValue(bAutoStart_, false);
105        SetConfigValue(bForceSpawn_, false);
106        SetConfigValue(numberOfBots_, 0);
107        SetConfigValue(scoreboardTemplate_, "defaultScoreboard");
108    }
109
110    void Gametype::tick(float dt)
111    {
112        SUPER(Gametype, tick, dt);
113
114        //count timer
115        if (timerIsActive_)
116        {
117            if (this->timeLimit_ == 0)
118                this->time_ += dt;
119            else
120                this->time_ -= dt;
121        }
122
123        if (this->gtinfo_->isStartCountdownRunning() && !this->gtinfo_->hasStarted())
124            this->gtinfo_->countdownStartCountdown(dt);
125
126        if (!this->gtinfo_->hasStarted())
127        {
128            for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
129            {
130                // Inform the GametypeInfo that the player is ready to spawn.
131                if(it->first->isHumanPlayer() && it->first->isReadyToSpawn())
132                    this->gtinfo_->playerReadyToSpawn(it->first);
133            }
134                   
135            this->checkStart();
136        }
137        else if (!this->gtinfo_->hasEnded())
138            this->spawnDeadPlayersIfRequested();
139
140        this->assignDefaultPawnsIfNeeded();
141    }
142
143    void Gametype::start()
144    {
145        this->addBots(this->numberOfBots_);
146
147        this->gtinfo_->start();
148
149        this->spawnPlayersIfRequested();
150    }
151
152    void Gametype::end()
153    {
154        this->gtinfo_->end();
155
156        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
157        {
158            if (it->first->getControllableEntity())
159            {
160                ControllableEntity* oldentity = it->first->getControllableEntity();
161
162                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(oldentity);
163                if (oldentity->getCamera())
164                {
165                    entity->setPosition(oldentity->getCamera()->getWorldPosition());
166                    entity->setOrientation(oldentity->getCamera()->getWorldOrientation());
167                }
168                else
169                {
170                    entity->setPosition(oldentity->getWorldPosition());
171                    entity->setOrientation(oldentity->getWorldOrientation());
172                }
173
174                it->first->startControl(entity);
175            }
176            else
177                this->spawnPlayerAsDefaultPawn(it->first);
178        }
179    }
180
181    void Gametype::playerEntered(PlayerInfo* player)
182    {
183        this->players_[player].state_ = PlayerState::Joined;
184        this->gtinfo_->playerEntered(player);
185    }
186
187    bool Gametype::playerLeft(PlayerInfo* player)
188    {
189        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
190        if (it != this->players_.end())
191        {
192            this->players_.erase(it);
193            return true;
194        }
195        return false;
196    }
197
198    void Gametype::playerSwitched(PlayerInfo* player, Gametype* newgametype)
199    {
200    }
201
202    void Gametype::playerSwitchedBack(PlayerInfo* player, Gametype* oldgametype)
203    {
204    }
205
206    bool Gametype::playerChangedName(PlayerInfo* player)
207    {
208        if (this->players_.find(player) != this->players_.end())
209        {
210            if (player->getName() != player->getOldName())
211            {
212                return true;
213            }
214        }
215        return false;
216    }
217
218    void Gametype::pawnPreSpawn(Pawn* pawn)
219    {
220    }
221
222    void Gametype::pawnPostSpawn(Pawn* pawn)
223    {
224    }
225
226    void Gametype::playerPreSpawn(PlayerInfo* player)
227    {
228    }
229
230    void Gametype::playerPostSpawn(PlayerInfo* player)
231    {
232    }
233
234    void Gametype::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
235    {
236    }
237
238    void Gametype::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
239    {
240    }
241
242    bool Gametype::allowPawnHit(Pawn* victim, Pawn* originator)
243    {
244        return true;
245    }
246
247    bool Gametype::allowPawnDamage(Pawn* victim, Pawn* originator)
248    {
249        return true;
250    }
251
252    bool Gametype::allowPawnDeath(Pawn* victim, Pawn* originator)
253    {
254        return true;
255    }
256
257    void Gametype::pawnKilled(Pawn* victim, Pawn* killer)
258    {
259        if (victim && victim->getPlayer())
260        {
261            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(victim->getPlayer());
262            if (it != this->players_.end())
263            {
264                it->second.state_ = PlayerState::Dead;
265                it->second.killed_++;
266
267                // Reward killer
268                if (killer && killer->getPlayer())
269                {
270                    std::map<PlayerInfo*, Player>::iterator it = this->players_.find(killer->getPlayer());
271                    if (it != this->players_.end())
272                    {
273                        it->second.frags_++;
274
275                        if (killer->getPlayer()->getClientID() != NETWORK_PEER_ID_UNKNOWN)
276                            this->gtinfo_->sendKillMessage("You killed " + victim->getPlayer()->getName(), killer->getPlayer()->getClientID());
277                        if (victim->getPlayer()->getClientID() != NETWORK_PEER_ID_UNKNOWN)
278                            this->gtinfo_->sendDeathMessage("You were killed by " + killer->getPlayer()->getName(), victim->getPlayer()->getClientID());
279                    }
280                }
281
282                if(victim->getPlayer()->isHumanPlayer())
283                    this->gtinfo_->pawnKilled(victim->getPlayer());
284
285                ControllableEntity* entity = this->defaultControllableEntity_.fabricate(victim->getCreator());
286                if (victim->getCamera())
287                {
288                    entity->setPosition(victim->getCamera()->getWorldPosition());
289                    entity->setOrientation(victim->getCamera()->getWorldOrientation());
290                }
291                else
292                {
293                    entity->setPosition(victim->getWorldPosition());
294                    entity->setOrientation(victim->getWorldOrientation());
295                }
296                it->first->startControl(entity);
297            }
298            else
299                orxout(internal_warning) << "Killed Pawn was not in the playerlist" << endl;
300        }
301    }
302
303    void Gametype::playerScored(PlayerInfo* player)
304    {
305        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
306        if (it != this->players_.end())
307            it->second.frags_++;
308    }
309
310    int Gametype::getScore(PlayerInfo* player) const
311    {
312        std::map<PlayerInfo*, Player>::const_iterator it = this->players_.find(player);
313        if (it != this->players_.end())
314            return it->second.frags_;
315        else
316            return 0;
317    }
318
319    SpawnPoint* Gametype::getBestSpawnPoint(PlayerInfo* player) const
320    {
321        // If there is at least one SpawnPoint.
322        if (this->spawnpoints_.size() > 0)
323        {
324            // Fallback spawn point if there is no active one, choose a random one.
325            SpawnPoint* fallbackSpawnPoint = NULL;
326            unsigned int randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(this->spawnpoints_.size())));
327            unsigned int index = 0;
328            std::vector<SpawnPoint*> activeSpawnPoints;
329            for (std::set<SpawnPoint*>::const_iterator it = this->spawnpoints_.begin(); it != this->spawnpoints_.end(); ++it)
330            {
331                if (index == randomspawn)
332                    fallbackSpawnPoint = (*it);
333
334                if (*it != NULL && (*it)->isActive())
335                    activeSpawnPoints.push_back(*it);
336
337                ++index;
338            }
339
340            if(activeSpawnPoints.size() > 0)
341            {
342                randomspawn = static_cast<unsigned int>(rnd(static_cast<float>(activeSpawnPoints.size())));
343                return activeSpawnPoints[randomspawn];
344            }
345
346            orxout(internal_warning) << "Fallback SpawnPoint was used because there were no active SpawnPoints." << endl;
347            return fallbackSpawnPoint;
348        }
349        return 0;
350    }
351
352    void Gametype::assignDefaultPawnsIfNeeded()
353    {
354        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
355        {
356            if (!it->first->getControllableEntity())
357            {
358                it->second.state_ = PlayerState::Dead;
359
360                if (!it->first->isReadyToSpawn() || !this->gtinfo_->hasStarted())
361                {
362                    this->spawnPlayerAsDefaultPawn(it->first);
363                    it->second.state_ = PlayerState::Dead;
364                }
365            }
366        }
367    }
368
369    void Gametype::checkStart()
370    {
371        if (!this->gtinfo_->hasStarted())
372        {
373            if (this->gtinfo_->isStartCountdownRunning())
374            {
375                if (this->gtinfo_->getStartCountdown() <= 0.0f)
376                {
377                    this->gtinfo_->stopStartCountdown();
378                    this->gtinfo_->setStartCountdown(0.0f);;
379                    this->start();
380                }
381            }
382            else if (this->players_.size() > 0)
383            {
384                if (this->bAutoStart_)
385                {
386                    this->start();
387                }
388                else
389                {
390                    bool allplayersready = true;
391                    bool hashumanplayers = false;
392                    for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
393                    {
394                        if (!it->first->isReadyToSpawn())
395                            allplayersready = false;
396                        if (it->first->isHumanPlayer())
397                            hashumanplayers = true;
398                    }
399                    if (allplayersready && hashumanplayers)
400                    {
401                        // If in developer's mode, there is no start countdown.
402                        if(Core::getInstance().inDevMode())
403                            this->start();
404                        else
405                            this->gtinfo_->setStartCountdown(this->initialStartCountdown_);
406                        this->gtinfo_->startStartCountdown();
407                    }
408                }
409            }
410        }
411    }
412
413    void Gametype::spawnPlayersIfRequested()
414    {
415        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
416        {
417            if (it->first->isReadyToSpawn() || this->bForceSpawn_)
418                this->spawnPlayer(it->first);
419        }
420    }
421
422    void Gametype::spawnDeadPlayersIfRequested()
423    {
424        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
425            if (it->second.state_ == PlayerState::Dead)
426                if (it->first->isReadyToSpawn() || this->bForceSpawn_)
427                    this->spawnPlayer(it->first);
428    }
429
430    void Gametype::spawnPlayer(PlayerInfo* player)
431    {
432        SpawnPoint* spawnpoint = this->getBestSpawnPoint(player);
433        if (spawnpoint)
434        {
435            this->playerPreSpawn(player);
436            player->startControl(spawnpoint->spawn());
437            this->players_[player].state_ = PlayerState::Alive;
438
439            if(player->isHumanPlayer())
440                this->gtinfo_->playerSpawned(player);
441           
442            this->playerPostSpawn(player);
443        }
444        else
445        {
446            orxout(user_error) << "No SpawnPoints in current Gametype" << endl;
447            abort();
448        }
449    }
450
451    void Gametype::spawnPlayerAsDefaultPawn(PlayerInfo* player)
452    {
453        SpawnPoint* spawn = this->getBestSpawnPoint(player);
454        if (spawn)
455        {
456            // force spawn at spawnpoint with default pawn
457            ControllableEntity* entity = this->defaultControllableEntity_.fabricate(spawn);
458            spawn->spawn(entity);
459            player->startControl(entity);
460        }
461        else
462        {
463            orxout(user_error) << "No SpawnPoints in current Gametype" << endl;
464            abort();
465        }
466    }
467
468    void Gametype::addBots(unsigned int amount)
469    {
470        for (unsigned int i = 0; i < amount; ++i)
471            this->botclass_.fabricate(this);
472    }
473
474    void Gametype::killBots(unsigned int amount)
475    {
476        unsigned int i = 0;
477        for (ObjectList<Bot>::iterator it = ObjectList<Bot>::begin(); (it != ObjectList<Bot>::end()) && ((amount == 0) || (i < amount)); )
478        {
479            if (it->getGametype() == this)
480            {
481                (it++)->destroy();
482                ++i;
483            }
484            else
485                ++it;
486        }
487    }
488
489    void Gametype::addTime(float t)
490    {
491        if (this->timeLimit_ == 0)
492          this->time_ -= t;
493        else
494          this->time_ += t;
495    }
496
497    void Gametype::removeTime(float t)
498    {
499        if (this->timeLimit_ == 0)
500          this->time_ += t;
501        else
502          this->time_ -= t;
503    }
504
505    void Gametype::resetTimer()
506    {
507        this->resetTimer(timeLimit_);
508    }
509
510    void Gametype::resetTimer(float t)
511    {
512        this->timeLimit_ = t;
513        this->time_ = t;
514    }
515}
Note: See TracBrowser for help on using the repository browser.