Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7617 was 7617, checked in by jo, 13 years ago

Level is now fixed. Some further minor changes.

  • Property svn:eol-style set to native
File size: 11.9 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
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=15.0f;
49        this->respawnDelay=4.0f;
50        this->bNoPunishment=false;
51        this->bHardPunishment=false;
52        this->punishDamageRate=0.4f;
53        this->setHUDTemplate("LastmanstandingHUD");
54    }
55
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            {
61                bool alive = (0<playerLives_[it->first]&&(inGame_[it->first]));
62                if (alive&&(it->first->isReadyToSpawn() || this->bForceSpawn_))
63                {
64                    this->spawnPlayer(it->first);
65                }
66                else if (0>=playerLives_[it->first])
67                {
68                    if (it->first->getClientID()== CLIENTID_UNKNOWN)
69                        continue;
70                    const std::string& message2 = "You have lost all " +multi_cast<std::string>(lives)+ " lives." ;
71                    this->gtinfo_->sendFadingMessage(message2,it->first->getClientID());
72                }
73            }
74    }
75
76
77    void LastManStanding::setConfigValues()
78    {
79        SetConfigValue(lives, 4);
80        SetConfigValue(timeRemaining, 15.0f);
81        SetConfigValue(respawnDelay, 4.0f);
82        SetConfigValue(bNoPunishment, false);
83        SetConfigValue(bHardPunishment, false);
84    }
85
86    bool LastManStanding::allowPawnDamage(Pawn* victim, Pawn* originator)
87    {
88        if (originator && originator->getPlayer())// only for safety
89        {
90            this->timeToAct_[originator->getPlayer()]=timeRemaining;
91
92            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(originator->getPlayer());
93            if (it != this->players_.end())
94            {
95                if (it->first->getClientID()== CLIENTID_UNKNOWN)
96                    return true;
97                const std::string& message = ""; // resets Camper-Warning-message
98                this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
99            }   
100        }
101        return true;
102    }
103
104    bool LastManStanding::allowPawnDeath(Pawn* victim, Pawn* originator)
105    {
106        if (!victim||!victim->getPlayer())// only for safety
107            return true;
108        playerLives_[victim->getPlayer()]=playerLives_[victim->getPlayer()]-1;
109        this->inGame_[victim->getPlayer()]=false;//if player dies he, isn't allowed to respawn immediately
110        if (playerLives_[victim->getPlayer()]<=0)//if player lost all lives
111        {
112            this->playersAlive--;
113            const std::string& message = victim->getPlayer()->getName() + " has lost all lives";
114            COUT(0) << message << std::endl;
115            Host::Broadcast(message);
116        }
117        return true;
118    }
119
120    int LastManStanding::getMinLives()
121    {
122        int min=lives;
123        for (std::map<PlayerInfo*, int>::iterator it = this->playerLives_.begin(); it != this->playerLives_.end(); ++it)
124        {
125            if (it->second<=0)
126                continue;
127            if (it->second<lives)
128                min=it->second;
129        }
130        return min;
131    }
132
133    void LastManStanding::end()
134    {
135        Gametype::end();
136       
137        for (std::map<PlayerInfo*, int>::iterator it = this->playerLives_.begin(); it != this->playerLives_.end(); ++it)
138        {
139            if (it->first->getClientID() == CLIENTID_UNKNOWN)
140                continue;
141
142            if (it->second > 0)
143                this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
144            else
145                this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
146        }
147    }
148
149
150    void LastManStanding::playerEntered(PlayerInfo* player)
151    {
152        if (!player)// only for safety
153            return;
154        Deathmatch::playerEntered(player);
155        if (playersAlive<=1)
156            playerLives_[player]=lives;
157        else
158            playerLives_[player]=getMinLives();//new players only get minimum of lives
159        this->playersAlive++;
160        this->timeToAct_[player]=timeRemaining;
161        this->playerDelayTime_[player]=respawnDelay;
162        this->inGame_[player]=true;
163        //Update: EachPlayer's "Players in Game"-HUD
164        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
165        {
166            if (it->first->getClientID() == CLIENTID_UNKNOWN)
167                continue;
168            const std::string& message1 = "Remaining Players: "+ multi_cast<std::string>(playersAlive);
169            this->gtinfo_->sendStaticMessage(message1,it->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f));
170        }
171    }
172
173    bool LastManStanding::playerLeft(PlayerInfo* player)
174    {
175        bool valid_player = Deathmatch::playerLeft(player);
176        if (valid_player)
177        {
178            this->playersAlive--;
179            this->playerLives_.erase (player);
180            this->playerDelayTime_.erase (player);
181            this->inGame_.erase (player);
182            //Update: EachPlayer's "Players in Game"-HUD
183            for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
184            {
185                if (it->first->getClientID() == CLIENTID_UNKNOWN)
186                    continue;
187                const std::string& message1 = "Remaining Players: "+ multi_cast<std::string>(playersAlive);
188                this->gtinfo_->sendStaticMessage(message1,it->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f));
189            }
190        }
191
192        return valid_player;
193    }
194
195    void LastManStanding::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
196    {
197        if (!player)
198            return;
199        this->timeToAct_[player]=timeRemaining+3.0f+respawnDelay;//reset timer
200        this->playerDelayTime_[player]=respawnDelay;
201        //Update: Individual Players "lifes"-HUD
202        std::map<PlayerInfo*, Player>::iterator it2 = this->players_.find(player);
203        if (it2 != this->players_.end())
204        {
205            if (it2->first->getClientID()== CLIENTID_UNKNOWN)
206                return;
207            const std::string& message = "Your Lives: " +multi_cast<std::string>(playerLives_[player]);
208            this->gtinfo_->sendFadingMessage(message,it2->first->getClientID());
209            const std::string& message1 = "Remaining Players: "+ multi_cast<std::string>(playersAlive);
210            this->gtinfo_->sendStaticMessage(message1,it2->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f));
211        }
212    }
213
214    void LastManStanding::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn)
215    {
216        //Update: EachPlayer's "Players in Game"-HUD
217        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
218        {
219            if (it->first->getClientID() == CLIENTID_UNKNOWN)
220                continue;
221            const std::string& message1 = "Remaining Players: "+ multi_cast<std::string>(playersAlive);
222            this->gtinfo_->sendStaticMessage(message1,it->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f));
223        }
224    }
225
226    const int LastManStanding::playerGetLives(PlayerInfo* player)
227    {
228        if (player)
229            return  playerLives_[player];
230        else
231            return 0;
232    }
233
234    void LastManStanding::punishPlayer(PlayerInfo* player)
235    {
236        if(!player)
237            return;
238        if(bNoPunishment)
239            return;
240        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
241        if (it != this->players_.end())
242        {
243            if(!player->getControllableEntity())
244                return;
245            Pawn* pawn = dynamic_cast<Pawn*>(player->getControllableEntity());
246            if(!pawn)
247                return;
248            if(bHardPunishment)
249            {
250                pawn->kill();
251                this->timeToAct_[player]=timeRemaining+3.0f+respawnDelay;//reset timer
252            }
253            else
254            {
255                float damage=pawn->getMaxHealth()*punishDamageRate*0.5;//TODO: Factor 0.5 is hard coded. Where is the ratio between MaxHealth actually defined?
256                pawn->removeHealth(damage);
257                this->timeToAct_[player]=timeRemaining;//reset timer
258            }
259        }
260    }
261
262    void LastManStanding::tick(float dt)
263    {
264        SUPER(LastManStanding, tick, dt);
265        if(this->hasStarted()&&(!this->hasEnded()))
266        {
267            if ((this->hasStarted()&&(playersAlive<=1)))//last player remaining
268            {
269                this->end();
270            }
271            for (std::map<PlayerInfo*, float>::iterator it = this->timeToAct_.begin(); it != this->timeToAct_.end(); ++it)
272            {   
273                if (playerGetLives(it->first)<=0)//Players without lives shouldn't be affected by time.
274                    continue;     
275                it->second-=dt;//Decreases punishment time.
276                if (!inGame_[it->first])//Manages respawn delay - player is forced to respawn after the delaytime is used up.
277                {
278                    playerDelayTime_[it->first]-=dt;
279                    if (playerDelayTime_[it->first]<=0)
280                    this->inGame_[it->first]=true;
281
282                    if (it->first->getClientID()== CLIENTID_UNKNOWN)
283                        continue;
284                    int output=1+playerDelayTime_[it->first];
285                    const std::string& message = "Respawn in " +multi_cast<std::string>(output)+ " seconds." ;//Countdown
286                    this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
287                }
288                else if (it->second<0.0f)
289                {
290                    it->second=timeRemaining+3.0f;//reset punishment-timer
291                    if (playerGetLives(it->first)>0)
292                    {
293                        this->punishPlayer(it->first);
294                        if (it->first->getClientID()== CLIENTID_UNKNOWN)
295                            return;
296                        const std::string& message = ""; // resets Camper-Warning-message
297                        this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
298                    }
299                }
300                else if (it->second<timeRemaining/5)//Warning message
301                {
302                    if (it->first->getClientID()== CLIENTID_UNKNOWN)
303                        continue;
304                    const std::string& message = "Camper Warning! Don't forget to shoot.";
305                    this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
306                }
307            }
308        }
309    }
310
311}
Note: See TracBrowser for help on using the repository browser.