Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-07-28 19:37:31 +0000
committerStijn Buys <ingar@osirion.org>2008-07-28 19:37:31 +0000
commitd389a31f9816b55d8c7685ec24b9ab814252d693 (patch)
tree9b2577692e543fa6c59fcda508f92c3eb839ac7a /src/core
parent17408276791033e8122819185abf3bcb01740105 (diff)
zone support
Diffstat (limited to 'src/core')
-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
18 files changed, 434 insertions, 183 deletions
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;
};
}