/* base/racetrack.cc This file is part of the Osirion project and is distributed under the terms and conditions of the GNU General Public License version 2 */ #include #include #include "base/racetrack.h" #include "core/gameserver.h" namespace base { /* ---- class CheckPoint ------------------------------------------- */ CheckPoint::CheckPoint(RaceTrack *parent) { entity_eventstate = core::Entity::NoPower; parent_track = parent; if (parent) { entity_color = parent->color(); entity_color_second = parent->color_second(); set_zone(parent->zone()); parent->add_checkpoint(this); } else { die(); } } CheckPoint::~CheckPoint() { } /* ---- class RaceTrack -------------------------------------------- */ RaceTrack::RaceTrack() { track_player = 0; track_racestart = 0; track_checkpointtime = 0; entity_eventstate = core::Entity::NoPower; } RaceTrack::~RaceTrack() { track_checkpoints.clear(); } void RaceTrack::add_checkpoint(CheckPoint *checkpoint) { track_checkpoints.push_back(checkpoint); } void RaceTrack::reset() { if (track_player) { track_player->set_mission_target(0); } track_player = 0; track_racestart = 0; track_checkpointtime = 0; for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { (*cpit)->set_eventstate(core::Entity::NoPower); } set_eventstate(core::Entity::NoPower); } void RaceTrack::frame(float seconds) { if (!track_checkpoints.size()) return; if (!track_player) { // FIXME this should go through proper collision detection for (core::GameServer::Players::iterator it = core::server()->players().begin(); it != core::server()->players().end(); ++it) { if ((*it)->control() && (*it)->control()->zone() == zone()) { if (math::distance((*it)->control()->location(), location()) <= 1) { track_player = (*it); track_racestart = core::server()->time(); set_eventstate(core::Entity::Normal); for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { set_eventstate(core::Entity::Normal); } entity_timer = 5.0f; std::string message("^B"); message.append(track_player->name()); message.append(" ^Bactivated the race! Race starts in 5..."); core::server()->broadcast(message); track_player->set_mission_target(this); return; } } } return; } // FIXME this should go into a proper general function // validate current player core::Player *player = 0; for (core::GameServer::Players::iterator pit = core::server()->players().begin(); (!player) && (pit != core::server()->players().end()); ++pit) { if ((*pit) == track_player) { player = (*pit); } } if (!player) { reset(); return; } if (!player->control() || (player->control()->zone() != zone())) { reset(); return; } if (entity_timer) { if (math::distance(player->control()->location(), location()) > 1) { std::string message("^BNo cheating!"); core::server()->broadcast(message); reset(); return; } if (track_racestart + 1.0f <= core::server()->time()) { entity_timer -= 1.0f; entity_dirty = true; if (entity_timer > 0) { std::stringstream msgstr; msgstr << "^B" << entity_timer << "..."; core::server()->broadcast(msgstr.str()); track_racestart = core::server()->time(); } else { for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { (*cpit)->set_eventstate(core::Entity::NoPower); } std::string message("^BGo!"); core::server()->broadcast(message); track_racestart = core::server()->time(); track_checkpointtime = core::server()->time() + 15.0f; track_checkpoint = track_checkpoints.begin(); (*track_checkpoint)->set_eventstate(core::Entity::Normal); track_player->set_mission_target((*track_checkpoint)); } } } else { if (core::server()->time() > track_checkpointtime) { std::string message("^BToo slow, race lost!"); core::server()->broadcast(message); reset(); return; } if (math::distance(track_player->control()->location(), (*track_checkpoint)->location()) <= 1) { CheckPoints::iterator next_checkpoint = track_checkpoint; next_checkpoint++; if (next_checkpoint != track_checkpoints.end()) { std::string message("^BCheckpoint!"); core::server()->broadcast(message); track_checkpointtime = core::server()->time() + 15.0f; (*track_checkpoint)->set_eventstate(core::Entity::NoPower); track_checkpoint++; (*track_checkpoint)->set_eventstate(core::Entity::Normal); track_player->set_mission_target((*track_checkpoint)); } else { std::stringstream msgstr; msgstr << "^BRace completed in " << core::server()->time() - track_racestart << " seconds!"; core::server()->broadcast(msgstr.str()); reset(); } } } } }