Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/output/src/orxonox/gametypes/LastManStanding.cc @ 8829

Last change on this file since 8829 was 8829, checked in by landauf, 13 years ago

enhanced chat system. chat related code is now separated into network-side code (located in Host, Client, Server) and client-side code (located in ChatManager).
note that there are now two chat related listeners: NetworkChatListener, which is used to send chat from the network to ChatManager, and ChatListener, which is used to send online and offline chat from ChatManager to the actual chat interfaces (ChatOverlay, ChatInputHandler, …).
the "chat" console command now supports a second argument which is the clientID of the receiver. this allows private messages (or gameplay messages directed to only one specific player).

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