Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/gametypes/LastTeamStanding.cc @ 8858

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

merged output branch back to trunk.

Changes:

  • you have to include util/Output.h instead of util/Debug.h
  • COUT(x) is now called orxout(level)
  • output levels are now defined by an enum instead of numbers. see util/Output.h for the definition
  • it's possible to use output contexts with orxout(level, context). see util/Output.h for some common contexts. you can define more contexts
  • you must use 'endl' at the end of an output message, '\n' does not flush the message

Output levels:

  • instead of COUT(0) use orxout()
  • instead of COUT(1) use orxout(user_error) or orxout(internal_error)
  • instead of COUT(2) use orxout(user_warning) or orxout(internal_warning)
  • instead of COUT(3) use orxout(user_status/user_info) or orxout(internal_status/internal_info)
  • instead of COUT(4) use orxout(verbose)
  • instead of COUT(5) use orxout(verbose_more)
  • instead of COUT(6) use orxout(verbose_ultra)

Guidelines:

  • user_* levels are for the user, visible in the console and the log-file
  • internal_* levels are for developers, visible in the log-file
  • verbose_* levels are for debugging, only visible if the context of the output is activated

Usage in C++:

  • orxout() << "message" << endl;
  • orxout(level) << "message" << endl;
  • orxout(level, context) << "message" << endl;

Usage in Lua:

  • orxout("message")
  • orxout(orxonox.level.levelname, "message")
  • orxout(orxonox.level.levelname, "context", "message")

Usage in Tcl (and in the in-game-console):

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