/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx 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, or (at your option) any later version. ### File Specific: main-programmer: Patrick Boenzli */ #define DEBUG_MODULE_GAME_RULES #include "multiplayer_team_deathmatch.h" #include "util/loading/load_param.h" #include "util/loading/factory.h" #include "render2D/image_plane.h" #include "state.h" #include "class_list.h" #include "player.h" #include "playable.h" #include "space_ships/space_ship.h" #include "shared_network_data.h" #include "terrain.h" #include "class_list.h" #include "space_ships/space_ship.h" using namespace std; CREATE_FACTORY(MultiplayerTeamDeathmatch, CL_MULTIPLAYER_TEAM_DEATHMATCH); /** * constructor */ MultiplayerTeamDeathmatch::MultiplayerTeamDeathmatch(const TiXmlElement* root) : GameRules(root) { this->setClassID(CL_MULTIPLAYER_TEAM_DEATHMATCH, "MultiplayerTeamDeathmatch"); this->bLocalPlayerDead = false; this->deathTimeout = 10.0f; // 5 seconds this->timeout = 0.0f; this->deathScreen = new ImagePlane(); this->deathScreen->setSize(State::getResX()/4.0, State::getResY()/4.0); this->deathScreen->setAbsCoor2D(State::getResX()/2.0f, State::getResY()/2.0f); this->deathScreen->setVisibility(false); this->localPlayer = State::getPlayer(); if( root != NULL) this->loadParams(root); } /** * decontsructor */ MultiplayerTeamDeathmatch::~MultiplayerTeamDeathmatch() { if( this->deathScreen) delete this->deathScreen; } void MultiplayerTeamDeathmatch::loadParams(const TiXmlElement* root) { GameRules::loadParams(root) ; LoadParam(root, "death-penalty-timeout", this, MultiplayerTeamDeathmatch, setDeathPenaltyTimeout) .describe("sets the time in seconds a player has to wait for respawn"); LoadParam(root, "max-kills", this, MultiplayerTeamDeathmatch, setMaxKills) .describe("sets the maximal kills for winning condition"); LoadParam(root, "death-screen-image", this, MultiplayerTeamDeathmatch, setDeathScreen) .describe("sets the death screen image"); } void MultiplayerTeamDeathmatch::setDeathScreen(const std::string& imageName) { if( this->deathScreen) this->deathScreen->setTexture(imageName); } /** * called when the player enters the game * @param player the spawned player */ void MultiplayerTeamDeathmatch::onPlayerSpawn() { this->bLocalPlayerDead = false; this->deathScreen->setVisibility(false); } /** * when the player is killed * @param player the killed player */ void MultiplayerTeamDeathmatch::onPlayerDeath() { this->bLocalPlayerDead = true; this->deathScreen->setVisibility(true); } /** * time tick * @param dt time */ void MultiplayerTeamDeathmatch::tick(float dt) { this->checkGameRules(); // is the local player dead and inactive if( unlikely(this->bLocalPlayerDead)) { this->timeout += dt; PRINTF(0)("TICK DEATH: %f of %f\n", this->timeout, this->deathTimeout); // long enough dead? if( this->timeout >= this->deathTimeout) { this->timeout = 0.0f; // respawn PRINTF(0)("RESPAWN\n"); (State::getPlayer())->getPlayable()->respawn(); } } } /** * draws the stuff */ void MultiplayerTeamDeathmatch::draw() { if( unlikely( this->bLocalPlayerDead)) { } } /** * check the game rules for consistency */ void MultiplayerTeamDeathmatch::checkGameRules() { Vector big_left(-201, 0, 0); float rBig = 176.0f; Vector big_right(177, 0, 0); Vector small_left(10, 0, 0); Vector small_middle(0, 0, 0); Vector small_right(-10, 0, 0); float rSmall = 90.0f; // check for max killing count if( this->teamAKills >= this->maxKills) { // team A winns } else if( this->teamBKills >= this->maxKills) { // team B winns } if ( SharedNetworkData::getInstance()->isGameServer() ) { float offsetx = 500.0f; float offsety = 323.0f; float offsetz = 200.0f; offsetz += 10; Terrain * terrain = dynamic_cast(*(ClassList::getList( CL_TERRAIN )->begin())); const std::list * list = ClassList::getList( CL_SPACE_SHIP ); for ( std::list::const_iterator it = list->begin(); it != list->end(); it++) { SpaceShip * ss = dynamic_cast(*it); float terrx = ss->getAbsCoor().x + offsetx; float terry = ss->getAbsCoor().z + offsetz; float terrz = ss->getAbsCoor().y + offsety; if ( terrz < terrain->getHeight( terrx, terry ) && ss->getAbsCoor().x > -1000 ) { //TODO handle this } float dist = (dynamic_cast(*it)->getAbsCoor() - big_left).len(); if( (dynamic_cast(*it)->getAbsCoor() - big_left).len() > rBig && (dynamic_cast(*it)->getAbsCoor() - big_right).len() > rBig && (dynamic_cast(*it)->getAbsCoor() - small_left).len() > rSmall && (dynamic_cast(*it)->getAbsCoor() - small_middle).len() > rSmall && (dynamic_cast(*it)->getAbsCoor() - small_right).len() > rSmall && ss->getAbsCoor().x > -1000) { PRINTF(0)("KILLLLLLLL\n"); if((*it)->isA(CL_SPACE_SHIP)) { //TODO handle this } } } } #if 0 std::list::const_iterator it; const std::list* list = ClassList::getList(CL_PLAYABLE); if( SharedNetworkData::getInstance()->isGameServer()) { for(it = list->begin(); it != list->end(); it++) { float dist = (dynamic_cast(*it)->getAbsCoor() - big_left).len(); if( (dynamic_cast(*it)->getAbsCoor() - big_left).len() > rBig && (dynamic_cast(*it)->getAbsCoor() - big_right).len() > rBig && (dynamic_cast(*it)->getAbsCoor() - small_left).len() > rSmall && (dynamic_cast(*it)->getAbsCoor() - small_middle).len() > rSmall && (dynamic_cast(*it)->getAbsCoor() - small_right).len() > rSmall) { PRINTF(0)("KILLLLLLLL\n"); if((*it)->isA(CL_SPACE_SHIP)) dynamic_cast(*it)->doCollideNetwork(116369220.33434f); } } } #endif }