Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

New functionality successfully added. No bugs found so far. Only the delaytimer is running a little bit too fast.

  • 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=10.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                        continue;
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                        continue;
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                    continue;     
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                        continue;
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.