Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8327 was 8327, checked in by scheusso, 13 years ago

merging network6 into trunk

  • Property svn:eol-style set to native
File size: 9.8 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            }
67    }
68
69
70    void LastManStanding::setConfigValues()
71    {
72        SetConfigValue(lives, 4);
73        SetConfigValue(timeRemaining, 15.0f);
74        SetConfigValue(respawnDelay, 4.0f);
75        SetConfigValue(bNoPunishment, false);
76        SetConfigValue(bHardPunishment, false);
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;
84
85            std::map<PlayerInfo*, Player>::iterator it = this->players_.find(originator->getPlayer());
86            if (it != this->players_.end())
87            {
88                if (it->first->getClientID()== NETWORK_PEER_ID_UNKNOWN)
89                    return true;
90                const std::string& message = ""; // resets Camper-Warning-message
91                this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
92            }   
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
111        return true;
112    }
113
114    int LastManStanding::getMinLives()
115    {
116        int min=lives;
117        for (std::map<PlayerInfo*, int>::iterator it = this->playerLives_.begin(); it != this->playerLives_.end(); ++it)
118        {
119            if (it->second<=0)
120                continue;
121            if (it->second<lives)
122                min=it->second;
123        }
124        return min;
125    }
126
127    void LastManStanding::end()
128    {
129        Gametype::end();
130       
131        for (std::map<PlayerInfo*, int>::iterator it = this->playerLives_.begin(); it != this->playerLives_.end(); ++it)
132        {
133            if (it->first->getClientID() == NETWORK_PEER_ID_UNKNOWN)
134                continue;
135
136            if (it->second > 0)
137                this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
138            else
139                this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
140        }
141    }
142
143    int LastManStanding::playerGetLives(PlayerInfo* player)
144    {
145        if (player)
146            return  playerLives_[player];
147        else
148            return 0;
149    }
150   
151    int LastManStanding::getNumPlayersAlive() const
152    {
153        return this->playersAlive;
154    }
155
156    void LastManStanding::playerEntered(PlayerInfo* player)
157    {
158        if (!player)// only for safety
159            return;
160        Deathmatch::playerEntered(player);
161        if (playersAlive<=1)
162            playerLives_[player]=lives;
163        else
164            playerLives_[player]=getMinLives();//new players only get minimum of lives
165        this->playersAlive++;
166        this->timeToAct_[player]=timeRemaining;
167        this->playerDelayTime_[player]=respawnDelay;
168        this->inGame_[player]=true;
169    }
170
171    bool LastManStanding::playerLeft(PlayerInfo* player)
172    {
173        bool valid_player = Deathmatch::playerLeft(player);
174        if (valid_player)
175        {
176            this->playersAlive--;
177            this->playerLives_.erase (player);
178            this->playerDelayTime_.erase (player);
179            this->inGame_.erase (player);
180            this->timeToAct_.erase(player);
181        }
182
183        return valid_player;
184    }
185
186    void LastManStanding::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn)
187    {
188        if (!player)
189            return;
190        this->timeToAct_[player]=timeRemaining+3.0f+respawnDelay;//reset timer
191        this->playerDelayTime_[player]=respawnDelay;
192       
193        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
194        if (it != this->players_.end())
195        {
196            if (it->first->getClientID()== NETWORK_PEER_ID_UNKNOWN)
197                return;
198            const std::string& message = ""; // resets Camper-Warning-message
199            this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
200        } 
201    }
202
203    void LastManStanding::punishPlayer(PlayerInfo* player)
204    {
205        if(!player)
206            return;
207        if(bNoPunishment)
208            return;
209        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
210        if (it != this->players_.end())
211        {
212            if(!player->getControllableEntity())
213                return;
214            Pawn* pawn = dynamic_cast<Pawn*>(player->getControllableEntity());
215            if(!pawn)
216                return;
217            if(bHardPunishment)
218            {
219                pawn->kill();
220                this->timeToAct_[player]=timeRemaining+3.0f+respawnDelay;//reset timer
221            }
222            else
223            {
224                float damage=pawn->getMaxHealth()*punishDamageRate*0.5f;//TODO: Factor 0.5 is hard coded. Where is the ratio between MaxHealth actually defined?
225                pawn->removeHealth(damage);
226                this->timeToAct_[player]=timeRemaining;//reset timer
227            }
228        }
229    }
230
231    void LastManStanding::tick(float dt)
232    {
233        SUPER(LastManStanding, tick, dt);
234        if(this->hasStarted()&&(!this->hasEnded()))
235        {
236            if ((this->hasStarted()&&(playersAlive<=1)))//last player remaining
237            {
238                this->end();
239            }
240            for (std::map<PlayerInfo*, float>::iterator it = this->timeToAct_.begin(); it != this->timeToAct_.end(); ++it)
241            {   
242                if (playerGetLives(it->first)<=0)//Players without lives shouldn't be affected by time.
243                    continue;     
244                it->second-=dt;//Decreases punishment time.
245                if (!inGame_[it->first])//Manages respawn delay - player is forced to respawn after the delaytime is used up.
246                {
247                    playerDelayTime_[it->first]-=dt;
248                    if (playerDelayTime_[it->first]<=0)
249                    this->inGame_[it->first]=true;
250
251                    if (it->first->getClientID()== NETWORK_PEER_ID_UNKNOWN)
252                        continue;
253                    int output=1+(int)playerDelayTime_[it->first];
254                    const std::string& message = "Respawn in " +multi_cast<std::string>(output)+ " seconds." ;//Countdown
255                    this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
256                }
257                else if (it->second<0.0f)
258                {
259                    it->second=timeRemaining+3.0f;//reset punishment-timer
260                    if (playerGetLives(it->first)>0)
261                    {
262                        this->punishPlayer(it->first);
263                        if (it->first->getClientID()== NETWORK_PEER_ID_UNKNOWN)
264                            return;
265                        const std::string& message = ""; // resets Camper-Warning-message
266                        this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
267                    }
268                }
269                else if (it->second<timeRemaining/5)//Warning message
270                {
271                    if (it->first->getClientID()== NETWORK_PEER_ID_UNKNOWN)
272                        continue;
273                    const std::string& message = "Camper Warning! Don't forget to shoot.";
274                    this->gtinfo_->sendFadingMessage(message,it->first->getClientID());
275                }
276            }
277        }
278    }
279
280}
Note: See TracBrowser for help on using the repository browser.