Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7556 was 7556, checked in by landauf, 14 years ago

eol-style native

  • Property svn:eol-style set to native
File size: 8.1 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
37namespace orxonox
38{
39    CreateUnloadableFactory(LastManStanding);
40
41    LastManStanding::LastManStanding(BaseObject* creator) : Gametype(creator)
42    {
43        RegisterObject(LastManStanding);
44        this->bForceSpawn_=true;
45        this->lives=4;
46        this->playersAlive=0;
47        this->timeRemaining=20.0f;
48    }
49
50    void LastManStanding::spawnDeadPlayersIfRequested()
51    {
52        for (std::map<PlayerInfo*, Player>::iterator it = this->players_.begin(); it != this->players_.end(); ++it)
53            if (it->second.state_ == PlayerState::Dead)
54            {
55                bool alive = (0<playerLives_[it->first]);
56                if (alive&&(it->first->isReadyToSpawn() || this->bForceSpawn_))
57                    this->spawnPlayer(it->first);
58             }
59    }
60
61
62    void LastManStanding::setConfigValues()
63    {
64        SetConfigValue(lives, 4);
65        SetConfigValue(timeRemaining, 20.0f);
66    }
67
68    bool LastManStanding::allowPawnDamage(Pawn* victim, Pawn* originator)
69    {
70        if (originator && originator->getPlayer())// only for safety
71        {
72            this->timeToAct_[originator->getPlayer()]=timeRemaining;
73        }
74
75        return true;
76    }
77
78    bool LastManStanding::allowPawnDeath(Pawn* victim, Pawn* originator)
79    {
80        if (!victim||!victim->getPlayer())// only for safety
81            return true;
82        playerLives_[victim->getPlayer()]=playerLives_[victim->getPlayer()]-1;
83        if (playerLives_[victim->getPlayer()]<=0)//if player lost all lives
84        {
85            this->playersAlive--;
86            const std::string& message = victim->getPlayer()->getName() + " has lost all lives";
87            COUT(0) << message << std::endl;
88            Host::Broadcast(message);
89        }
90        return true;
91    }
92
93    void LastManStanding::start()
94    {
95        Gametype::start();
96
97        std::string message("Try to survive!");
98        COUT(0) << message << std::endl;
99        Host::Broadcast(message);
100    }
101
102    void LastManStanding::end()
103    {
104        Gametype::end();
105       
106        for (std::map<PlayerInfo*, int>::iterator it = this->playerLives_.begin(); it != this->playerLives_.end(); ++it)
107        {
108            if (it->first->getClientID() == CLIENTID_UNKNOWN)
109                continue;
110
111            if (it->second > 0)
112                this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID());
113            else
114                this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID());
115        }
116    }
117
118    void LastManStanding::playerEntered(PlayerInfo* player)
119    {
120        if (!player)// only for safety
121            return;
122        Gametype::playerEntered(player);
123
124        playerLives_[player]=lives;
125        this->playersAlive++;
126        this->timeToAct_[player]=timeRemaining;
127        const std::string& message = player->getName() + " entered the game";
128        COUT(0) << message << std::endl;
129        Host::Broadcast(message);
130    }
131
132    bool LastManStanding::playerLeft(PlayerInfo* player)
133    {
134        bool valid_player = Gametype::playerLeft(player);
135
136        if (valid_player)
137        {
138            this->playersAlive--;
139            //this->playerLives_[player].erase (player); not necessary?
140            //
141            const std::string& message = player->getName() + " left the game";
142            COUT(0) << message << std::endl;
143            Host::Broadcast(message);
144        }
145
146        return valid_player;
147    }
148
149    bool LastManStanding::playerChangedName(PlayerInfo* player)
150    {
151        bool valid_player = Gametype::playerChangedName(player);
152
153        if (valid_player)
154        {
155            const std::string& message = player->getOldName() + " changed name to " + player->getName();
156            COUT(0) << message << std::endl;
157            Host::Broadcast(message);
158        }
159
160        return valid_player;
161    }
162
163    void LastManStanding::pawnKilled(Pawn* victim, Pawn* killer)
164    {
165        if (victim && victim->getPlayer())
166        {
167            std::string message;
168            if (killer)
169            {
170                if (killer->getPlayer())
171                    message = victim->getPlayer()->getName() + " was killed by " + killer->getPlayer()->getName();
172                else
173                    message = victim->getPlayer()->getName() + " was killed";
174            }
175            else
176                message = victim->getPlayer()->getName() + " died";
177
178            COUT(0) << message << std::endl;
179            Host::Broadcast(message);
180        }
181
182        Gametype::pawnKilled(victim, killer);
183    }
184
185    const int LastManStanding::playerGetLives(PlayerInfo* player)
186    {
187        if (player)
188            return  playerLives_[player];
189        else
190            return 0;
191    }
192    /*BUG-Description:
193    *There are two ways for a player to be killed: Either receiving damage, or through the following function.
194    *The function works fine - until the last call, when a player looses his last live. Than the kill part
195    *(it->second.state_ = PlayerState::Dead;) somehow isn't executed:
196    *The player isn't killed (he doesn't leave play). Although the corresponding code is reached.
197    *
198    *How to reproduce this bug: Start a new Lastmanstanding-Match. Immdiately add 8 bots(before actually entering the level).
199    *Just fly around and wait. Don't shoot, since only passive behaviour triggers the killPlayer-Function.
200    */
201    void LastManStanding::killPlayer(PlayerInfo* player)
202    {
203        if(!player)
204            return;
205        std::map<PlayerInfo*, Player>::iterator it = this->players_.find(player);
206        if (it != this->players_.end())
207        {
208            if (playerLives_[player]<=1)//if player lost all lives
209            {
210                this->playersAlive--;
211                const std::string& message = player->getName() + " is out";
212                COUT(0) << message << std::endl;
213                Host::Broadcast(message);
214                playerLives_[player]=playerLives_[player]-1;//-----------datapart
215                it->second.killed_++;
216                it->second.state_ = PlayerState::Dead;//-------------killpart
217            }
218            else
219            {
220                playerLives_[player]=playerLives_[player]-1;//-----------datapart
221                it->second.killed_++;
222                it->second.state_ = PlayerState::Dead;//-------------killpart
223
224                this->timeToAct_[player]=timeRemaining+3.0f;//reset timer
225            }
226        }
227    }
228   
229
230    void LastManStanding::tick(float dt)
231    {
232        SUPER(LastManStanding, tick, dt);
233        if(!this->hasEnded())
234        {
235            if ((this->hasStarted()&&(playersAlive==1)))//last player remaining
236            {
237            this->end();
238            }
239            for (std::map<PlayerInfo*, float>::iterator it = this->timeToAct_.begin(); it != this->timeToAct_.end(); ++it)
240            {       
241                it->second-=dt;
242                if (it->second<0.0f)
243                {
244                    it->second=timeRemaining+3.0f;//reset timer
245                    if (playerGetLives(it->first)>0)
246                        this->killPlayer(it->first);
247                }
248            }
249        }
250    }
251
252}
Note: See TracBrowser for help on using the repository browser.