Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/lastmanstanding/src/orxonox/gametypes/LastTeamStanding.cc @ 7695

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

that wasnt it either

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