Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 8351 was 8351, checked in by rgrieder, 13 years ago

Merged kicklib2 branch back to trunk (includes former branches ois_update, mac_osx and kicklib).

Notes for updating

Linux:
You don't need an extra package for CEGUILua and Tolua, it's already shipped with CEGUI.
However you do need to make sure that the OgreRenderer is installed too with CEGUI 0.7 (may be a separate package).
Also, Orxonox now recognises if you install the CgProgramManager (a separate package available on newer Ubuntu on Debian systems).

Windows:
Download the new dependency packages versioned 6.0 and use these. If you have problems with that or if you don't like the in game console problem mentioned below, you can download the new 4.3 version of the packages (only available for Visual Studio 2005/2008).

Key new features:

  • *Support for Mac OS X*
  • Visual Studio 2010 support
  • Bullet library update to 2.77
  • OIS library update to 1.3
  • Support for CEGUI 0.7 —> Support for Arch Linux and even SuSE
  • Improved install target
  • Compiles now with GCC 4.6
  • Ogre Cg Shader plugin activated for Linux if available
  • And of course lots of bug fixes

There are also some regressions:

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