Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio/audio.cc2
-rw-r--r--src/audio/wav.cc2
-rw-r--r--src/client/input.cc4
-rw-r--r--src/client/keyboard.cc2
-rw-r--r--src/client/targets.cc85
-rw-r--r--src/client/view.cc13
-rw-r--r--src/core/Makefile.am6
-rw-r--r--src/core/application.cc4
-rw-r--r--src/core/commandbuffer.cc73
-rw-r--r--src/core/core.h1
-rw-r--r--src/core/cvar.cc22
-rw-r--r--src/core/cvar.h10
-rw-r--r--src/core/entity.cc105
-rw-r--r--src/core/entity.h65
-rw-r--r--src/core/func.cc36
-rw-r--r--src/core/func.h7
-rw-r--r--src/core/gameinterface.cc41
-rw-r--r--src/core/gameserver.cc23
-rw-r--r--src/core/net.h2
-rw-r--r--src/core/netconnection.cc25
-rw-r--r--src/core/netserver.cc82
-rw-r--r--src/core/netserver.h10
-rw-r--r--src/core/player.cc79
-rw-r--r--src/core/player.h26
-rw-r--r--src/filesystem/inifile.cc33
-rw-r--r--src/filesystem/inifile.h2
-rw-r--r--src/game/game.cc372
-rw-r--r--src/game/game.h7
-rw-r--r--src/game/ship.cc12
-rw-r--r--src/game/ship.h5
-rw-r--r--src/game/shipmodel.cc1
-rw-r--r--src/game/shipmodel.h3
-rw-r--r--src/model/map.cc2
-rw-r--r--src/render/draw.cc46
-rw-r--r--src/render/render.cc3
-rw-r--r--src/render/text.cc6
-rw-r--r--src/render/tga.cc5
37 files changed, 859 insertions, 363 deletions
diff --git a/src/audio/audio.cc b/src/audio/audio.cc
index 3be1aa5..3ad640d 100644
--- a/src/audio/audio.cc
+++ b/src/audio/audio.cc
@@ -39,7 +39,7 @@ void init()
Sources::init();
- con_debug << " audio device ^B" << alcGetString(audio_device, ALC_DEFAULT_DEVICE_SPECIFIER) << std::endl;
+ //con_debug << " audio device ^B" << alcGetString(audio_device, ALC_DEFAULT_DEVICE_SPECIFIER) << std::endl;
// the "no sound" sound
load("ui/nosnd");
diff --git a/src/audio/wav.cc b/src/audio/wav.cc
index 5d118c6..178f199 100644
--- a/src/audio/wav.cc
+++ b/src/audio/wav.cc
@@ -109,7 +109,7 @@ PCM *Wav::load(std::string const & name)
con_warn << "Error reading " << filename << ": file truncated!" << std::endl;
}
- con_print << " " << filename << " " << pcm->samplerate()<< "Hz " << pcm->bitspersample() << "bit " <<
+ con_debug << " " << filename << " " << pcm->samplerate()<< "Hz " << pcm->bitspersample() << "bit " <<
pcm->channels() << " chan " << pcm->size() << " bytes" << std::endl;
filesystem::close(wav_file);
diff --git a/src/client/input.cc b/src/client/input.cc
index 6306fc8..d26c3ba 100644
--- a/src/client/input.cc
+++ b/src/client/input.cc
@@ -4,6 +4,7 @@
the terms and conditions of the GNU General Public License version 2
*/
+#include "auxiliary/functions.h"
#include "audio/audio.h"
#include "core/core.h"
#include "client/client.h"
@@ -128,6 +129,7 @@ void func_list_keys(std::string const &args)
std::stringstream argstr(args);
std::string keyname;
if (argstr >> keyname) {
+ aux::lowercase(keyname);
keyboard->list_bind(keyname);
} else {
keyboard->list_keys();
@@ -143,6 +145,7 @@ void func_list_binds(std::string const &args)
std::stringstream argstr(args);
std::string keyname;
if (argstr >> keyname) {
+ aux::lowercase(keyname);
keyboard->list_bind(keyname);
} else {
keyboard->list_binds();
@@ -158,6 +161,7 @@ void func_bind(std::string const &args)
std::stringstream argstr(args);
std::string keyname;
if (argstr >> keyname) {
+ aux::lowercase(keyname);
if (args.size() > keyname.size()+1) {
keyboard->bind(keyname, args.substr(keyname.size()+1));
} else {
diff --git a/src/client/keyboard.cc b/src/client/keyboard.cc
index d8b14b3..5870e06 100644
--- a/src/client/keyboard.cc
+++ b/src/client/keyboard.cc
@@ -329,7 +329,7 @@ Key *Keyboard::find(unsigned int keysym)
void Keyboard::bind(std::string const &name, const std::string str)
{
- Key *key = find(aux::lowercase(name));
+ Key *key = find(name);
if (key) {
key->assign(Key::None, str.c_str());
} else {
diff --git a/src/client/targets.cc b/src/client/targets.cc
index a39943f..666ea6a 100644
--- a/src/client/targets.cc
+++ b/src/client/targets.cc
@@ -67,8 +67,14 @@ void select_target(core::Entity *entity)
void select_target(unsigned int id)
{
- // FIXME validate
- core::Entity * entity = core::Entity::find(id);
+ if (!core::localcontrol())
+ return;
+ core::Zone *zone = core::localcontrol()->zone();
+ if (!zone)
+ return;
+
+ core::Entity *entity = zone->find_entity(id);
+
if (entity)
select_target(entity);
}
@@ -77,45 +83,49 @@ void func_target_next(std::string const &args)
{
if (!core::localcontrol())
return;
+ core::Zone *zone = core::localcontrol()->zone();
+ if (!zone)
+ return;
- if (!core::Entity::registry.size()) {
+ if (!zone->content().size()) {
current_target = 0;
current_target_id = 0;
return;
}
- std::map<unsigned int, core::Entity *>::iterator it = core::Entity::registry.begin();
+ core::Zone::Content::iterator it = zone->content().begin();
if (!current_target_id) {
// first entity
- it = core::Entity::registry.begin();
- while (!is_legal_target((*it).second) && it != core::Entity::registry.end())
+ it = zone->content().begin();
+ while (!is_legal_target((*it)) && it != zone->content().end())
it++;
} else {
// current entity
- it = core::Entity::registry.find(current_target_id);
+ while (it != zone->content().end() && ((*it)->id() != current_target_id))
+ ++it;
// next legal entity
- if (it != core::Entity::registry.end())
+ if (it != zone->content().end())
it++;
- if (it == core::Entity::registry.end()) {
- it = core::Entity::registry.begin();
+ if (it == zone->content().end()) {
+ it = zone->content().begin();
}
- while (!is_legal_target((*it).second)) {
+ while (!is_legal_target((*it))) {
it++;
- if (it == core::Entity::registry.end())
- it = core::Entity::registry.begin();
+ if (it == zone->content().end())
+ it = zone->content().begin();
- if ((*it).first == current_target_id) {
- current_target = (*it).second;
+ if ((*it)->id() == current_target_id) {
+ current_target = (*it);
return;
}
}
}
- if (it != core::Entity::registry.end()) {
- select_target((*it).second);
+ if (it != zone->content().end()) {
+ select_target((*it));
} else {
current_target = 0;
current_target_id = 0;
@@ -127,45 +137,47 @@ void func_target_prev(std::string const &args)
{
if (!core::localcontrol())
return;
+ core::Zone *zone = core::localcontrol()->zone();
+ if (!zone)
+ return;
- if (!core::Entity::registry.size()) {
+ if (!zone->content().size()) {
current_target = 0;
current_target_id = 0;
return;
}
- std::map<unsigned int, core::Entity *>::reverse_iterator rit = core::Entity::registry.rbegin();
+ core::Zone::Content::reverse_iterator rit = zone->content().rbegin();
if (!current_target_id) {
// last entity
- rit = core::Entity::registry.rbegin();
- while (!is_legal_target((*rit).second) && rit != core::Entity::registry.rend())
+ rit = zone->content().rbegin();
+ while (!is_legal_target((*rit)) && rit != zone->content().rend())
rit++;
} else {
// current entity
- while (rit != core::Entity::registry.rend() && ((*rit).first != current_target_id))
+ while (rit != zone->content().rend() && ((*rit)->id() != current_target_id))
++rit;
// previous legal entity
- if (rit != core::Entity::registry.rend())
+ if (rit != zone->content().rend())
++rit;
- if (rit == core::Entity::registry.rend()) {
- rit = core::Entity::registry.rbegin();
+ if (rit == zone->content().rend()) {
+ rit = zone->content().rbegin();
}
- while (!is_legal_target((*rit).second)) {
+ while (!is_legal_target((*rit))) {
++rit;
- if (rit == core::Entity::registry.rend())
- rit = core::Entity::registry.rbegin();
+ if (rit == zone->content().rend())
+ rit = zone->content().rbegin();
- if ((*rit).first == current_target_id) {
- current_target = (*rit).second;
+ if ((*rit)->id() == current_target_id) {
+ current_target = (*rit);
return;
}
}
}
- if (rit != core::Entity::registry.rend()) {
- select_target((*rit).second);
-
+ if (rit != zone->content().rend()) {
+ select_target((*rit));
} else {
current_target = 0;
current_target_id = 0;
@@ -260,6 +272,9 @@ void render_entity_sound(core::Entity *entity)
// render client targets
void frame()
{
+ core::Zone *zone = core::localplayer()->zone();
+ if (!zone)
+ return;
/* Notes
http://en.wikipedia.org/wiki/Line-plane_intersection
@@ -283,8 +298,8 @@ void frame()
cursor -= render::Camera::axis().up() * y;
math::Vector3f center = render::Camera::eye() + (render::Camera::axis().forward() * (render::Camera::frustum_front() +0.01f));
- for (core::Entity::Registry::iterator it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
- core::Entity *entity = (*it).second;
+ for (core::Zone::Content::iterator it=zone->content().begin(); it != zone->content().end(); it++) {
+ core::Entity *entity = (*it);
// render entity sound
render_entity_sound(entity);
diff --git a/src/client/view.cc b/src/client/view.cc
index eda5cf8..75c4989 100644
--- a/src/client/view.cc
+++ b/src/client/view.cc
@@ -92,15 +92,13 @@ void draw_status()
{
using namespace render;
- // print the status in the upper left corner
std::stringstream status;
-
if (core::game()) {
int minutes = (int) floorf(core::game()->clientframetime() / 60.0f);
int seconds = (int) floorf( core::game()->clientframetime() - (float) minutes* 60.0f);
status << "^Ntime ^B" << std::setfill(' ') << std::setw(3) << minutes << ":" << std::setfill('0') << std::setw(2) << seconds;
- Text::draw(video::width-Text::fontwidth()*11-4, 4+Text::fontheight(), status);
+ Text::draw(video::width-Text::fontwidth()*11-4, 4, status);
}
// print stats if desired
@@ -113,7 +111,8 @@ void draw_status()
}
stats << "^Ntx ^B"<< std::setw(5) << (core::Stats::network_bytes_sent >> 10) << "\n";
stats << "^Nrx ^B"<< std::setw(5) << (core::Stats::network_bytes_received >> 10) << "\n";
- Text::draw(video::width-Text::fontwidth()*11-4, 4 + Text::fontheight()*3, stats);
+
+ Text::draw(video::width-Text::fontwidth()*11-4, 4 + Text::fontheight()*2, stats);
}
// draw a basic HUD
@@ -136,6 +135,10 @@ void draw_status()
Text::draw(4, video::height - Text::fontheight()*2 -4, location);
}
+ if (core::localplayer()->zone()) {
+ Text::draw(video::width - 4-Text::fontwidth()*24, video::height - Text::fontheight()*3 -4, core::localplayer()->zone()->name());
+ }
+
core::Entity *entity = targets::current();
if (entity) {
std::stringstream target;
@@ -345,6 +348,8 @@ void frame(float seconds)
// Clear the color and depth buffers.
gl::clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+ render::Stats::clear();
+
if (core::application()->connected() && core::game()->serverframetime()) {
render::draw(seconds); // draw the world
targets::frame();
diff --git a/src/core/Makefile.am b/src/core/Makefile.am
index fb32450..6c2c41e 100644
--- a/src/core/Makefile.am
+++ b/src/core/Makefile.am
@@ -1,9 +1,9 @@
METASOURCES = AUTO
INCLUDES = -I$(top_srcdir)/src
-libcore_la_SOURCES = application.cc commandbuffer.cc clientstate.cc core.cc cvar.cc entity.cc \
- func.cc gameconnection.cc gameinterface.cc gameserver.cc module.cc netclient.cc \
- netconnection.cc netserver.cc player.cc stats.cc
+libcore_la_SOURCES = application.cc clientstate.cc commandbuffer.cc core.cc \
+ cvar.cc entity.cc func.cc gameconnection.cc gameinterface.cc gameserver.cc \
+ module.cc netclient.cc netconnection.cc netserver.cc player.cc stats.cc zone.cc
libcore_la_LDFLAGS = -avoid-version -no-undefined
libcore_la_LIBADD = $(top_builddir)/src/model/libmodel.la \
$(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/math/libmath.la $(top_builddir)/src/sys/libsys.la \
diff --git a/src/core/application.cc b/src/core/application.cc
index 8234b8f..4d1ef86 100644
--- a/src/core/application.cc
+++ b/src/core/application.cc
@@ -349,9 +349,7 @@ void Application::save_config()
ofs << "# this file is automaticly generated" << std::endl;
- Cvar::iterator it;
- for (it = Cvar::registry.begin(); it != Cvar::registry.end(); it++) {
-
+ for (Cvar::Registry::iterator it = Cvar::registry().begin(); it != Cvar::registry().end(); it++) {
if (((*it).second->flags() & Cvar::Archive) == Cvar::Archive)
ofs << "set " << (*it).first << " " << (*it).second->str() << std::endl;
}
diff --git a/src/core/commandbuffer.cc b/src/core/commandbuffer.cc
index 80e7e36..c111e17 100644
--- a/src/core/commandbuffer.cc
+++ b/src/core/commandbuffer.cc
@@ -17,6 +17,7 @@
#include "core/gameconnection.h"
#include "core/func.h"
#include "core/cvar.h"
+#include "core/zone.h"
namespace core
{
@@ -51,31 +52,83 @@ void func_list_ent(std::string const &args)
Entity::list();
}
+void func_list_zone(std::string const &args)
+{
+ std::istringstream argstream(args);
+ std::string zonelabel;
+ if (argstream >> zonelabel) {
+ aux::lowercase(zonelabel);
+ Zone::list_zone(zonelabel);
+ } else {
+ Zone::list();
+ }
+}
+
void func_set(std::string const &args)
{
std::istringstream argstream(args);
std::string varname;
- if (!(argstream >> varname))
+ if (!(argstream >> varname)) {
+ con_print << "Variable name expected!" << std::endl;
return;
+ }
aux::to_lowercase(varname);
std::string value;
if (!(argstream >> value)) {
+ Cvar *cvar = Cvar::find(varname);
+ if (cvar) {
+ con_print << " " << varname << " " << cvar->str() << " ^N" << cvar->info() << "\n";
+ }
return;
}
char c;
while (argstream.get(c))
value += c;
+
Cvar *cvar = Cvar::set(varname.c_str(), value.c_str(), Cvar::Archive);
+ if (cvar->flags() && Cvar::Info) {
+ localplayer()->player_dirty = true;
+ }
+
+ con_debug << " " << cvar->name() << " " << cvar->str() << "\n";
+}
+
+void func_toggle(std::string const &args)
+{
+ std::istringstream argstream(args);
+ std::string varname;
+ if (!(argstream >> varname)) {
+ con_print << "Variable name expected!" << std::endl;
+ return;
+ }
- con_print << " " << cvar->name() << " " << cvar->str() << "\n";
+ aux::to_lowercase(varname);
+
+ Cvar *cvar = Cvar::find(varname);
+ if (!cvar) {
+ con_print << "Unknown variable '" << varname << "'\n";
+ return;
+ }
+
+ float valueone = 1.0f;
+ if (!(argstream >> valueone)) {
+ valueone = 1.0f;
+ }
+
+ if (cvar->value()) {
+ (*cvar) = 0.0f;
+ } else {
+ (*cvar) = valueone;
+ }
if (cvar->flags() && Cvar::Info) {
localplayer()->player_dirty = true;
}
- return;
+
+ con_debug << " " << cvar->name() << " " << cvar->str() << "\n";
}
void func_exec(std::string const &args)
@@ -104,9 +157,15 @@ void CommandBuffer::init()
func = Func::add("list_var", (FuncPtr)func_list_var);
func->set_info("list variables");
+ func = Func::add("list_zone", (FuncPtr)func_list_zone);
+ func->set_info("list zones");
+
func = Func::add("set", (FuncPtr)func_set);
func->set_info("[variable] [str] set variable value");
+ func = Func::add("toggle", (FuncPtr)func_toggle);
+ func->set_info("[variable] toggle a variable");
+
func = Func::add("print", func_print);
func->set_info("[str] print a message on the console");
@@ -122,9 +181,11 @@ void CommandBuffer::shutdown()
//con_debug << "Shutting down command buffer...\n";
Func::remove("set");
+ Func::remove("toggle");
Func::remove("list_var");
Func::remove("list_func");
Func::remove("list_ent");
+ Func::remove("list_zone");
Func::remove("print");
Func::remove("print_file");
Func::remove("exec");
@@ -220,8 +281,7 @@ void CommandBuffer::complete(std::string &input, size_t &pos)
aux::to_lowercase(partial);
// search function registry for matches
- std::map<std::string, Func *>::iterator f;
- for (f = Func::registry.begin(); f != Func::registry.end(); f++) {
+ for (Func::Registry::iterator f = Func::registry().begin(); f != Func::registry().end(); f++) {
if (partial == (*f).first.substr(0, partial.size())) {
match.push_back((*f).first);
//con_print << " " << (*f).first << "\n";
@@ -229,8 +289,7 @@ void CommandBuffer::complete(std::string &input, size_t &pos)
}
// search cvar registry for matches
- std::map<std::string, Cvar *>::iterator c;
- for (c = Cvar::registry.begin(); c != Cvar::registry.end(); c++) {
+ for (Cvar::Registry::iterator c = Cvar::registry().begin(); c != Cvar::registry().end(); c++) {
if (partial == (*c).first.substr(0, partial.size())) {
match.push_back((*c).first);
//con_print << " " << (*c).first << "\n";
diff --git a/src/core/core.h b/src/core/core.h
index a3e13e4..a3c9005 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -17,6 +17,7 @@
#include "core/gameinterface.h"
#include "core/module.h"
#include "core/player.h"
+#include "core/zone.h"
/// core contains the basic functionality of the engine
namespace core
diff --git a/src/core/cvar.cc b/src/core/cvar.cc
index 772144f..45f04f3 100644
--- a/src/core/cvar.cc
+++ b/src/core/cvar.cc
@@ -33,7 +33,7 @@ Cvar *Cvar::net_framerate = 0;
Cvar *Cvar::rconpassword = 0;
-std::map<std::string, Cvar*> Cvar::registry;
+Cvar::Registry Cvar::cvar_registry;
Cvar::Cvar(const char *name, unsigned int flags)
{
@@ -85,7 +85,7 @@ Cvar* Cvar::get(const char *name, const char *value, unsigned int flags)
} else {
//con_debug << "get " << name << " " << value << std::endl;
c = new Cvar(name, flags);
- registry[std::string(name)] = c;
+ cvar_registry[std::string(name)] = c;
(*c) = value;
}
c->cvar_flags |= flags;
@@ -100,7 +100,7 @@ Cvar* Cvar::get(const char *name, float value, unsigned int flags)
} else {
//con_debug << "get " << name << " " << value << std::endl;
c = new Cvar(name, flags);
- registry[std::string(name)] = c;
+ cvar_registry[std::string(name)] = c;
(*c) = value;
}
c->cvar_flags |= flags;
@@ -112,7 +112,7 @@ Cvar* Cvar::set(const char *name, const char *value, unsigned int flags)
Cvar *c = find(name);
if (!c) {
c = new Cvar(name, flags);
- registry[std::string(name)] = c;
+ cvar_registry[std::string(name)] = c;
}
(*c) = value;
c->cvar_flags = flags;
@@ -126,7 +126,7 @@ Cvar* Cvar::set(const char *name, float value, unsigned int flags)
Cvar *c = find(name);
if (!c) {
c = new Cvar(name, flags);
- registry[std::string(name)] = c;
+ cvar_registry[std::string(name)] = c;
}
(*c) = value;
c->cvar_flags = flags;
@@ -140,7 +140,7 @@ void Cvar::unset(std::string const &name)
Cvar *c = find(name);
if (c) {
con_debug << "unset " << name << std::endl;
- registry.erase(name);
+ cvar_registry.erase(name);
delete c;
}
}
@@ -152,8 +152,8 @@ void Cvar::unset(const char *name)
Cvar *Cvar::find(std::string const &name)
{
- std::map<std::string, Cvar*>::iterator it = registry.find(name);
- if (it == registry.end())
+ Registry::iterator it = cvar_registry.find(name);
+ if (it == cvar_registry.end())
return 0;
else
return (*it).second;
@@ -168,8 +168,8 @@ void Cvar::list()
{
con_print << "Flags: A=Archive G=Game R=ReadOnly" << std::endl;
- std::map<std::string, Cvar*>::iterator it;
- for (it = registry.begin(); it != registry.end(); it++) {
+ Registry::iterator it;
+ for (it = cvar_registry.begin(); it != cvar_registry.end(); it++) {
std::string typeindicator;
if (((*it).second->flags() & Archive) == Archive)
typeindicator += 'A';
@@ -189,7 +189,7 @@ void Cvar::list()
con_print << " " << typeindicator <<
" " << (*it).first << " " << (*it).second->str() << " ^N" << (*it).second->info() << std::endl;
}
- con_print << registry.size() << " registered variables" << std::endl;
+ con_print << cvar_registry.size() << " registered variables" << std::endl;
}
}
diff --git a/src/core/cvar.h b/src/core/cvar.h
index 7aab5d3..b8e406c 100644
--- a/src/core/cvar.h
+++ b/src/core/cvar.h
@@ -61,6 +61,9 @@ public:
Cvar &operator=(float other);
/* ---- Static functions for the Cvar registry -------------------- */
+
+ /// type definition for the Cvar registry
+ typedef std::map<std::string, Cvar*> Registry;
/// get a cvar value from the registry
/** If the a cvar with the given name already exists in the registry,
@@ -104,10 +107,7 @@ public:
static void list();
/// the Cvar registry
- static std::map<std::string, Cvar*> registry;
-
- /// an iterator for the Cvar registry
- typedef std::map<std::string, Cvar*>::iterator iterator;
+ static inline Registry & registry() { return cvar_registry; }
static Cvar *sv_dedicated; // dedicated server
static Cvar *sv_private; // client with private server
@@ -133,6 +133,8 @@ private:
unsigned int cvar_flags;
float cvar_value;
+ static Registry cvar_registry;
+
};
}
diff --git a/src/core/entity.cc b/src/core/entity.cc
index c45825b..20e34ee 100644
--- a/src/core/entity.cc
+++ b/src/core/entity.cc
@@ -19,17 +19,17 @@ using math::Vector3f;
/* ---- Static functions for the Entity registry ------------------- */
-std::map<unsigned int, Entity *> Entity::registry;
+Entity::Registry Entity::entity_registry;
void Entity::add(Entity *ent)
{
Registry::iterator it;
unsigned int id = 1;
- for (it = registry.begin(); it != registry.end() && id == (*it).second->id(); it++) {
+ for (it = entity_registry.begin(); it != entity_registry.end() && id == (*it).second->id(); it++) {
id++;
}
ent->entity_id = id;
- registry[id] = ent;
+ entity_registry[id] = ent;
}
void Entity::add(Entity *ent, unsigned int id)
@@ -39,33 +39,33 @@ void Entity::add(Entity *ent, unsigned int id)
return;
}
ent->entity_id = id;
- registry[id] = ent;
+ entity_registry[id] = ent;
}
Entity *Entity::find(unsigned int id)
{
- std::map<unsigned int, Entity *>::iterator it = registry.find(id);
- if (it == registry.end())
+ Registry::iterator it = entity_registry.find(id);
+ if (it == entity_registry.end())
return 0;
else
return (*it).second;
}
-void Entity::remove(unsigned int id)
+void Entity::erase(unsigned int id)
{
- std::map<unsigned int, Entity *>::iterator it = registry.find(id);
- if (it != registry.end()) {
+ Registry::iterator it = entity_registry.find(id);
+ if (it != entity_registry.end()) {
delete((*it).second);
- registry.erase(it);
+ entity_registry.erase(it);
} else {
- con_warn << "Could not remove entity " << id << "!\n";
+ con_warn << "Could not erase entity " << id << "!\n";
}
}
void Entity::list()
{
- std::map<unsigned int, Entity *>::iterator it;
- for (it = registry.begin(); it != registry.end(); it++) {
+ Registry::iterator it;
+ for (it = entity_registry.begin(); it != entity_registry.end(); it++) {
std::string typeindicator;
Entity *entity = (*it).second;
con_print << " id " << std::setw(4) << entity->id()
@@ -73,7 +73,7 @@ void Entity::list()
<< ":" << std::setw(4) << entity->moduletype()
<< " " << entity->label() << std::endl;
}
- con_print << registry.size() << " registered entities" << std::endl;
+ con_print << entity_registry.size() << " registered entities" << std::endl;
}
/*----- Entity ----------------------------------------------------- */
@@ -101,11 +101,15 @@ Entity::Entity(unsigned int flags) :
entity_clientstate = 0;
+ entity_zone = 0;
+
add(this);
}
Entity::Entity(std::istream & is)
{
+ entity_zone = 0;
+
// type is already determined
unsigned int s;
std::string n;
@@ -113,6 +117,13 @@ Entity::Entity(std::istream & is)
is >> entity_id;
is >> entity_moduletypeid;
is >> entity_flags;
+ is >> s;
+
+ set_zone(Zone::find(s));
+ if (entity_zone && !s) {
+ con_warn << "Received entity " << entity_id << " for unknown zone " << s << "!" << std::endl;
+ }
+
is >> entity_location;
is >> entity_color;
is >> entity_color_second;
@@ -162,6 +173,29 @@ Entity::~Entity()
{
if (entity_clientstate)
delete entity_clientstate;
+
+ if (entity_zone)
+ entity_zone->remove(this);
+}
+
+void Entity::die()
+{
+ entity_destroyed = true;
+}
+
+void Entity::set_zone(Zone *zone)
+{
+ if (entity_zone == zone)
+ return;
+
+ if (entity_zone)
+ entity_zone->remove(this);
+
+ entity_zone = zone;
+ entity_dirty = true;
+
+ if (entity_zone)
+ entity_zone->add(this);
}
void Entity::serialize(std::ostream & os) const
@@ -170,6 +204,7 @@ void Entity::serialize(std::ostream & os) const
<< entity_id << " "
<< entity_moduletypeid << " "
<< entity_flags << " "
+ << (entity_zone ? entity_zone->id() : 0) << " "
<< entity_location << " "
<< entity_color << " "
<< entity_color_second << " "
@@ -186,7 +221,7 @@ void Entity::serialize_client_update(std::ostream & os) const
{
}
-void Entity::recieve_client_update(std::istream &is)
+void Entity::receive_client_update(std::istream &is)
{
}
@@ -194,7 +229,7 @@ void Entity::serialize_server_update(std::ostream & os) const
{
}
-void Entity::recieve_server_update(std::istream &is)
+void Entity::receive_server_update(std::istream &is)
{
}
@@ -244,42 +279,58 @@ void EntityDynamic::serialize_client_update(std::ostream & os) const
{
}
-void EntityDynamic::recieve_client_update(std::istream &is)
+void EntityDynamic::receive_client_update(std::istream &is)
{
}
void EntityDynamic::serialize_server_update(std::ostream & os) const
{
+ os << (entity_zone ? entity_zone->id() : 0) << " ";
os << entity_location << " ";
os << entity_axis.forward() << " ";
os << entity_axis.left() << " ";
os << entity_speed;
}
-void EntityDynamic::recieve_server_update(std::istream &is)
+void EntityDynamic::receive_server_update(std::istream &is)
{
+ unsigned int zone_id;
+ is >> zone_id;
is >> entity_location;
// axis up vector is the crossproduct of forward and left
is >> entity_axis[0];
is >> entity_axis[1];
entity_axis[2] = math::crossproduct(entity_axis.forward(), entity_axis.left());
is >> entity_speed;
+
+
+ if (!zone_id) {
+ if (entity_zone) {
+ entity_zone->remove(this);
+ entity_zone = 0;
+ }
+ } else {
+ if (zone_id != entity_zone->id()) {
+ set_zone(Zone::find(zone_id));
+ }
+ }
}
/*----- EntityControlable ------------------------------------------ */
-EntityControlable::EntityControlable(Player *player, unsigned int flags) :
+EntityControlable::EntityControlable(Player *owner, unsigned int flags) :
EntityDynamic(flags)
{
- entity_owner = player;
- if (entity_owner)
- entity_owner->add_asset(this);
entity_thrust = 0;
target_direction = 0.0f;
target_thrust = 0.0f;
target_pitch = 0.0f;
target_roll = 0.0f;
+
+ entity_owner = 0;
+ if (owner)
+ owner->add_asset(this);
}
EntityControlable::EntityControlable(std::istream & is) :
@@ -305,7 +356,7 @@ void EntityControlable::serialize(std::ostream & os) const
{
EntityDynamic::serialize(os);
os << " " << entity_thrust;
- os << " " << entity_owner->id();
+ os << " " << ( entity_owner ? entity_owner->id() : 0);
}
void EntityControlable::serialize_client_update(std::ostream & os) const
@@ -318,9 +369,9 @@ void EntityControlable::serialize_client_update(std::ostream & os) const
}
-void EntityControlable::recieve_client_update(std::istream &is)
+void EntityControlable::receive_client_update(std::istream &is)
{
- EntityDynamic::recieve_client_update(is);
+ EntityDynamic::receive_client_update(is);
is >> target_direction;
is >> target_pitch;
is >> target_thrust;
@@ -333,9 +384,9 @@ void EntityControlable::serialize_server_update(std::ostream & os) const
os << " " << entity_thrust;
}
-void EntityControlable::recieve_server_update(std::istream &is)
+void EntityControlable::receive_server_update(std::istream &is)
{
- EntityDynamic::recieve_server_update(is);
+ EntityDynamic::receive_server_update(is);
is >> entity_thrust;
}
diff --git a/src/core/entity.h b/src/core/entity.h
index d6000b9..ca2d029 100644
--- a/src/core/entity.h
+++ b/src/core/entity.h
@@ -25,6 +25,7 @@ class EntityControlable;
#include "core/clientstate.h"
#include "core/player.h"
+#include "core/zone.h"
namespace core
{
@@ -48,7 +49,7 @@ public:
/// create a new entity and add it to the registry
Entity(unsigned int flags = 0);
- /// create an entity froms stream data
+ /// create an entity from stream data
Entity(std::istream & is);
/// destroy an entity
@@ -83,6 +84,9 @@ public:
/// pointer to the model, is used client-side
inline model::Model * model() { return entity_model; }
+ /// pointer to the zone the entity belongs to
+ inline Zone *zone() const { return entity_zone; }
+
/// dirty flag
inline bool dirty() const { return entity_dirty; }
@@ -117,13 +121,13 @@ public:
/*----- mutators -------------------------------------------------- */
/// receive a client-to-server update from a stream
- virtual void recieve_client_update(std::istream &is);
+ virtual void receive_client_update(std::istream &is);
/// receive a server-to-client update from a stream
- virtual void recieve_server_update(std::istream &is);
+ virtual void receive_server_update(std::istream &is);
/// mark the entity as destroyed
- inline void die() { entity_destroyed = true; }
+ void die();
/// runs one game frame for the entity
/**
@@ -131,23 +135,30 @@ public:
*/
virtual void frame(float seconds);
+ /// set the zone the entity is currently in
+ /**
+ * this fuction removes the entity from its previous zone
+ * and removes it to the new one, if it is not 0
+ */
+ virtual void set_zone(Zone *zone);
+
/*----- static ---------------------------------------------------- */
/// type definition for the entity registry
typedef std::map<unsigned int, Entity*> Registry;
- /// the entity registry
- static Registry registry;
-
/// find an entity in the registry
static Entity *find(unsigned int id);
- /// remove one entity from the registry and deletes it
- static void remove(unsigned int entity_id);
+ /// erase an entity from the registry and delete it
+ static void erase(unsigned int entity_id);
/// list the entity registry
static void list();
+ /// the entity registry
+ static inline Registry & registry() { return entity_registry; }
+
/* entity_ variables can be set by the module */
math::Vector3f entity_location;
math::Axis entity_axis;
@@ -172,15 +183,23 @@ public:
ClientState *entity_clientstate;
+protected:
+ // the zone the entity belongs to
+ Zone *entity_zone;
+
private:
- /// add an entity to the registry
+ // add an entity to the registry
static void add(Entity *ent);
- /// add an entity with id to the registry
- void add(Entity *ent, unsigned int id);
+ // add an entity to the registry
+ static void add(Entity *ent, unsigned int it);
- /// the id is set by add()
+ // the id is set by add()
unsigned int entity_id;
+
+
+ // the entity registry
+ static Registry entity_registry;
};
@@ -216,10 +235,10 @@ public:
/*----- mutators -------------------------------------------------- */
/// receive a client-to-server update from a stream
- virtual void recieve_client_update(std::istream &is);
+ virtual void receive_client_update(std::istream &is);
/// receive a server-to-client update from a stream
- virtual void recieve_server_update(std::istream &is);
+ virtual void receive_server_update(std::istream &is);
/// runs one game frame for the entity
/**
@@ -235,9 +254,11 @@ public:
/// an entity that can be controlled by a player
class EntityControlable : public EntityDynamic
{
+ friend class Player;
+
public:
/// create a controlable entity
- EntityControlable(Player *player, unsigned int flags = 0);
+ EntityControlable(Player *owner, unsigned int flags = 0);
/// create a controlable entity from stream data
EntityControlable(std::istream & is);
@@ -269,10 +290,10 @@ public:
/*----- mutators -------------------------------------------------- */
/// receive a client-to-server update from a stream
- virtual void recieve_client_update(std::istream &is);
+ virtual void receive_client_update(std::istream &is);
/// receive a server-to-client update from a stream
- virtual void recieve_server_update(std::istream &is);
+ virtual void receive_server_update(std::istream &is);
/// set the target thrust
void set_thrust(float thrust);
@@ -293,9 +314,6 @@ public:
*/
virtual void frame(float seconds);
- /* entity_ variables can be set by the module */
- /// owner of the entity
- Player *entity_owner;
/// current thrust
float entity_thrust;
@@ -314,6 +332,11 @@ public:
/** target_roll must be in the [-1, 1] range
*/
float target_roll;
+
+private:
+ // owner of the entity
+ Player *entity_owner;
+
};
/// a Globe entity
diff --git a/src/core/func.cc b/src/core/func.cc
index ad25426..edebc8a 100644
--- a/src/core/func.cc
+++ b/src/core/func.cc
@@ -16,15 +16,15 @@ namespace core
/* ---- Static functions for the Func registry -------------------- */
-std::map<std::string, Func*> Func::registry;
+Func::Registry Func::func_registry;
Func * Func::add(const char *name, FuncPtr functionptr, unsigned int flags)
{
Func *func = 0;
- std::map<std::string, Func*>::iterator it = registry.find(name);
- if (it == registry.end()) {
+ Registry::iterator it = func_registry.find(name);
+ if (it == func_registry.end()) {
func = new Func(name, (void *)functionptr, flags & ~Func::Game);
- registry[std::string(name)] = func;
+ func_registry[std::string(name)] = func;
//con_debug << "Function '" << name << "' registered." << std::endl;
} else {
con_warn << "Function '" << name << "' already registered!" << std::endl;
@@ -36,10 +36,10 @@ Func * Func::add(const char *name, FuncPtr functionptr, unsigned int flags)
Func *Func::add(const char *name, GameFuncPtr gamefunctionptr, unsigned int flags)
{
Func *func = 0;
- std::map<std::string, Func*>::iterator it = registry.find(name);
- if (it == registry.end()) {
+ Registry::iterator it = func_registry.find(name);
+ if (it == func_registry.end()) {
func = new Func(name, (void *)gamefunctionptr, flags | Func::Game);
- registry[std::string(name)] = func;
+ func_registry[std::string(name)] = func;
//con_debug << "Function '" << name << "' registered." << std::endl;
} else {
con_warn << "Function '" << name << "' already registered!" << std::endl;
@@ -50,20 +50,20 @@ Func *Func::add(const char *name, GameFuncPtr gamefunctionptr, unsigned int flag
void Func::remove(const char *name)
{
- std::map<std::string, Func *>::iterator it = registry.find(std::string(name));
- if (it != registry.end()) {
+ std::map<std::string, Func *>::iterator it = func_registry.find(std::string(name));
+ if (it != func_registry.end()) {
delete (*it).second;
- registry.erase(it);
+ func_registry.erase(it);
//con_debug << "Function '" << name << "' unregistered." << std::endl;
}
}
void Func::remove(const std::string &name)
{
- std::map<std::string, Func *>::iterator it = registry.find(name);
- if (it != registry.end()) {
+ std::map<std::string, Func *>::iterator it = func_registry.find(name);
+ if (it != func_registry.end()) {
delete (*it).second;
- registry.erase(it);
+ func_registry.erase(it);
//con_debug << "Function '" << name << "' unregistered." << std::endl;
}
@@ -71,8 +71,8 @@ void Func::remove(const std::string &name)
Func *Func::find(const std::string &name)
{
- std::map<std::string, Func *>::iterator it = registry.find(name);
- if (it == registry.end())
+ std::map<std::string, Func *>::iterator it = func_registry.find(name);
+ if (it == func_registry.end())
return 0;
else
return (*it).second;
@@ -80,10 +80,10 @@ Func *Func::find(const std::string &name)
void Func::list()
{
- std::map<std::string, Func*>::iterator it;
+ Registry::iterator it;
con_print << "Flags: G=Game S=Shared" << std::endl;
- for (it = registry.begin(); it != registry.end(); it++) {
+ for (it = func_registry.begin(); it != func_registry.end(); it++) {
std::string typeindicator;
if (((*it).second->flags() & Game) == Game)
typeindicator += 'G';
@@ -96,7 +96,7 @@ void Func::list()
con_print << " " << typeindicator << " " << (*it).second->name() << " " << (*it).second->info() << std::endl;
}
- con_print << registry.size() << " registered functions" << std::endl;
+ con_print << func_registry.size() << " registered functions" << std::endl;
}
/* ---- Func ------------------------------------------------------ */
diff --git a/src/core/func.h b/src/core/func.h
index d72e583..7c5635f 100644
--- a/src/core/func.h
+++ b/src/core/func.h
@@ -58,6 +58,9 @@ public:
/* ---- Static functions for the Func registry -------------------- */
+ /// type definition
+ typedef std::map<std::string, Func*> Registry;
+
/// add a function to the registry
static Func *add(const char *name, FuncPtr functionptr, unsigned int flags=0);
@@ -77,13 +80,15 @@ public:
static void list();
/// the function registry
- static std::map<std::string, Func*> registry;
+ static inline Registry & registry() { return func_registry; }
private:
std::string func_name;
std::string func_info;
unsigned int func_flags;
void *func_ptr;
+
+ static Registry func_registry;
};
}
diff --git a/src/core/gameinterface.cc b/src/core/gameinterface.cc
index be4d288..7833bf5 100644
--- a/src/core/gameinterface.cc
+++ b/src/core/gameinterface.cc
@@ -12,6 +12,7 @@
#include "core/func.h"
#include "core/gameinterface.h"
#include "core/player.h"
+#include "core/zone.h"
#include "model/model.h"
#include "sys/sys.h"
@@ -52,12 +53,12 @@ GameInterface::GameInterface()
game_localplayer.update_info();
}
- core::Func::add("list_model", (core::FuncPtr) func_list_model);
+ Func::add("list_model", (FuncPtr) func_list_model);
}
GameInterface::~GameInterface()
{
- core::Func::remove("list_model");
+ Func::remove("list_model");
game_localplayer.clear();
@@ -70,24 +71,30 @@ void GameInterface::clear()
//con_debug << "Clearing game data\n";
// remove all entities
- for (std::map<unsigned int, Entity*>::iterator it = Entity::registry.begin(); it != Entity::registry.end(); it++) {
+ for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) {
delete (*it).second;
}
- Entity::registry.clear();
+ Entity::registry().clear();
+
+ // remove all zones
+ for (Zone::Registry::iterator it = Zone::registry().begin(); it != Zone::registry().end(); it++) {
+ delete (*it).second;
+ }
+ Zone::registry().clear();
// remove all game functions
- for (std::map<std::string, Func*>::iterator it = Func::registry.begin(); it != Func::registry.end(); it++) {
+ for (Func::Registry::iterator it = Func::registry().begin(); it != Func::registry().end(); it++) {
if ( ((*it).second->flags() & Func::Game) == Func::Game) {
delete (*it).second;
- Func::registry.erase(it);
+ Func::registry().erase(it);
}
}
// remove all game cvars
- for (std::map<std::string, Cvar*>::iterator it = Cvar::registry.begin(); it != Cvar::registry.end(); it++) {
+ for (Cvar::Registry::iterator it = Cvar::registry().begin(); it != Cvar::registry().end(); it++) {
if ( ((*it).second->flags() & Cvar::Game) == Cvar::Game) {
delete (*it).second;
- Cvar::registry.erase(it);
+ Cvar::registry().erase(it);
}
}
@@ -104,12 +111,11 @@ void GameInterface::reset_clientstate(float timestamp, float prevtimestamp)
game_previousframetime = prevtimestamp;
game_serverframetime = timestamp;
- std::map<unsigned int, core::Entity *>::iterator it;
- for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
+ for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) {
- core::Entity *entity = (*it).second;
+ Entity *entity = (*it).second;
- if (entity->state() && !(entity->flags() & core::Entity::Static))
+ if (entity->state() && !(entity->flags() & Entity::Static))
entity->state()->assign(entity);
}
@@ -124,7 +130,7 @@ void GameInterface::reset_clientstate(float timestamp, float prevtimestamp)
void GameInterface::update_entity_clientstate(Entity *entity)
{
if (!entity->state()) {
- entity->entity_clientstate = new core::ClientState(entity);
+ entity->entity_clientstate = new ClientState(entity);
entity->entity_clientstate->assign(entity);
}
@@ -134,7 +140,7 @@ void GameInterface::update_entity_clientstate(Entity *entity)
return;
}
- if (!(entity->flags() & core::Entity::Static)) {
+ if (!(entity->flags() & Entity::Static)) {
// clientstate location
entity->state()->state_location = entity->state()->previouslocation() +
@@ -156,7 +162,7 @@ void GameInterface::update_entity_clientstate(Entity *entity)
if (angle > MIN_DELTA)
entity->state()->state_axis.rotate(n, -angle);
}
-
+ /*
n.assign(math::crossproduct( entity->state()->axis().left(), entity->axis().left()));
if (!(n.length() < MIN_DELTA)) {
n.normalize();
@@ -174,7 +180,7 @@ void GameInterface::update_entity_clientstate(Entity *entity)
if (angle > MIN_DELTA)
entity->state()->state_axis.rotate(n, -angle);
}
-
+ */
} else {
entity->state()->state_axis.assign(entity->axis());
}
@@ -188,8 +194,7 @@ void GameInterface::update_clientstate(float seconds)
{
game_clientframetime += seconds;
- std::map<unsigned int, core::Entity *>::iterator it;
- for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
+ for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) {
update_entity_clientstate((*it).second);
}
}
diff --git a/src/core/gameserver.cc b/src/core/gameserver.cc
index afdc269..db8852a 100644
--- a/src/core/gameserver.cc
+++ b/src/core/gameserver.cc
@@ -188,10 +188,10 @@ GameServer::~GameServer()
server_network = 0;
}
- if (!Cvar::sv_dedicated->value())
- player_disconnect(localplayer());
-
if (server_module) {
+ if (server_module->running() && !Cvar::sv_dedicated->value())
+ player_disconnect(localplayer());
+
server_module->shutdown();
if (server_module != Module::preload())
@@ -480,6 +480,9 @@ void GameServer::player_disconnect(Player *player)
message.append("^B disconnects.");
broadcast(message, player);
+ // clear all player assets
+ player->clear_assets();
+
// notify the game module
server_module->player_disconnect(player);
@@ -533,8 +536,7 @@ void GameServer::frame(float seconds)
}
// run a time frame on each entity
- std::map<unsigned int, Entity *>::iterator it;
- for (it=Entity::registry.begin(); it != Entity::registry.end(); it++) {
+ for (Entity::Registry::iterator it=Entity::registry().begin(); it != Entity::registry().end(); it++) {
Entity *entity = (*it).second;
if ((entity->type() == Entity::Controlable) || (entity->type() == Entity::Dynamic)) {
@@ -562,8 +564,7 @@ void GameServer::frame(float seconds)
server_network->broadcast_frame(server_time, server_previoustime);
// send changes in the world
- std::map<unsigned int, Entity *>::iterator it;
- for (it=Entity::registry.begin(); it != Entity::registry.end(); it++) {
+ for (Entity::Registry::iterator it=Entity::registry().begin(); it != Entity::registry().end(); it++) {
Entity *entity = (*it).second;
@@ -573,7 +574,7 @@ void GameServer::frame(float seconds)
server_network->broadcast_entity_delete(entity);
}
- core::Entity::remove(entity->id());
+ core::Entity::erase(entity->id());
} else if (entity->entity_created) {
@@ -597,12 +598,12 @@ void GameServer::frame(float seconds)
} else {
// local update stub
- std::map<unsigned int, Entity *>::iterator it;
- for (it=Entity::registry.begin(); it != Entity::registry.end(); it++) {
+ for (Entity::Registry::iterator it=Entity::registry().begin(); it != Entity::registry().end(); it++) {
Entity *entity = (*it).second;
if (entity->entity_destroyed) {
- core::Entity::remove(entity->id());
+ Entity::erase(entity->id());
+
} else if (entity->entity_created) {
entity->entity_created = false;
diff --git a/src/core/net.h b/src/core/net.h
index 177aa14..c80b979 100644
--- a/src/core/net.h
+++ b/src/core/net.h
@@ -11,7 +11,7 @@ namespace core
{
/// network protocol version
-const unsigned int PROTOCOLVERSION = 2;
+const unsigned int PROTOCOLVERSION = 3;
/// maximum lenght of a (compressed) network message block
const unsigned int FRAMESIZE = 1152;
diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc
index 1bda423..db8e3a2 100644
--- a/src/core/netconnection.cc
+++ b/src/core/netconnection.cc
@@ -394,6 +394,7 @@ void NetConnection::send_say(std::string const &text)
* frame
* sup
* pif
+ * zone
*/
void NetConnection::parse_incoming_message(const std::string & message)
{
@@ -453,9 +454,9 @@ void NetConnection::parse_incoming_message(const std::string & message)
//con_debug << "Received die entity id " << id << std::endl;
Entity *e = Entity::find(id);
if (localcontrol() == e)
- localplayer()->player_control = 0;
+ localplayer()->set_control(0);
if (e)
- Entity::remove(id);
+ Entity::erase(id);
}
} else if (command == "ent") {
@@ -481,9 +482,25 @@ void NetConnection::parse_incoming_message(const std::string & message)
break;
}
}
+ } else if (command.compare("zone") == 0) {
+ unsigned int id;
+ std::string label;
+ if (msgstream >> id) {
+ con_debug << "Received create zone " << id << std::endl;
+ Zone * zone = Zone::find(id);
+
+ // create the zone if necessary
+ if (!zone) {
+ zone = new Zone(msgstream);
+ Zone::add(zone, id);
+ } else {
+ zone->receive_server_update(msgstream);
+ }
+ }
+
} else if (command == "pif") {
//con_debug << "Received update player info" << std::endl;
- connection()->localplayer()->recieve_server_update(msgstream);
+ connection()->localplayer()->receive_server_update(msgstream);
} else if (command == "sup") {
if (connection_state == Connected)
@@ -497,7 +514,7 @@ void NetConnection::parse_incoming_message(const std::string & message)
con_warn << "Update for unknown entity " << id << std::endl;
} else {
// FIXME check of the received update matches the actual entity
- entity->recieve_server_update(msgstream);
+ entity->receive_server_update(msgstream);
}
}
}
diff --git a/src/core/netserver.cc b/src/core/netserver.cc
index 2e50efd..10fd554 100644
--- a/src/core/netserver.cc
+++ b/src/core/netserver.cc
@@ -29,6 +29,7 @@
#include "core/func.h"
#include "core/core.h"
#include "core/stats.h"
+#include "core/zone.h"
#ifdef _WIN32
typedef int socklen_t;
@@ -53,15 +54,6 @@ NetServer::NetServer(std::string const host, unsigned int const port)
return;
}
- /*
- // set socket options
- socklen_t yes = 1;
- if (::setsockopt(netserver_fd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(socklen_t)) == -1) {
- con_error << "Network can't set socket options!" << std::endl;
- //perror("setsockopt");
- return;
- }
- */
// Get the local adress to bind to
netserver_addr.sin_family = AF_INET;
@@ -103,7 +95,7 @@ NetServer::~NetServer()
std::string netmsg("disconnect\n");
// delete all clients
- std::list<NetClient *>:: iterator it;
+ Clients:: iterator it;
for (it = clients.begin(); it != clients.end(); it++) {
// notify the game server
@@ -133,7 +125,7 @@ void NetServer::abort() {
// remove disconnected clients
void NetServer::reap()
{
- for (std::list<NetClient *>:: iterator it = clients.begin(); it != clients.end(); it++) {
+ for (Clients:: iterator it = clients.begin(); it != clients.end(); it++) {
NetClient *client = *it;
if (client->client_timeout + NETTIMEOUT < application()->time()) {
@@ -169,7 +161,7 @@ void NetServer::reap()
void NetServer::transmit()
{
- for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ for (Clients::iterator it = clients.begin(); it != clients.end(); it++) {
(*it)->transmit(fd());
}
}
@@ -220,7 +212,7 @@ void NetServer::receive()
// get messages from clients
bool msg_received = false;
- for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end() && !msg_received; it++) {
+ for (Clients::iterator it = clients.begin(); it != clients.end() && !msg_received; it++) {
NetClient *client = *it;
if ((client->host() == client_host) && (client->port() == (int) client_port)) {
@@ -282,25 +274,24 @@ NetClient * NetServer::client_connect(std::string const host, int const port)
void NetServer::client_initialize(NetClient *client) {
// send welcome message
- std::ostringstream netmsg;
- netmsg.str("");
- netmsg << "msg info ^B" << Cvar::sv_name->str() << "\n";
- client->send_raw(netmsg.str());
+ std::string welcome("^B");
+ welcome.append(Cvar::sv_name->str());
+ send_message(client, "info", welcome);
client->transmit(fd());
+ // send zones
+ for (Zone::Registry::iterator it = Zone::registry().begin(); it != Zone::registry().end(); it++) {
+ send_zone_update(client, (*it).second);
+ }
+
// send entities
- std::map<unsigned int, Entity *>::iterator it;
- for (it=Entity::registry.begin(); it != Entity::registry.end(); it++) {
- netmsg.str("");
- netmsg << "ent ";
- (*it).second->serialize(netmsg);
- netmsg << "\n";
- client->send_raw(netmsg.str());
+ for (Entity::Registry::iterator it = Entity::registry().begin(); it != Entity::registry().end(); it++) {
+ send_entity_create(client, (*it).second);
}
// send connect completed
- netmsg.str("connect\n");
- client->send_raw(netmsg.str());
+ std::string connect("connect\n");
+ client->send_raw(connect);
client->transmit(fd());
// set client state to pending
@@ -310,7 +301,7 @@ void NetServer::client_initialize(NetClient *client) {
// find the client corresponding to a player
NetClient *NetServer::find_client(Player const *player)
{
- for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ for (Clients::iterator it = clients.begin(); it != clients.end(); it++) {
if ((*it)->player() == player) {
return (*it);
}
@@ -331,6 +322,7 @@ NetClient *NetServer::find_client(Player const *player)
* msg <channel> <text>
* supported message channels are "info" "public" "rcon" and "snd"
* "snd" is a special channel to transmit sound events
+ * zone <id> <zone create/update data>
*/
// broadcast a "msg <channel>" message to all clients
@@ -345,7 +337,7 @@ void NetServer::broadcast_message(const char *channel, std::string const & messa
msg.append(message);
msg += '\n';
- for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ for (Clients::iterator it = clients.begin(); it != clients.end(); it++) {
if (((*it)->player() && (*it)->player() != ignore_player) && ((*it)->state() == NetClient::Connected)) {
(*it)->send_raw(msg);
}
@@ -382,7 +374,7 @@ void NetServer::broadcast_frame(float timestamp, float previoustimestamp)
std::ostringstream msg("");
msg << "frame " << timestamp << " " << previoustimestamp << "\n";
- for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ for (Clients::iterator it = clients.begin(); it != clients.end(); it++) {
if ((*it)->state() == NetClient::Connected) {
(*it)->send_raw(msg.str());
}
@@ -395,7 +387,7 @@ void NetServer::broadcast_entity_delete(Entity *entity)
std::ostringstream msg("");
msg << "die " << entity->id() << '\n';
- for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ for (Clients::iterator it = clients.begin(); it != clients.end(); it++) {
if ((*it)->state() == NetClient::Connected) {
(*it)->send_raw(msg.str());
}
@@ -410,13 +402,33 @@ void NetServer::broadcast_entity_create(Entity *entity)
entity->serialize(msg);
msg << '\n';
- for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ for (Clients::iterator it = clients.begin(); it != clients.end(); it++) {
if ((*it)->state() == NetClient::Connected) {
(*it)->send_raw(msg.str());
}
}
}
+// send a "ent" create entity message to all clients
+void NetServer::send_entity_create(NetClient *client, Entity *entity)
+{
+ std::ostringstream msg;
+ msg << "ent ";
+ entity->serialize(msg);
+ msg << '\n';
+ client->send_raw(msg.str());
+}
+
+// send a "zone" update zone message to a client
+void NetServer::send_zone_update(NetClient *client, Zone *zone)
+{
+ std::ostringstream msg;
+ msg << "zone ";
+ zone->serialize_server_update(msg);
+ msg << '\n';
+ client->send_raw(msg.str());
+}
+
// broadcast a "sup" server update entity message to all clients
void NetServer::broadcast_entity_update(Entity *entity)
{
@@ -425,7 +437,7 @@ void NetServer::broadcast_entity_update(Entity *entity)
entity->serialize_server_update(msg);
msg << '\n';
- for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ for (Clients::iterator it = clients.begin(); it != clients.end(); it++) {
if ((*it)->state() == NetClient::Connected) {
(*it)->send_raw(msg.str());
}
@@ -435,7 +447,7 @@ void NetServer::broadcast_entity_update(Entity *entity)
// broadcast a "pif" update player information if necessary
void NetServer::broadcast_player_update()
{
- for (std::list<NetClient *>::iterator it = clients.begin(); it != clients.end(); it++) {
+ for (Clients::iterator it = clients.begin(); it != clients.end(); it++) {
NetClient *client = *it;
if (client->player()->dirty()) {
@@ -525,7 +537,7 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
// client connection is completed on the first pif
if (command == "pif") {
std::string oldname(client->player()->name());
- client->player()->recieve_client_update(msgstream);
+ client->player()->receive_client_update(msgstream);
if (client->state() == NetClient::Pending) {
@@ -582,7 +594,7 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me
}
entitycontrolable->entity_dirty = true;
- entitycontrolable->recieve_client_update(msgstream);
+ entitycontrolable->receive_client_update(msgstream);
}
return;
}
diff --git a/src/core/netserver.h b/src/core/netserver.h
index d76676f..2340a5d 100644
--- a/src/core/netserver.h
+++ b/src/core/netserver.h
@@ -27,6 +27,8 @@ namespace core
class NetServer
{
public:
+ typedef std::list<NetClient *> Clients;
+
NetServer(std::string const host, unsigned int const port);
~NetServer();
@@ -70,6 +72,12 @@ public:
/// broadcast a create entity event
void broadcast_entity_create(Entity *entity);
+ /// send a create entity event to a single player
+ void send_entity_create(NetClient *client, Entity *entity);
+
+ /// send a zone update event to a single player
+ void send_zone_update(NetClient *client, Zone *zone);
+
/// broadcast a update entity event
void broadcast_entity_update(Entity *entity);
@@ -108,7 +116,7 @@ private:
char recbuf[FRAMESIZE];
- std::list<NetClient *> clients;
+ Clients clients;
};
}
diff --git a/src/core/player.cc b/src/core/player.cc
index 18dabed..9f531ed 100644
--- a/src/core/player.cc
+++ b/src/core/player.cc
@@ -26,6 +26,7 @@ Player::~Player()
void Player::clear()
{
player_id = 0;
+ player_zone = 0;
player_name.clear();
player_dirty = false;
player_rcon = false;
@@ -34,16 +35,21 @@ void Player::clear()
clear_assets();
}
-void Player::clear_assets()
+void Player::set_control(EntityControlable *entitycontrolable)
{
- // clear assets
- for (std::list<EntityControlable*>::iterator asset = assets.begin(); asset != assets.end(); asset++) {
- (*asset)->entity_owner = 0;
- (*asset)->die();
+ player_control = entitycontrolable;
+
+ if (entitycontrolable) {
+ player_zone = entitycontrolable->zone();
}
- assets.clear();
- player_control = 0;
+ player_dirty = true;
+}
+
+void Player::set_zone(Zone *zone)
+{
+ player_zone = zone;
+ player_dirty = true;
}
void Player::update_info()
@@ -76,7 +82,7 @@ void Player::serialize_client_update(std::ostream & os)
os << " " << player_color << " " << player_color_second << " \"" << player_name << "\"";
}
-void Player::recieve_client_update(std::istream &is)
+void Player::receive_client_update(std::istream &is)
{
is >> player_color;
is >> player_color_second;
@@ -93,24 +99,41 @@ void Player::recieve_client_update(std::istream &is)
void Player::serialize_server_update(std::ostream & os) const
{
+ unsigned int zone;
+ if (player_zone)
+ zone = player_zone->id();
+ else
+ zone = 0;
+
unsigned int co;
if (player_control)
co = player_control->id();
else
co = 0;
+
- os << player_id << " " << co << " " << player_color << " \"" << player_name << "\"";
+ os << player_id << " " << zone << " " << co << " " << player_color << " \"" << player_name << "\"";
}
-void Player::recieve_server_update(std::istream &is)
+void Player::receive_server_update(std::istream &is)
{
is >> player_id;
+
+ unsigned int zone = 0;
+ is >> zone;
+ if (zone) {
+ player_zone = Zone::find(zone);
+ } else {
+ player_zone = 0;
+ }
+
unsigned int co = 0;
is >> co;
if (co) {
Entity *e = Entity::find(co);
if (e && e->type() == Entity::Controlable) {
player_control = (EntityControlable *) e;
+ player_zone = player_control->zone();
} else {
player_control = 0;
con_warn << "control set to unknown entity " << co << "\n";
@@ -135,15 +158,24 @@ void Player::add_asset(EntityControlable *entity)
{
entity->entity_owner = this;
assets.push_back(entity);
+ con_debug << " adding asset " << entity->id() << " to player " << id() << std::endl;
}
void Player::remove_asset(EntityControlable *entity)
{
+ if (!entity)
+ return;
+
for (std::list<EntityControlable*>::iterator asset = assets.begin(); asset != assets.end(); asset++) {
- if ((*asset) == entity) {
+ if (((*asset) == entity) && (entity->owner() == this)) {
+ //con_debug << " removing asset " << (*asset)->id() << " from player " << id() << std::endl;
+
+ if ((*asset) == player_control)
+ player_control = 0;
(*asset)->entity_owner = 0;
(*asset)->die();
assets.erase(asset);
+ player_dirty = true;
return;
}
}
@@ -152,15 +184,38 @@ void Player::remove_asset(EntityControlable *entity)
void Player::remove_asset(unsigned int id)
{
+ if (!id)
+ return;
+
for (std::list<EntityControlable*>::iterator asset = assets.begin(); asset != assets.end(); asset++) {
- if ((*asset)->id() == id) {
+ if ( ((*asset)->id() == id) && ((*asset)->owner() == this) ) {
+ //con_debug << " removing asset " << (*asset)->id() << " from player " << this->id() << std::endl;
+
+ if ((*asset) == player_control)
+ player_control = 0;
+
(*asset)->entity_owner = 0;
(*asset)->die();
assets.erase(asset);
+ player_dirty = true;
return;
}
}
con_warn << "Could not remove asset " << id << " from player " << this->id() << "\n";
}
+void Player::clear_assets()
+{
+ // clear assets
+ for (std::list<EntityControlable*>::iterator asset = assets.begin(); asset != assets.end(); asset++) {
+ //con_debug << " removing asset " << (*asset)->id() << " from player " << id() << std::endl;
+
+ (*asset)->entity_owner = 0;
+ (*asset)->die();
+ }
+ assets.clear();
+
+ player_control = 0;
+}
+
}
diff --git a/src/core/player.h b/src/core/player.h
index e37c577..cdcdbd1 100644
--- a/src/core/player.h
+++ b/src/core/player.h
@@ -13,6 +13,7 @@ class Player;
}
#include "core/entity.h"
+#include "core/zone.h"
#include "math/mathlib.h"
#include <string>
@@ -44,6 +45,17 @@ public:
/// the entity the Player is currently controling
inline EntityControlable *control() const { return player_control; }
+ /// set the entity the player is currenty controlling
+ /** This will automaticly set zone() to the zone the entity is in
+ */
+ void set_control(EntityControlable *entitycontrolable);
+
+ /// the zone the player is currently in
+ inline Zone *zone() const { return player_zone; }
+
+ /// set the zone the player is currently in
+ void set_zone(Zone *zone);
+
/// player primary color
inline math::Color const & color() const { return player_color; }
@@ -59,13 +71,13 @@ public:
void serialize_server_update(std::ostream & os) const;
/// receive player info from a stream
- void recieve_server_update(std::istream &is);
+ void receive_server_update(std::istream &is);
/// serialize player info to a stream
void serialize_client_update(std::ostream & os);
/// receive player info from a stream
- void recieve_client_update(std::istream &is);
+ void receive_client_update(std::istream &is);
/// clear all the data
void clear();
@@ -108,12 +120,14 @@ public:
/// player is muted by admin
bool player_mute;
- /// the entity the Player is currently controling
- EntityControlable *player_control;
+ std::list<EntityControlable *> assets;
- std::list<EntityControlable*> assets;
+private:
+ // the entity the Player is currently controling
+ EntityControlable *player_control;
-
+ // the zone the player is currently in
+ Zone *player_zone;
};
}
diff --git a/src/filesystem/inifile.cc b/src/filesystem/inifile.cc
index 0cc690f..47baebf 100644
--- a/src/filesystem/inifile.cc
+++ b/src/filesystem/inifile.cc
@@ -187,6 +187,39 @@ bool IniFile::got_key_color(const char * keylabel, math::Color & color) {
}
}
+bool IniFile::got_key_bool(const char * keylabel, bool & b)
+{
+ if (last_read_was_key && (key_current.compare(keylabel) == 0 )) {
+ std::istringstream is(value_current);
+
+ unsigned int i;
+ if (is >> i) {
+ if (i) b = true; else b = false;
+ return true;
+ }
+
+ std::string val(value_current);
+ aux::trim(val);
+ aux::lowercase(val);
+
+ if (val.compare("yes") == 0) {
+ b = true;
+ return true;
+ } else if (val.compare("true") == 0) {
+ b = true;
+ return true;
+ } else if (val.compare("no") == 0) {
+ b = false;
+ return true;
+ } else if (val.compare("false") == 0) {
+ b = false;
+ return true;
+ }
+ }
+
+ return false;
+}
+
void IniFile::close()
{
inifile_ifs.close();
diff --git a/src/filesystem/inifile.h b/src/filesystem/inifile.h
index f5c903d..3efcfc4 100644
--- a/src/filesystem/inifile.h
+++ b/src/filesystem/inifile.h
@@ -73,6 +73,8 @@ public:
bool got_key_vector3f(const char * keylabel, math::Vector3f & v);
+ bool got_key_bool(const char * keylabel, bool & b);
+
inline unsigned int line() const {
return line_number;
diff --git a/src/game/game.cc b/src/game/game.cc
index 2d21be8..efca1be 100644
--- a/src/game/game.cc
+++ b/src/game/game.cc
@@ -20,7 +20,11 @@
namespace game
{
-ShipModel *default_shipmodel;
+Game *this_game = 0;
+
+ShipModel *default_shipmodel = 0;
+core::Zone *default_zone = 0;
+
/*----- engine game functions ------------------------------------- */
/// list the ship model registry
@@ -35,8 +39,11 @@ void func_join(core::Player *player, std::string const &args)
if (player->control())
return;
- player->player_control = new Ship(player, default_shipmodel);
- player->control()->entity_color = player->color();
+ player->set_zone(default_zone);
+ Ship *ship = new Ship(player, default_shipmodel);
+ ship->set_zone(default_zone);
+ player->set_control(ship);
+
core::server()->send_sound(player, "game/buy-ship");
std::string message("^B");
@@ -50,7 +57,7 @@ void func_join(core::Player *player, std::string const &args)
/// a player joins the spectators
void func_spectate(core::Player *player, std::string const &args)
{
- if (!player->player_control)
+ if (!player->control())
return;
std::string message("^B");
@@ -59,12 +66,8 @@ void func_spectate(core::Player *player, std::string const &args)
core::server()->broadcast(message);
if (player->control()) {
- // player has only ship for now
- player->player_control->die();
- player->player_control = 0;
+ player->remove_asset(player->control());
}
-
- player->player_dirty = true;
}
/// a player buys a ship
@@ -92,17 +95,16 @@ void func_buy(core::Player *player, std::string const &args)
if (shipmodel) {
// player has only ship for now
if (player->control()) {
- player->player_control->die();
- player->player_control = 0;
+ player->remove_asset(player->control());
}
- player->player_control = new Ship(player, shipmodel);
- player->control()->entity_color = player->color();
- player->control()->entity_color_second = player->color_second();
-
+ Ship * ship = new Ship(player, shipmodel);
+ ship->set_zone(default_zone);
+ player->set_control(ship);
+
core::server()->broadcast("^B" + player->name() + " ^Bpurchased " + aux::article(shipmodel->name()));
core::server()->send_sound(player, "game/buy-ship");
- player->player_dirty = true;
+
} else {
core::server()->send(player, "Usage: buy [^B" + helpstr + "^N]");
}
@@ -131,10 +133,49 @@ void func_hail(core::Player *player, std::string const &args)
core::server()->send_sound(targetplayer, "com/hail");
}
+/// a player actives the jumpdrive on his ship
+void func_jump(core::Player *player, std::string const &args)
+{
+ if (!player->control())
+ return;
+
+ if (!player->control()->moduletype() == ship_enttype)
+ return;
+
+ Ship * ship = static_cast<Ship *>(player->control());
+
+ if (!ship->jumpdrive()) {
+ core::server()->send(player, "Your ship is not equiped with a jumpdrive");
+ return;
+ }
+
+ std::string target;
+ std::istringstream is(args);
+ if (!(is >> target)) {
+ core::server()->send(player, "Usage: jump [system]");
+ return;
+ }
+
+ core::Zone *zone = core::Zone::find_zone(target);
+ if (!zone) {
+ core::server()->send(player, "Unknown system '" + target + '\'');
+ return;
+ }
+
+ if (zone == player->control()->zone())
+ return;
+
+ core::server()->send(player, "Jumping to '" + zone->name() + '\'');
+
+ player->control()->set_zone(zone);
+ player->set_zone(zone);
+}
+
/*----- Game ------------------------------------------------------ */
Game::Game() : core::Module("Project::OSiRiON")
{
+ this_game = this;
}
Game::~Game()
@@ -143,23 +184,130 @@ Game::~Game()
void Game::init()
{
- using math::Vector3f;
- using math::Color;
-
module_running = false;
ShipModel::clear();
- // setup the game world
+ if (!load_world()) {
+ abort();
+ return;
+ }
+
+ if (!load_ships()) {
+ abort();
+ return;
+ }
+
+ // add engine game functions
+ core::Func *func = 0;
+ func = core::Func::add("buy", (core::GameFuncPtr) func_buy);
+ func->set_info("buy a ship");
+ func = core::Func::add("jump", (core::GameFuncPtr) func_jump);
+ func->set_info("make a hyperspace jump");
+ func = core::Func::add("join", (core::GameFuncPtr) func_join);
+ func->set_info("join the game");
+ func = core::Func::add("hail", (core::GameFuncPtr) func_hail);
+ func->set_info("send a standard hail");
+ func = core::Func::add("spectate", (core::GameFuncPtr) func_spectate);
+ func->set_info("leave the game and spectate");
+
+ // add engine core functions
+ func = core::Func::add("list_ship", (core::FuncPtr) func_list_ship);
+ func->set_info("list ship statistics");
+
+ // set game variables
+ core::Cvar::set("g_impulsespeed", "10.0f", core::Cvar::Game);
+
+ // indicate the module is ready to run frames
+ module_running = true;
+}
+
+void Game::shutdown()
+{
+ // game functions are automaticly removed
+
+ // remove engine core functions
+ core::Func::remove("list_ship");
+
+ ShipModel::clear();
+ module_running = false;
+}
+
+bool Game::load_world()
+{
+ std::string inifilename("world");
+
filesystem::IniFile worldini;
- worldini.open("world");
+ worldini.open(inifilename);
if (!worldini.is_open()) {
- con_error << "Could not open ini/world.ini!" << std::endl;
- abort();
- return;
+ con_error << "Could not open " << worldini.name() << std::endl;
+ return false;
+ }
+
+ core::Zone *zone = 0;
+ std::string label;
+
+ while (worldini.getline()) {
+
+ if (worldini.got_section()) {
+
+ if (worldini.got_section("world")) {
+ continue;
+ } else {
+ con_warn << worldini.name() << " unknown section '" << worldini.section() << "' at line " << worldini.line() << std::endl;
+ }
+
+ } else if (worldini.section().compare("world") == 0 ) {
+ if (worldini.got_key_string("zone", label)) {
+ aux::trim(label);
+ aux::lowercase(label);
+ zone = new core::Zone(label);
+ core::Zone::add(zone);
+ }
+ }
+ }
+ worldini.close();
+
+ if (!core::Zone::registry().size()) {
+ con_error << "No zones found!" << std::endl;
+ return false;
+ }
+
+ con_debug << " " << worldini.name() << " " << core::Zone::registry().size() << " zones" << std::endl;
+
+ for (core::Zone::Registry::iterator it = core::Zone::registry().begin(); it != core::Zone::registry().end(); it++) {
+ if (!load_zone((*it).second)) {
+ return false;
+ }
+ }
+
+ if (!default_zone) {
+ con_error << "No default zone found!" << std::endl;
+ return false;
+ }
+
+ return true;
+}
+
+bool Game::load_zone(core::Zone *zone)
+{
+ using math::Vector3f;
+ using math::Color;
+
+ std::string inifilename("zones/");
+ inifilename.append(zone->label());
+
+ filesystem::IniFile zoneini;
+ zoneini.open(inifilename);
+
+ if (!zoneini.is_open()) {
+ con_error << "Could not open " << zoneini.name() << std::endl;
+ return false;
}
+ size_t count = 0;
+
Planet *planet = 0;
Star *star = 0;
core::Entity *entity = 0;
@@ -168,41 +316,61 @@ void Game::init()
float pitch;
float roll;
- while (worldini.getline()) {
- if (worldini.got_key()) {
- if (worldini.section().compare("star") == 0) {
- if (worldini.got_key_string("label", star->entity_label))
+ bool b;
+
+ std::string strval;
+
+ // set th default sky
+ zone->set_sky("sky");
+
+ while (zoneini.getline()) {
+ if (zoneini.got_key()) {
+ if (zoneini.section().compare("zone") == 0) {
+ if (zoneini.got_key_string("name", strval)) {
+ zone->set_name(strval);
+ continue;
+ } else if (zoneini.got_key_string("sky", strval)) {
+ zone->set_sky(strval);
+ continue;
+ } else if (zoneini.got_key_bool("default", b)) {
+ if (b) default_zone = zone;
continue;
- else if (worldini.got_key_string("name", star->entity_name))
+ } else {
+ con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl;
+ }
+ } else if (zoneini.section().compare("star") == 0) {
+ if (zoneini.got_key_string("label", star->entity_label))
continue;
- else if (worldini.got_key_vector3f("location", star->entity_location ))
+ else if (zoneini.got_key_string("name", star->entity_name))
continue;
- else if (worldini.got_key_color("color", star->entity_color))
+ else if (zoneini.got_key_vector3f("location", star->entity_location ))
continue;
- else if (worldini.got_key_angle("radius", star->entity_radius))
+ else if (zoneini.got_key_color("color", star->entity_color))
+ continue;
+ else if (zoneini.got_key_angle("radius", star->entity_radius))
continue;
else
- con_warn << worldini.name() << " unknown key '" << worldini.key() << "' at line " << worldini.line() << std::endl;
+ con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl;
- } else if (worldini.section().compare("planet") == 0) {
- if (worldini.got_key_string("label", planet->entity_label))
+ } else if (zoneini.section().compare("planet") == 0) {
+ if (zoneini.got_key_string("label", planet->entity_label))
continue;
- else if (worldini.got_key_string("name", planet->entity_name))
+ else if (zoneini.got_key_string("name", planet->entity_name))
continue;
- else if (worldini.got_key_string("texture", planet->entity_texture))
+ else if (zoneini.got_key_string("texture", planet->entity_texture))
continue;
- else if (worldini.got_key_vector3f("location", planet->entity_location ))
+ else if (zoneini.got_key_vector3f("location", planet->entity_location ))
continue;
- else if (worldini.got_key_color("color", planet->entity_color))
+ else if (zoneini.got_key_color("color", planet->entity_color))
continue;
- else if (worldini.got_key_angle("radius", planet->entity_radius))
+ else if (zoneini.got_key_angle("radius", planet->entity_radius))
continue;
else
- con_warn << worldini.name() << " unknown key '" << worldini.key() << "' at line " << worldini.line() << std::endl;
+ con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl;
- } else if (worldini.section().compare("entity") == 0) {
+ } else if (zoneini.section().compare("entity") == 0) {
std::string shapename;
- if (worldini.got_key_string("shape", shapename)) {
+ if (zoneini.got_key_string("shape", shapename)) {
if (shapename.compare("axis") == 0) {
entity->entity_shape = core::Entity::Axis;
} else if (shapename.compare("cube") == 0) {
@@ -212,65 +380,83 @@ void Game::init()
} else if (shapename.compare("sphere") == 0) {
entity->entity_shape = core::Entity::Sphere;
} else {
- con_warn << worldini.name() << " unknown shape '" << shapename << "' at line " << worldini.line() << std::endl;
+ con_warn << zoneini.name() << " unknown shape '" << shapename << "' at line " << zoneini.line() << std::endl;
}
continue;
- } else if (worldini.got_key_string("label", entity->entity_label)) {
+ } else if (zoneini.got_key_string("label", entity->entity_label)) {
continue;
- } else if (worldini.got_key_string("name", entity->entity_name)) {
+ } else if (zoneini.got_key_string("name", entity->entity_name)) {
continue;
- } else if (worldini.got_key_string("model", entity->entity_modelname)) {
+ } else if (zoneini.got_key_string("model", entity->entity_modelname)) {
continue;
- } else if (worldini.got_key_angle("direction", direction)) {
+ } else if (zoneini.got_key_angle("direction", direction)) {
entity->axis().change_direction(direction);
continue;
- } else if (worldini.got_key_angle("pitch", pitch)) {
+ } else if (zoneini.got_key_angle("pitch", pitch)) {
entity->axis().change_pitch(pitch);
continue;
- } else if (worldini.got_key_angle("roll", roll)) {
+ } else if (zoneini.got_key_angle("roll", roll)) {
entity->axis().change_roll(roll);
continue;
- } else if (worldini.got_key_angle("radius", entity->entity_radius)) {
+ } else if (zoneini.got_key_angle("radius", entity->entity_radius)) {
continue;
- } else if (worldini.got_key_vector3f("location", entity->entity_location)) {
+ } else if (zoneini.got_key_vector3f("location", entity->entity_location)) {
continue;
- } else if (worldini.got_key_color("color", entity->entity_color)) {
+ } else if (zoneini.got_key_color("color", entity->entity_color)) {
continue;
- } else if (worldini.got_key_color("colorsecond", entity->entity_color_second)) {
+ } else if (zoneini.got_key_color("colorsecond", entity->entity_color_second)) {
continue;
} else {
- con_warn << worldini.name() << " unknown key '" << worldini.key() << "' at line " << worldini.line() << std::endl;
+ con_warn << zoneini.name() << " unknown key '" << zoneini.key() << "' at line " << zoneini.line() << std::endl;
}
}
- } else if (worldini.got_section("star")) {
+ } else if (zoneini.got_section("zone")) {
+ continue;
+
+ } else if (zoneini.got_section("star")) {
star = new Star();
+ star->set_zone(zone);
+ count ++;
- } else if (worldini.got_section("planet")) {
+ } else if (zoneini.got_section("planet")) {
planet = new Planet();
+ planet->set_zone(zone);
+ count ++;
- } else if (worldini.got_section("entity")) {
+ } else if (zoneini.got_section("entity")) {
entity = new core::Entity();
entity->entity_flags += core::Entity::Static;
+ entity->set_zone(zone);
+ count ++;
- } else if (worldini.got_section()) {
- con_warn << worldini.name() << " unknown section '" << worldini.section() << "' at line " << worldini.line() << std::endl;
+ } else if (zoneini.got_section()) {
+ con_warn << zoneini.name() << " unknown section '" << zoneini.section() << "' at line " << zoneini.line() << std::endl;
}
}
- worldini.close();
+ zoneini.close();
+
+ con_debug << " " << zoneini.name() << " " << zone->content().size() << " entities" << std::endl;
+
+ return true;
+}
+
+// read ship model specifications
+bool Game::load_ships()
+{
+ using math::Vector3f;
+ using math::Color;
+
+ default_shipmodel = 0;
- // read ship model specifications
- // note:
- // do not reuse the previous IniFile instance, some gcc versions do not like it
filesystem::IniFile shipsini;
shipsini.open("ships");
if (!shipsini.is_open()) {
con_error << "Could not open ini/ships.ini!" << std::endl;
- abort();
- return;
+ return false;
}
ShipModel *shipmodel = 0;
- default_shipmodel = 0;
+ bool b;
while (shipsini.getline()) {
if (shipsini.got_key()) {
@@ -282,8 +468,10 @@ void Game::init()
continue;
} else if (shipsini.got_key_string("model", shipmodel->shipmodel_modelname)) {
continue;
- } else if (shipsini.got_key("default")) {
- default_shipmodel = shipmodel;
+ } else if (shipsini.got_key_bool("default", b)) {
+ if (b) default_shipmodel = shipmodel;
+ continue;
+ } else if (shipsini.got_key_bool("jumpdrive", shipmodel->shipmodel_jumpdrive)) {
continue;
} else if (shipsini.got_key_float("acceleration", shipmodel->shipmodel_acceleration)) {
continue;
@@ -307,43 +495,14 @@ void Game::init()
}
shipsini.close();
+ con_debug << " " << shipsini.name() << " " << ShipModel::registry.size() << " ship models" << std::endl;
+
if (!default_shipmodel) {
- con_error << "No default ship model in ini/ships.ini!\n";
- abort();
- return;
+ con_error << "No default ship model found!\n";
+ return false;
}
- // add engine game functions
- core::Func *func = 0;
- func = core::Func::add("buy", (core::GameFuncPtr) func_buy);
- func->set_info("buy a ship");
- func = core::Func::add("join", (core::GameFuncPtr) func_join);
- func->set_info("join the game");
- func = core::Func::add("hail", (core::GameFuncPtr) func_hail);
- func->set_info("send a standard hail");
- func = core::Func::add("spectate", (core::GameFuncPtr) func_spectate);
- func->set_info("leave the game and spectate");
-
- // add engine core functions
- func = core::Func::add("list_ship", (core::FuncPtr) func_list_ship);
- func->set_info("list ship statistics");
-
- // set game variables
- core::Cvar::set("g_impulsespeed", "10.0f", core::Cvar::Game);
-
- // indicate the module is ready to run frames
- module_running = true;
-}
-
-void Game::shutdown()
-{
- // game functions are automaticly removed
-
- // remove engine core functions
- core::Func::remove("list_ship");
-
- ShipModel::clear();
- module_running = false;
+ return true;
}
void Game::frame(float seconds)
@@ -355,16 +514,13 @@ void Game::frame(float seconds)
void Game::player_connect(core::Player *player)
{
std::string args;
+ player->set_zone(default_zone);
func_spectate(player, args);
}
void Game::player_disconnect(core::Player *player)
{
- if (player->control()) {
- // player has only one ship for now
- player->control()->die();
- player->player_control = 0;
- }
+ player->remove_asset(player->control());
}
} // namespace game
diff --git a/src/game/game.h b/src/game/game.h
index 89889a0..a715edd 100644
--- a/src/game/game.h
+++ b/src/game/game.h
@@ -47,6 +47,13 @@ public:
/// is called when a player disconnects
void player_disconnect(core::Player *player);
+
+private:
+ bool load_world();
+
+ bool load_zone(core::Zone *zone);
+
+ bool load_ships();
};
}
diff --git a/src/game/ship.cc b/src/game/ship.cc
index 66d8b52..f61c9bd 100644
--- a/src/game/ship.cc
+++ b/src/game/ship.cc
@@ -23,19 +23,23 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) :
entity_modelname = "ships/" + shipmodel->modelname();
entity_name = shipmodel->name() + ": <^B" + owner->name() + "^N>";
entity_label = shipmodel->label();
- ship_shipmodel = shipmodel;
entity_moduletypeid = ship_enttype;
current_target_direction = 0.0f;
current_target_pitch = 0.0f;;
- current_target_roll = 0.0f;;
+ current_target_roll = 0.0f;
+
+ entity_color = owner->color();
+ entity_color_second = owner->color_second();
+
+ ship_shipmodel = shipmodel;
+ ship_jumpdrive = shipmodel->shipmodel_jumpdrive;
}
Ship::~Ship()
{
- if (entity_owner)
- entity_owner->remove_asset(this);
+
}
void Ship::frame(float seconds)
diff --git a/src/game/ship.h b/src/game/ship.h
index 9e978bb..bca0857 100644
--- a/src/game/ship.h
+++ b/src/game/ship.h
@@ -24,12 +24,17 @@ public:
/// update the ship state
virtual void frame(float seconds);
+ /// true if the ship is equiped with a jumpdrive
+ inline bool jumpdrive() const { return ship_jumpdrive; }
+
private:
ShipModel *ship_shipmodel;
float current_target_direction;
float current_target_pitch;
float current_target_roll;
+
+ bool ship_jumpdrive;
};
}
diff --git a/src/game/shipmodel.cc b/src/game/shipmodel.cc
index aa0c2c9..6a226f4 100644
--- a/src/game/shipmodel.cc
+++ b/src/game/shipmodel.cc
@@ -19,6 +19,7 @@ ShipModel::ShipModel()
shipmodel_maxspeed = 3.0f;
shipmodel_turnspeed = 0.1f;
+ shipmodel_jumpdrive = false;
}
ShipModel::~ShipModel()
diff --git a/src/game/shipmodel.h b/src/game/shipmodel.h
index 686d736..a29f860 100644
--- a/src/game/shipmodel.h
+++ b/src/game/shipmodel.h
@@ -44,6 +44,9 @@ public:
std::string shipmodel_name;
std::string shipmodel_modelname;
+ /// indicates of this model can be equiped with a jump drive
+ bool shipmodel_jumpdrive;
+
static ShipModel *find(const std::string label);
/// the ship model registry
diff --git a/src/model/map.cc b/src/model/map.cc
index ad569eb..c68bb1d 100644
--- a/src/model/map.cc
+++ b/src/model/map.cc
@@ -912,7 +912,7 @@ Model * Map::load(std::string const &name)
*/
mapfile.load_fragments(model);
- con_print << " " << mapfile.name() << " " <<
+ con_debug << " " << mapfile.name() << " " <<
model->model_tris_count << "/" << model->model_tris_detail_count << " tris/detail " <<
model->model_quad_count << "/" << model->model_quad_detail_count << " quads/detail " <<
model->fragments().size() << " frags " <<std::endl;
diff --git a/src/render/draw.cc b/src/render/draw.cc
index 2e72529..b26b8ce 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -41,6 +41,7 @@ math::Vector3f v7(-1, -1, -1);
const float drawdistance = 128.0f;
const float drawfxdistance = 64.0f;
+core::Zone *zone = 0;
float angle = 0;
@@ -367,10 +368,8 @@ void pass_prepare(float seconds)
glGetDoublev(GL_MODELVIEW, gl_model_matrix);
glGetIntegerv(GL_VIEWPORT, gl_viewport);
- std::map<unsigned int, core::Entity *>::iterator it;
- for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
-
- core::Entity *entity = (*it).second;
+ for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) {
+ core::Entity *entity = (*it);
// load entity models and light flare textures
if (!entity->model() && entity->modelname().size()) {
@@ -503,9 +502,8 @@ void pass_prepare(float seconds)
/* Draw entities without model */
void draw_pass_default()
{
- std::map<unsigned int, core::Entity *>::iterator it;
- for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
- core::Entity *entity = (*it).second;
+ for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) {
+ core::Entity *entity = (*it);
// draw entities without model
if (!entity->model()) {
@@ -590,10 +588,9 @@ void draw_pass_default()
/* draw model geometry fragments */
void draw_pass_model_fragments()
{
- std::map<unsigned int, core::Entity *>::iterator it;
- for (it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
+ for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) {
+ core::Entity *entity = (*it);
- core::Entity *entity = (*it).second;
if (entity->model() && entity->state()->visible()) {
gl::push();
gl::translate(entity->state()->location());
@@ -619,8 +616,8 @@ void draw_pass_model_fx(float elapsed)
gl::begin(gl::Quads);
- for (std::map<unsigned int, core::Entity *>::iterator it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
- core::Entity *entity = (*it).second;
+ for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) {
+ core::Entity *entity = (*it);
if (entity->model() && entity->state()->detailvisible()) {
@@ -822,10 +819,10 @@ void draw_pass_model_corona()
if (!(r_radius && r_radius->value()))
return;
- for (std::map<unsigned int, core::Entity *>::iterator it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
- core::Entity *entity = (*it).second;
+ for (core::Zone::Content::iterator it = zone->content().begin(); it != zone->content().end(); it++) {
+ core::Entity *entity = (*it);
- if (entity->model() && entity->state() && entity->state()->visible()) {
+ if (entity->model() && entity->state()->visible()) {
gl::push();
gl::translate(entity->state()->location());
math::Color color = entity->color();
@@ -844,9 +841,20 @@ void draw_pass_sky()
if (!(r_sky && r_sky->value()))
return;
- size_t sky_texture = Textures::load("textures/env/sky");
- Textures::bind(sky_texture);
+ if (!core::localplayer()->zone())
+ return;
+
+ if (!core::localplayer()->zone()->sky_texture() && core::localplayer()->zone()->sky().size()) {
+ std::string texture_name("textures/env/");
+ texture_name.append(core::localplayer()->zone()->sky());
+ core::localplayer()->zone()->set_sky_texture(Textures::load(texture_name));
+
+ if (!core::localplayer()->zone()->sky_texture())
+ core::localplayer()->zone()->set_sky("");
+ }
+
+ Textures::bind(core::localplayer()->zone()->sky_texture());
gl::enable(GL_TEXTURE_2D);
gl::push();
@@ -901,7 +909,9 @@ void draw_pass_spacegrid()
void draw(float seconds)
{
- Stats::clear();
+ zone = core::localplayer()->zone();
+ if (!zone)
+ return;
// used for animations
angle += 180.0f * seconds;
diff --git a/src/render/render.cc b/src/render/render.cc
index cb0d4dd..dd5703a 100644
--- a/src/render/render.cc
+++ b/src/render/render.cc
@@ -108,8 +108,9 @@ void shutdown()
con_print << "^BShutting down renderer..." << std::endl;
// clear entity models, this will force a reload
- for (std::map<unsigned int, core::Entity *>::iterator it=core::Entity::registry.begin(); it != core::Entity::registry.end(); it++) {
+ for (core::Entity::Registry::iterator it = core::Entity::registry().begin(); it != core::Entity::registry().end(); it++) {
core::Entity *entity = (*it).second;
+
if (entity->model())
entity->entity_model = 0;
}
diff --git a/src/render/text.cc b/src/render/text.cc
index f5c221f..c64e331 100644
--- a/src/render/text.cc
+++ b/src/render/text.cc
@@ -32,13 +32,13 @@ void Text::init()
base_color[7] = new math::Color(1, 1, 1);
for (size_t i=0; i< 26; i++) {
- core_color[i] = new math::Color(.7, .7, .7);
+ core_color[i] = new math::Color(.75, .75, .75);
}
// N - normal color
- core_color[(size_t)('N'-'A')]->assign(.7, .7, .7);
+ core_color[(size_t)('N'-'A')]->assign(.75, .75, .75);
// D - Debug color
- core_color[(size_t)('D'-'A')]->assign(.6, .6, .6);
+ core_color[(size_t)('D'-'A')]->assign(.5, .5, .5);
// B - bold color
core_color[(size_t)('B'-'A')]->assign(1, 1, 1);
// W - warning color
diff --git a/src/render/tga.cc b/src/render/tga.cc
index fb4301b..fb65910 100644
--- a/src/render/tga.cc
+++ b/src/render/tga.cc
@@ -97,9 +97,6 @@ Image *TGA::load(const char *filename)
// byte 17 - image descriptor byte
unsigned int tga_descriptor = header[17];
- con_debug << " " << filename << " "
- << tga_width << "x" << tga_height << "x" << tga_depth << "bpp" << std::endl;
-
// read the image id if there is one
if (tga_idlength)
tga_file->skip(tga_idlength);
@@ -214,6 +211,8 @@ Image *TGA::load(const char *filename)
con_warn << filename << ": descriptor bit 4 (left-right) set!" << std::endl;
}
+ con_debug << " " << filename << " " << tga_width << "x" << tga_height << "x" << tga_depth << "bpp" << std::endl;
+
return image;
}