Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/gametypes/LastManStanding.cc @ 9348

Last change on this file since 9348 was 9348, checked in by landauf, 12 years ago

merged branch presentation2012merge back to trunk

  • Property svn:eol-style set to native
File size: 9.8 KB
RevLine 
[7480]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 *      Johannes Ritz
24 *   Co-authors:
25 *      ...
26 *
27 */
[7485]28
[7480]29#include "LastManStanding.h"
30
31#include "core/CoreIncludes.h"
[8858]32#include "chat/ChatManager.h"
[7480]33#include "infos/PlayerInfo.h"
34#include "worldentities/pawns/Pawn.h"
35#include "core/ConfigValueIncludes.h"
[7579]36#include "util/Convert.h"
[7605]37
[7480]38namespace orxonox
39{
40    CreateUnloadableFactory(LastManStanding);
41
[7583]42    LastManStanding::LastManStanding(BaseObject* creator) : Deathmatch(creator)
[7480]43    {
44        RegisterObject(LastManStanding);
45        this->bForceSpawn_=true;
[7485]46        this->lives=4;
[7480]47        this->playersAlive=0;
[7602]48        this->timeRemaining=15.0f;
[7596]49        this->respawnDelay=4.0f;
[7617]50        this->bNoPunishment=false;
51        this->bHardPunishment=false;
[7605]52        this->punishDamageRate=0.4f;
[7579]53        this->setHUDTemplate("LastmanstandingHUD");
[7480]54    }
55
[7542]56    void LastManStanding::spawnDeadPlayersIfRequested()
57    {
58        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
59            if (it->second.state_ == PlayerState::Dead)
60            {
[7596]61                bool alive = (0<playerLives_[it->first]&&(inGame_[it->first]));
[7542]62                if (alive&&(it->first->isReadyToSpawn() || this->bForceSpawn_))
[7596]63                {
[7542]64                    this->spawnPlayer(it->first);
[7596]65                }
66            }
[7542]67    }
68
69
[7480]70    void LastManStanding::setConfigValues()
71    {
[7485]72        SetConfigValue(lives, 4);
[7602]73        SetConfigValue(timeRemaining, 15.0f);
[7596]74        SetConfigValue(respawnDelay, 4.0f);
[7617]75        SetConfigValue(bNoPunishment, false);
76        SetConfigValue(bHardPunishment, false);
[7480]77    }
78
79    bool LastManStanding::allowPawnDamage(Pawn* victim, Pawn* originator)
80    {
81        if (originator && originator->getPlayer())// only for safety
82        {
83            this->timeToAct_[originator->getPlayer()]=timeRemaining;
[7605]84
85            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(originator->getPlayer());
86            if (it != this->players_.end())
87            {
[8327]88                if (it->first->getClientID()== NETWORK_PEER_ID_UNKNOWN)
[7605]89                    return true;
[7617]90                const std::string& message = ""; // resets Camper-Warning-message
[7605]91                this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
[8858]92            }
[7480]93        }
94        return true;
95    }
96
97    bool LastManStanding::allowPawnDeath(Pawn* victim, Pawn* originator)
98    {
[7542]99        if (!victim||!victim->getPlayer())// only for safety
[7480]100            return true;
[7542]101        playerLives_[victim->getPlayer()]=playerLives_[victim->getPlayer()]-1;
[7596]102        this->inGame_[victim->getPlayer()]=false;//if player dies he, isn't allowed to respawn immediately
[7542]103        if (playerLives_[victim->getPlayer()]<=0)//if player lost all lives
[7480]104        {
105            this->playersAlive--;
106            const std::string& message = victim->getPlayer()->getName() + " has lost all lives";
[8858]107            ChatManager::message(message);
[7480]108        }
[7640]109
[7480]110        return true;
111    }
112
[7605]113    int LastManStanding::getMinLives()
114    {
115        int min=lives;
116        for (std::map<PlayerInfo*, int>::iterator it = this->playerLives_.begin(); it != this->playerLives_.end(); ++it)
117        {
118            if (it->second<=0)
119                continue;
120            if (it->second<lives)
121                min=it->second;
122        }
123        return min;
124    }
125
[7480]126    void LastManStanding::end()
127    {
128        Gametype::end();
[8858]129
[7480]130        for (std::map<PlayerInfo*, int>::iterator it = this->playerLives_.begin(); it != this->playerLives_.end(); ++it)
131        {
[8327]132            if (it->first->getClientID() == NETWORK_PEER_ID_UNKNOWN)
[7480]133                continue;
134
135            if (it->second > 0)
136                this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
137            else
138                this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
139        }
140    }
141
[7636]142    int LastManStanding::playerGetLives(PlayerInfo* player)
[7635]143    {
144        if (player)
145            return  playerLives_[player];
146        else
147            return 0;
148    }
[8858]149
[7636]150    int LastManStanding::getNumPlayersAlive() const
151    {
152        return this->playersAlive;
153    }
[7635]154
[7480]155    void LastManStanding::playerEntered(PlayerInfo* player)
156    {
157        if (!player)// only for safety
158            return;
[7583]159        Deathmatch::playerEntered(player);
[7605]160        if (playersAlive<=1)
161            playerLives_[player]=lives;
162        else
163            playerLives_[player]=getMinLives();//new players only get minimum of lives
[7480]164        this->playersAlive++;
165        this->timeToAct_[player]=timeRemaining;
[7596]166        this->playerDelayTime_[player]=respawnDelay;
167        this->inGame_[player]=true;
[7480]168    }
169
170    bool LastManStanding::playerLeft(PlayerInfo* player)
171    {
[7583]172        bool valid_player = Deathmatch::playerLeft(player);
[7480]173        if (valid_player)
174        {
175            this->playersAlive--;
[7605]176            this->playerLives_.erase (player);
177            this->playerDelayTime_.erase (player);
178            this->inGame_.erase (player);
[7642]179            this->timeToAct_.erase(player);
[7480]180        }
181
182        return valid_player;
183    }
184
[7579]185    void LastManStanding::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
186    {
187        if (!player)
188            return;
[7596]189        this->timeToAct_[player]=timeRemaining+3.0f+respawnDelay;//reset timer
190        this->playerDelayTime_[player]=respawnDelay;
[8858]191
[7640]192        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
193        if (it != this->players_.end())
[7579]194        {
[8327]195            if (it->first->getClientID()== NETWORK_PEER_ID_UNKNOWN)
[7596]196                return;
[7640]197            const std::string& message = ""; // resets Camper-Warning-message
198            this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
[8858]199        }
[7579]200    }
201
[7605]202    void LastManStanding::punishPlayer(PlayerInfo* player)
[7480]203    {
204        if(!player)
205            return;
[7617]206        if(bNoPunishment)
[7605]207            return;
[7543]208        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
[7480]209        if (it != this->players_.end())
210        {
[7581]211            if(!player->getControllableEntity())
[7605]212                return;
[9348]213            Pawn* pawn = orxonox_cast<Pawn*>(player->getControllableEntity());
[7581]214            if(!pawn)
[7605]215                return;
[7617]216            if(bHardPunishment)
[7605]217            {
218                pawn->kill();
219                this->timeToAct_[player]=timeRemaining+3.0f+respawnDelay;//reset timer
220            }
[7617]221            else
[7605]222            {
[8234]223                float damage=pawn->getMaxHealth()*punishDamageRate*0.5f;//TODO: Factor 0.5 is hard coded. Where is the ratio between MaxHealth actually defined?
[7605]224                pawn->removeHealth(damage);
225                this->timeToAct_[player]=timeRemaining;//reset timer
[7617]226            }
[7480]227        }
228    }
[7605]229
[7480]230    void LastManStanding::tick(float dt)
231    {
232        SUPER(LastManStanding, tick, dt);
[7581]233        if(this->hasStarted()&&(!this->hasEnded()))
[7480]234        {
[7581]235            if ((this->hasStarted()&&(playersAlive<=1)))//last player remaining
[7480]236            {
[7605]237                this->end();
[7480]238            }
239            for (std::map<PlayerInfo*, float>::iterator it = this->timeToAct_.begin(); it != this->timeToAct_.end(); ++it)
[8858]240            {
[7596]241                if (playerGetLives(it->first)<=0)//Players without lives shouldn't be affected by time.
[8858]242                    continue;
[7596]243                it->second-=dt;//Decreases punishment time.
[8858]244                if (!inGame_[it->first])//Manages respawn delay - player is forced to respawn after the delaytime is used up.
[7585]245                {
[7596]246                    playerDelayTime_[it->first]-=dt;
247                    if (playerDelayTime_[it->first]<=0)
248                    this->inGame_[it->first]=true;
[7605]249
[8327]250                    if (it->first->getClientID()== NETWORK_PEER_ID_UNKNOWN)
[7605]251                        continue;
[8234]252                    int output=1+(int)playerDelayTime_[it->first];
[7605]253                    const std::string& message = "Respawn in " +multi_cast<std::string>(output)+ " seconds." ;//Countdown
254                    this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
[7585]255                }
[7596]256                else if (it->second<0.0f)
[7480]257                {
[7596]258                    it->second=timeRemaining+3.0f;//reset punishment-timer
[7542]259                    if (playerGetLives(it->first)>0)
[7617]260                    {
[7605]261                        this->punishPlayer(it->first);
[8327]262                        if (it->first->getClientID()== NETWORK_PEER_ID_UNKNOWN)
[7617]263                            return;
264                        const std::string& message = ""; // resets Camper-Warning-message
265                        this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
266                    }
[7480]267                }
[7605]268                else if (it->second<timeRemaining/5)//Warning message
[7596]269                {
[8327]270                    if (it->first->getClientID()== NETWORK_PEER_ID_UNKNOWN)
[7600]271                        continue;
[7596]272                    const std::string& message = "Camper Warning! Don't forget to shoot.";
273                    this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
274                }
[7480]275            }
276        }
277    }
278
279}
Note: See TracBrowser for help on using the repository browser.