diff options
Diffstat (limited to 'src/game')
-rw-r--r-- | src/game/Makefile.am | 5 | ||||
-rw-r--r-- | src/game/game.cc | 76 | ||||
-rw-r--r-- | src/game/game.h | 3 | ||||
-rw-r--r-- | src/game/ship.cc | 137 | ||||
-rw-r--r-- | src/game/ship.h | 5 |
5 files changed, 169 insertions, 57 deletions
diff --git a/src/game/Makefile.am b/src/game/Makefile.am index efa051f..0ff1ba5 100644 --- a/src/game/Makefile.am +++ b/src/game/Makefile.am @@ -2,9 +2,10 @@ INCLUDES = -I$(top_srcdir)/src METASOURCES = AUTO libgame_la_LDFLAGS = -avoid-version -libgame_la_SOURCES = game.cc navpoint.cc planet.cc racetrack.cc ship.cc \ - shipmodel.cc star.cc +libgame_la_SOURCES = game.cc jumppoint.cc navpoint.cc planet.cc racetrack.cc \ + ship.cc shipmodel.cc star.cc noinst_LTLIBRARIES = libgame.la noinst_HEADERS = game.h navpoint.h planet.h racetrack.h ship.h shipmodel.h \ star.h +_SOURCES = jumppoint.h diff --git a/src/game/game.cc b/src/game/game.cc index 3b13767..0502ece 100644 --- a/src/game/game.cc +++ b/src/game/game.cc @@ -5,6 +5,7 @@ */ #include <vector> +#include <string> #include "auxiliary/functions.h" #include "core/gameserver.h" @@ -12,6 +13,7 @@ #include "filesystem/inifile.h" #include "game/game.h" #include "game/navpoint.h" +#include "game/jumppoint.h" #include "game/planet.h" #include "game/racetrack.h" #include "game/ship.h" @@ -289,6 +291,12 @@ bool Game::load_world() } } + for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { + if (!validate_zone((*it).second)) { + return false; + } + } + if (!default_zone) { con_error << "No default zone found!" << std::endl; return false; @@ -318,6 +326,7 @@ bool Game::load_zone(core::Zone *zone) Planet *planet = 0; Star *star = 0; NavPoint *navpoint = 0; + JumpPoint *jumppoint = 0; RaceTrack *racetrack = 0; CheckPoint *checkpoint = 0; core::Entity *entity = 0; @@ -385,6 +394,20 @@ bool Game::load_zone(core::Zone *zone) } else { con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; } + } else if (zoneini.section().compare("jumppoint") == 0) { + if (zoneini.got_key_string("label", strval)) { + aux::to_label(strval); + jumppoint->entity_label.assign(strval); + continue; + } else if (zoneini.got_key_string("name", jumppoint->entity_name)) { + continue; + } else if (zoneini.got_key_string("target", jumppoint->jumppoint_targetlabel)) { + continue; + } else if (zoneini.got_key_vector3f("location", jumppoint->entity_location )) { + continue; + } else { + con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl; + } } else if (zoneini.section().compare("planet") == 0) { if (zoneini.got_key_string("label", strval)) { aux::to_label(strval); @@ -513,6 +536,11 @@ bool Game::load_zone(core::Zone *zone) navpoint->set_zone(zone); count ++; + } else if (zoneini.got_section("jumppoint")) { + jumppoint = new JumpPoint(); + jumppoint->set_zone(zone); + count ++; + } else if(zoneini.got_section("racetrack")) { racetrack = new RaceTrack(); racetrack->set_zone(zone); @@ -542,6 +570,54 @@ bool Game::load_zone(core::Zone *zone) con_debug << " " << zoneini.name() << " " << zone->content().size() << " entities" << std::endl; + + return true; +} + +bool Game::validate_zone(core::Zone *zone) +{ + for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) { + core::Entity *entity = (*it); + + if (entity->entity_moduletypeid == jumppoint_enttype) { + JumpPoint *jumppoint = static_cast<JumpPoint *>(entity); + + if (jumppoint->targetlabel().size() < 3) { + con_warn << " Jumppoint with invalid target label '" << jumppoint->targetlabel() << "'\n"; + continue; + } + size_t pos = jumppoint->targetlabel().find(':'); + if ((pos < 1 ) || (pos >= (jumppoint->targetlabel().size()-1))) { + con_warn << " Jumppoint with invalid target label '" << jumppoint->targetlabel() << "'\n"; + continue; + } + + std::string zonelabel(jumppoint->targetlabel().substr(0, pos)); + std::string entitylabel(jumppoint->targetlabel().substr(pos+1, jumppoint->targetlabel().size()-pos)); + + core::Zone *targetzone = core::Zone::find(zonelabel); + if (!targetzone) { + con_warn << " Jumppoint with invalid target zone '" << zonelabel << "'\n"; + continue; + } + + core::Entity *targetentity = targetzone->find_entity(entitylabel); + if (!targetentity) { + con_warn << " Could not find target jumppoint '" << entitylabel << "'\n"; + continue; + } + + if (targetentity->moduletype() != jumppoint_enttype) { + con_warn << " Jumppoint with invalid target jumppoint '" << entitylabel << "'\n"; + continue; + } + + jumppoint->jumppoint_target = static_cast<JumpPoint *>(targetentity); + + con_debug << " Jump point " << zone->label() << ":" << jumppoint->label() << " with target " << jumppoint->targetlabel() << std::endl; + } + } + return true; } diff --git a/src/game/game.h b/src/game/game.h index be64dd2..c7ec040 100644 --- a/src/game/game.h +++ b/src/game/game.h @@ -28,6 +28,7 @@ const unsigned int ship_enttype = 256; const unsigned int star_enttype = 257; const unsigned int planet_enttype = 258; const unsigned int navpoint_enttype = 259; +const unsigned int jumppoint_enttype = 260; class Game : public core::Module { public: @@ -62,6 +63,8 @@ private: bool load_zone(core::Zone *zone); + bool validate_zone(core::Zone *zone); + bool load_ships(); static Game *game_instance; diff --git a/src/game/ship.cc b/src/game/ship.cc index 167c82a..0dde90e 100644 --- a/src/game/ship.cc +++ b/src/game/ship.cc @@ -38,8 +38,6 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) : ship_shipmodel = shipmodel; ship_jumpdrive = shipmodel->shipmodel_jumpdrive; - ship_jumptargetzone = 0; - ship_impulsedrive_timer = 0; ship_jumpdrive_timer = 0; @@ -71,7 +69,6 @@ void Ship::impulse() if (entity_eventstate == core::Entity::JumpInitiate) { ship_jumpdrive_timer = 0; - ship_jumptargetzone = 0; entity_timer = 0; } @@ -90,58 +87,74 @@ void Ship::impulse() void Ship::jump(std::string const &args) { - if (!jumpdrive() && !Game::instance()->g_devel->value()) { - core::server()->send(owner(), "This ship is not equiped with a hyperspace drive!"); - return; - - } else if (entity_eventstate == core::Entity::Jump) { - return; + // devel mode provides instant jump access to arbitrary systems + if (Game::instance()->g_devel->value() && (args.size())) { + + core::Zone *jumptargetzone = 0; + std::string target; + std::istringstream is(args); + if (!(is >> target)) { + std::string helpstr; + for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { + core::Zone *zone = (*it).second; + if (helpstr.size()) + helpstr.append("^N|^B"); + helpstr.append(zone->label()); + } + + core::server()->send(owner(), "Usage: jump [^B" + helpstr + "^N]"); + return; + } + + aux::to_lowercase(target); + jumptargetzone = core::Zone::find_zone(target); + if (!jumptargetzone) { + core::server()->send(owner(), "Unknown system '" + target + '\''); + return; + } + + if (jumptargetzone == zone()) { + core::server()->send(owner(), "Already in the " + jumptargetzone->name() + '.'); + return; + } + + core::server()->send(owner(), "Jumping to '" + jumptargetzone->name() + '\''); + set_zone(jumptargetzone); + if (owner()->control() == (EntityControlable*) this) + owner()->set_zone(jumptargetzone); - } else if (entity_eventstate == core::Entity::JumpInitiate) { - core::server()->send(owner(), "Jump aborted, hyperspace drive deactivated."); - ship_jumptargetzone = 0; ship_jumpdrive_timer = 0; entity_timer = 0; - entity_eventstate = core::Entity::Normal; + entity_eventstate = core::Entity::Jump; + entity_dirty = true; return; - } - - std::string target; - std::istringstream is(args); - if (!(is >> target)) { - std::string helpstr; - for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) { - core::Zone *zone = (*it).second; - if (helpstr.size()) - helpstr.append("^N|^B"); - helpstr.append(zone->label()); - } - core::server()->send(owner(), "Usage: jump [^B" + helpstr + "^N]"); - return; - } + } else { + if (!jumpdrive() && !Game::instance()->g_devel->value()) { + core::server()->send(owner(), "This ship is not equiped with a hyperspace drive!"); + return; - aux::to_lowercase(target); - ship_jumptargetzone = core::Zone::find_zone(target); - if (!ship_jumptargetzone) { - core::server()->send(owner(), "Unknown system '" + target + '\''); - return; - } + } else if (entity_eventstate == core::Entity::Jump) { + return; - if (ship_jumptargetzone == zone()) { - core::server()->send(owner(), "Already in the " + ship_jumptargetzone->name() + '.'); - ship_jumptargetzone = 0; - return; - } + } else if (entity_eventstate == core::Entity::JumpInitiate) { + core::server()->send(owner(), "Jump aborted, hyperspace drive deactivated."); + ship_jumpdrive_timer = 0; + entity_timer = 0; + entity_eventstate = core::Entity::Normal; + return; + } + + entity_eventstate = core::Entity::JumpInitiate; + if (Game::instance()->g_devel->value()) { + entity_timer = 0; + } else { + entity_timer = 8; + } - entity_eventstate = core::Entity::JumpInitiate; - if (Game::instance()->g_devel->value()) { - entity_timer = 0; - } else { - entity_timer = 10; + ship_jumpdrive_timer = core::server()->time(); + entity_dirty = true; } - ship_jumpdrive_timer = core::server()->time(); - entity_dirty = true; } void Ship::frame(float seconds) @@ -171,14 +184,34 @@ void Ship::frame(float seconds) entity_timer -= 1.0f; if (entity_timer <= 0) { - core::server()->send(owner(), "Jumping to '" + ship_jumptargetzone->name() + '\''); - set_zone(ship_jumptargetzone); - if (owner()->control() == (EntityControlable*) this) - owner()->set_zone(ship_jumptargetzone); + // find closest jumppoint + float d = -1; + JumpPoint *jumppoint = 0; + for (core::Zone::Content::iterator it = zone()->content().begin(); it != zone()->content().end(); it++) { + core::Entity *entity = (*it); + if (entity->moduletype() == jumppoint_enttype) { + JumpPoint *te = static_cast<JumpPoint *>(entity); + float d1 = math::distance(location(), te->location()); + if ((d < 0) || (d1 < d1)) { + d = d1; + jumppoint = te; + } + } + } + if (jumppoint && jumppoint->target()) { + core::server()->send(owner(), "Jumping to '" + jumppoint->target()->zone()->name() + '\''); + set_zone(jumppoint->target()->zone()); + if (owner()->control() == (EntityControlable*) this) + owner()->set_zone(jumppoint->target()->zone()); + entity_eventstate = core::Entity::Jump; + entity_location.assign(jumppoint->target()->location() + location() - jumppoint->location()); + } else { + core::server()->send(owner(), "Jump failed!"); + entity_eventstate = core::Entity::Normal; + } ship_jumpdrive_timer = 0; - ship_jumptargetzone = 0; entity_timer = 0; - entity_eventstate = core::Entity::Jump; + entity_dirty = true; return; } else { diff --git a/src/game/ship.h b/src/game/ship.h index e85a0ad..568997c 100644 --- a/src/game/ship.h +++ b/src/game/ship.h @@ -10,6 +10,7 @@ #include "core/player.h" #include "core/entity.h" #include "game/shipmodel.h" +#include "game/jumppoint.h" #include "math/vector3f.h" namespace game { @@ -48,9 +49,7 @@ private: bool ship_jumpdrive; float ship_jumpdrive_timer; - float ship_impulsedrive_timer; - - core::Zone *ship_jumptargetzone; + float ship_impulsedrive_timer; }; } |