/* * ORXONOX - the hottest 3D action shooter ever to exist * > www.orxonox.net < * * * License notice: * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * Author: * Johannes Ritz * Co-authors: * ... * */ #include "LastManStanding.h" #include "core/CoreIncludes.h" #include "network/Host.h" #include "infos/PlayerInfo.h" #include "worldentities/pawns/Pawn.h" #include "core/ConfigValueIncludes.h" #include "util/Convert.h" namespace orxonox { CreateUnloadableFactory(LastManStanding); LastManStanding::LastManStanding(BaseObject* creator) : Deathmatch(creator) { RegisterObject(LastManStanding); this->bForceSpawn_=true; this->lives=4; this->playersAlive=0; this->timeRemaining=20.0f; this->setHUDTemplate("LastmanstandingHUD"); } void LastManStanding::spawnDeadPlayersIfRequested() { for (std::map::iterator it = this->players_.begin(); it != this->players_.end(); ++it) if (it->second.state_ == PlayerState::Dead) { bool alive = (0first]); if (alive&&(it->first->isReadyToSpawn() || this->bForceSpawn_)) this->spawnPlayer(it->first); } } void LastManStanding::setConfigValues() { SetConfigValue(lives, 4); SetConfigValue(timeRemaining, 20.0f); } bool LastManStanding::allowPawnDamage(Pawn* victim, Pawn* originator) { if (originator && originator->getPlayer())// only for safety { this->timeToAct_[originator->getPlayer()]=timeRemaining; } return true; } bool LastManStanding::allowPawnDeath(Pawn* victim, Pawn* originator) { if (!victim||!victim->getPlayer())// only for safety return true; playerLives_[victim->getPlayer()]=playerLives_[victim->getPlayer()]-1; if (playerLives_[victim->getPlayer()]<=0)//if player lost all lives { this->playersAlive--; const std::string& message = victim->getPlayer()->getName() + " has lost all lives"; COUT(0) << message << std::endl; Host::Broadcast(message); } return true; } void LastManStanding::end() { Gametype::end(); for (std::map::iterator it = this->playerLives_.begin(); it != this->playerLives_.end(); ++it) { if (it->first->getClientID() == CLIENTID_UNKNOWN) continue; if (it->second > 0) this->gtinfo_->sendAnnounceMessage("You have won the match!", it->first->getClientID()); else this->gtinfo_->sendAnnounceMessage("You have lost the match!", it->first->getClientID()); } } void LastManStanding::playerEntered(PlayerInfo* player) { if (!player)// only for safety return; Deathmatch::playerEntered(player); playerLives_[player]=lives; this->playersAlive++; this->timeToAct_[player]=timeRemaining; //Update: EachPlayer's "Players in Game"-HUD for (std::map::iterator it = this->players_.begin(); it != this->players_.end(); ++it) { if (it->first->getClientID() == CLIENTID_UNKNOWN) continue; const std::string& message1 = "Remaining Players: "+ multi_cast(playersAlive); this->gtinfo_->sendStaticMessage(message1,it->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f)); } } bool LastManStanding::playerLeft(PlayerInfo* player) { bool valid_player = Deathmatch::playerLeft(player); if (valid_player) { this->playersAlive--; //this->playerLives_[player].erase (player); not necessary? //Update: EachPlayer's "Players in Game"-HUD for (std::map::iterator it = this->players_.begin(); it != this->players_.end(); ++it) { if (it->first->getClientID() == CLIENTID_UNKNOWN) continue; const std::string& message1 = "Remaining Players: "+ multi_cast(playersAlive); this->gtinfo_->sendStaticMessage(message1,it->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f)); } } return valid_player; } void LastManStanding::playerStartsControllingPawn(PlayerInfo* player, Pawn* pawn) { if (!player) return; this->timeToAct_[player]=timeRemaining+3.0f;//reset timer //Update: Individual Players "lifes"-HUD std::map::iterator it2 = this->players_.find(player); if (it2 != this->players_.end()) { const std::string& message = "Your Lives: " +multi_cast(playerLives_[player]); this->gtinfo_->sendFadingMessage(message,it2->first->getClientID()); } } void LastManStanding::playerStopsControllingPawn(PlayerInfo* player, Pawn* pawn) { //Update: EachPlayer's "Players in Game"-HUD for (std::map::iterator it = this->players_.begin(); it != this->players_.end(); ++it) { if (it->first->getClientID() == CLIENTID_UNKNOWN) continue; const std::string& message1 = "Remaining Players : "+ multi_cast(playersAlive); this->gtinfo_->sendStaticMessage(message1,it->first->getClientID(),ColourValue(1.0f, 1.0f, 0.5f)); } } const int LastManStanding::playerGetLives(PlayerInfo* player) { if (player) return playerLives_[player]; else return 0; } void LastManStanding::killPlayer(PlayerInfo* player) { if(!player) return; std::map::iterator it = this->players_.find(player); if (it != this->players_.end()) { if(!player->getControllableEntity()) {return;} Pawn* pawn = dynamic_cast(player->getControllableEntity()); if(!pawn) {return;} pawn->kill(); this->timeToAct_[player]=timeRemaining+3.0f;//reset timer } } void LastManStanding::tick(float dt) { SUPER(LastManStanding, tick, dt); if(this->hasStarted()&&(!this->hasEnded())) { if ((this->hasStarted()&&(playersAlive<=1)))//last player remaining { this->end(); } for (std::map::iterator it = this->timeToAct_.begin(); it != this->timeToAct_.end(); ++it) { it->second-=dt; if (it->secondgtinfo_->sendFadingMessage(message,it->first->getClientID()); } if (it->second<0.0f) { it->second=timeRemaining+3.0f;//reset timer if (playerGetLives(it->first)>0) this->killPlayer(it->first); } } } } }