Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/lastmanstanding/src/orxonox/gametypes/LastManStanding.cc @ 7596

Last change on this file since 7596 was 7596, checked in by jo, 14 years ago

Respawn delay added. One new bug has to be removed.

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