diff options
-rw-r--r-- | src/auxiliary/functions.cc | 2 | ||||
-rw-r--r-- | src/client/targets.cc | 4 | ||||
-rw-r--r-- | src/client/view.cc | 7 | ||||
-rw-r--r-- | src/core/entity.cc | 3 | ||||
-rw-r--r-- | src/core/entity.h | 5 | ||||
-rw-r--r-- | src/core/netserver.cc | 11 | ||||
-rw-r--r-- | src/core/zone.cc | 11 | ||||
-rw-r--r-- | src/core/zone.h | 3 | ||||
-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 | ||||
-rw-r--r-- | src/render/draw.cc | 5 |
14 files changed, 207 insertions, 70 deletions
diff --git a/src/auxiliary/functions.cc b/src/auxiliary/functions.cc index a6187af..860524a 100644 --- a/src/auxiliary/functions.cc +++ b/src/auxiliary/functions.cc @@ -149,7 +149,7 @@ void to_label(std::string &text) size_t pos = 0; while (pos < text.size()) { - if ((text[pos] == ' ') || (text[pos] == '-')) { + if ((text[pos] == ' ') || (text[pos] == '-') || (text[pos] == '_')) { text[pos] = '_'; pos++; } else if ((text[pos] >= 'A') && (text[pos] <= 'Z')) { diff --git a/src/client/targets.cc b/src/client/targets.cc index 7e852ad..a18392f 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -40,7 +40,9 @@ core::Cvar *snd_engines = 0; bool is_legal_target(core::Entity *entity) { - if (entity->id() == core::localcontrol()->id()) { + if (entity->serverside()) { + return false; + } else if (entity->id() == core::localcontrol()->id()) { return false; } else if (entity->state()->distance() < 0.001f) { return false; diff --git a/src/client/view.cc b/src/client/view.cc index 32f2971..8cf1af9 100644 --- a/src/client/view.cc +++ b/src/client/view.cc @@ -204,8 +204,11 @@ void draw_entity_offscreen_target(core::Entity *entity, bool is_active_target) } const float r = 16; - cx = (0.5f - cx) * (float) video::width; - cy = (0.5f - cy) * (float)video::height; + const float margin = 24; + cx = (0.5f - cx) * ((float) video::width - margin*2); + cx += margin; + cy = (0.5f - cy) * ((float)video::height - margin*2); + cy += margin; render::gl::disable(GL_TEXTURE_2D); render::gl::color(0, 0, 0, 1); diff --git a/src/core/entity.cc b/src/core/entity.cc index 0a6a201..bed17fb 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -110,11 +110,14 @@ Entity::Entity(unsigned int flags) : entity_zone = 0; entity_oldzone = 0; + entity_serverside = false; + add(this); } Entity::Entity(std::istream & is) { + entity_serverside = false; entity_id = 0; entity_zone = 0; entity_oldzone = 0; diff --git a/src/core/entity.h b/src/core/entity.h index 180d535..c988143 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -114,6 +114,9 @@ public: /// base radius of the entity inline float radius() const { return entity_radius; } + /// indicates a server-side entity + inline bool serverside() const { return entity_serverside; } + /*----- serializers ----------------------------------------------- */ /// serialize the entity to a stream @@ -205,6 +208,8 @@ protected: // the previous zone the entity belonged too Zone *entity_oldzone; + bool entity_serverside; + private: // add an entity to the registry static void add(Entity *ent); diff --git a/src/core/netserver.cc b/src/core/netserver.cc index dcc152f..93d4682 100644 --- a/src/core/netserver.cc +++ b/src/core/netserver.cc @@ -468,7 +468,7 @@ void NetServer::send_frame_marker(NetClient *client, float timestamp, float prev // send a "ent" create entity message to all clients void NetServer::send_entity_create(NetClient *client, Entity *entity) { - if (client->state() == NetClient::Connected) { + if ((client->state() == NetClient::Connected) && !entity->serverside()) { std::ostringstream msg; msg << "ent " << entity->id() << " " << entity->type() << " "; entity->serialize_server_create(msg); @@ -480,10 +480,9 @@ void NetServer::send_entity_create(NetClient *client, Entity *entity) // send a "die" delete entity message to a client void NetServer::send_entity_delete(NetClient *client, Entity *entity) { - std::ostringstream msg(""); - msg << "die " << entity->id() << '\n'; - - if (client->state() == NetClient::Connected) { + if ((client->state() == NetClient::Connected) && !entity->serverside()) { + std::ostringstream msg(""); + msg << "die " << entity->id() << '\n'; client->send_raw(msg.str()); } } @@ -491,7 +490,7 @@ void NetServer::send_entity_delete(NetClient *client, Entity *entity) // broadcast a "sup" server update entity message to all clients void NetServer::send_entity_update(NetClient *client, Entity *entity) { - if (client->state() == NetClient::Connected) { + if ((client->state() == NetClient::Connected) && !entity->serverside()) { std::ostringstream msg; msg << "sup " << entity->id() << " "; entity->serialize_server_update(msg); diff --git a/src/core/zone.cc b/src/core/zone.cc index 87ab9b4..2dfc5c2 100644 --- a/src/core/zone.cc +++ b/src/core/zone.cc @@ -181,6 +181,17 @@ Entity *Zone::find_entity(unsigned int id) return 0; } +Entity *Zone::find_entity(const std::string & label) +{ + for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) { + if ((*it)->label().compare(label) == 0) { + return (*it); + } + } + + return 0; +} + void Zone::serialize_server_update(std::ostream & os) const { os << zone_label << " "; diff --git a/src/core/zone.h b/src/core/zone.h index cd1fec2..bb2074e 100644 --- a/src/core/zone.h +++ b/src/core/zone.h @@ -98,6 +98,9 @@ public: /// find an entity inside a zone Entity *find_entity(unsigned int id); + /// find a labeled entity inside a zone + Entity *find_entity(const std::string & label); + /* ---- mutators ------------------------------------------- */ /// set the Zone label 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; }; } diff --git a/src/render/draw.cc b/src/render/draw.cc index 8bf694f..c74f65f 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -498,7 +498,7 @@ void draw_pass_default() for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); ++it) { core::Entity *entity = (*it); - if (!entity->model() && (entity->type() != core::Entity::Globe)) { + if (!entity->serverside() && !entity->model() && (entity->type() != core::Entity::Globe)) { gl::push(); gl::translate(entity->state()->location()); @@ -1086,7 +1086,6 @@ void draw(float seconds) draw_pass_spacegrid(); // draw the blue spacegrid Dust::draw(zone_color); // draw spacedust - draw_pass_model_fx(seconds); // draw entity lights and engines gl::enable(GL_LIGHTING); @@ -1103,7 +1102,7 @@ void draw(float seconds) gl::disable(GL_COLOR_MATERIAL); // disable color tracking gl::disable(GL_CULL_FACE); // disable culling - gl::depthmask(GL_TRUE); // enable depth buffer writing + gl::depthmask(GL_TRUE); // enable depth buffer writing gl::disable(GL_DEPTH_TEST); // disable depth buffer testing // GL_BLEND must be enabled for the GUI } |