diff options
-rw-r--r-- | src/game/racetrack.cc | 200 | ||||
-rw-r--r-- | src/game/racetrack.h | 63 |
2 files changed, 263 insertions, 0 deletions
diff --git a/src/game/racetrack.cc b/src/game/racetrack.cc new file mode 100644 index 0000000..31e5b40 --- /dev/null +++ b/src/game/racetrack.cc @@ -0,0 +1,200 @@ +/* + game/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 <string> +#include <sstream> + +#include "game/racetrack.h" +#include "core/gameserver.h" + +namespace game { + +/* ---- 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() +{ + track_player = 0; + track_racestart = 0; + track_checkpointtime = 0; + + for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { + (*cpit)->entity_eventstate |= core::Entity::NoPower; + (*cpit)->entity_dirty = true; + } + + entity_eventstate |= core::Entity::NoPower; + entity_dirty = true; +} + +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(); + entity_eventstate &= (~core::Entity::NoPower); + entity_dirty = true; + + for (CheckPoints::iterator cpit = track_checkpoints.begin(); cpit != track_checkpoints.end(); ++cpit) { + (*cpit)->entity_eventstate &= (~core::Entity::NoPower); + (*cpit)->entity_dirty = true; + } + + 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); + 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)->entity_eventstate |= core::Entity::NoPower; + (*cpit)->entity_dirty = true; + } + 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)->entity_eventstate &= ~core::Entity::NoPower; + (*track_checkpoint)->entity_dirty = true; + } + } + + + } 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)->entity_eventstate |= core::Entity::NoPower; + (*track_checkpoint)->entity_dirty = true; + track_checkpoint++; + (*track_checkpoint)->entity_eventstate &= ~core::Entity::NoPower; + (*track_checkpoint)->entity_dirty = true; + + } else { + std::stringstream msgstr; + msgstr << "^BRace completed in " << core::server()->time() - track_racestart << " seconds!"; + core::server()->broadcast(msgstr.str()); + track_player = 0; + track_racestart = 0; + track_checkpointtime = 0; + + reset(); + } + } + } +} + +} diff --git a/src/game/racetrack.h b/src/game/racetrack.h new file mode 100644 index 0000000..733051a --- /dev/null +++ b/src/game/racetrack.h @@ -0,0 +1,63 @@ +/* + game/racetrack.h + This file is part of the Osirion project and is distributed under + the terms and conditions of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_GAME_RACETRACK_H__ +#define __INCLUDED_GAME_RACETRACK_H__ + +#include "core/entity.h" +#include "core/player.h" +#include "math/mathlib.h" + +#include <string> + +namespace game { + +class CheckPoint; + +/* ---- class RaceTrack -------------------------------------------- */ + +class RaceTrack : public core::EntityDynamic { + +public: + typedef std::list<CheckPoint *> CheckPoints ; + + RaceTrack(); + ~RaceTrack(); + + void add_checkpoint(CheckPoint *checkpoint); + + /// reset the race track + void reset(); + + virtual void frame(float seconds); + + inline core::Player *player() { return track_player; } + +private: + CheckPoints track_checkpoints; + core::Player *track_player; + float track_racestart; + float track_checkpointtime; + CheckPoints::iterator track_checkpoint; + +}; + +/* ---- class CheckPoint ------------------------------------------- */ + +class CheckPoint : public core::EntityDynamic { +public: + CheckPoint(RaceTrack *parent); + ~CheckPoint(); + +private: + RaceTrack *parent_track; +}; + + +} + +#endif // __INCLUDED_GAME_NAVPOINT_H__ + |