Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/auxiliary/functions.cc2
-rw-r--r--src/client/targets.cc4
-rw-r--r--src/client/view.cc7
-rw-r--r--src/core/entity.cc3
-rw-r--r--src/core/entity.h5
-rw-r--r--src/core/netserver.cc11
-rw-r--r--src/core/zone.cc11
-rw-r--r--src/core/zone.h3
-rw-r--r--src/game/Makefile.am5
-rw-r--r--src/game/game.cc76
-rw-r--r--src/game/game.h3
-rw-r--r--src/game/ship.cc137
-rw-r--r--src/game/ship.h5
-rw-r--r--src/render/draw.cc5
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
}