/* core/entity.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2. */ #include #include #include "sys/sys.h" #include "core/entity.h" #include "core/cvar.h" namespace core { using math::Color; using math::Vector3f; /* ---- Static functions for the Entity registry ------------------- */ std::map Entity::registry; void Entity::add(Entity *ent) { std::map::iterator it; unsigned int id = 1; for (it = registry.begin(); it != registry.end() && id == (*it).second->id(); it++) { id++; } ent->entity_id = id; registry[id] = ent; } void Entity::add(Entity *ent, unsigned int id) { if (find(id)) { con_warn << "Duplicate entity " << id << "!\n"; return; } ent->entity_id = id; registry[id] = ent; } Entity *Entity::find(unsigned int id) { std::map::iterator it = registry.find(id); if (it == registry.end()) return 0; else return (*it).second; } void Entity::remove(unsigned int id) { std::map::iterator it = registry.find(id); if (it != registry.end()) { delete((*it).second); registry.erase(it); } else { con_warn << "Could not remove entity " << id << "!\n"; } } void Entity::list() { std::map::iterator it; for (it = registry.begin(); it != registry.end(); it++) { std::string typeindicator; Entity *entity = (*it).second; con_print << " id " << std::setw(4) << entity->id() << " type " << std::setw(4) << entity->type() << ":" << std::setw(4) << entity->moduletype() << " " << entity->name() << std::endl; } con_print << registry.size() << " registered entities" << std::endl; } /*----- Entity ----------------------------------------------------- */ Entity::Entity(unsigned int flags) : entity_location(0.0f, 0.0f, 0.0f), entity_color(1.0f, 1.0f, 1.0f, 1.0f) { entity_id = 0; entity_flags = flags; entity_moduletypeid = 0; entity_radius = 1.0f; entity_shape = Diamond; entity_created = true; entity_destroyed = false; entity_dirty = false; entity_model = 0; entity_modelname.clear(); entity_name.clear(); entity_clientstate = 0; add(this); } Entity::Entity(std::istream & is) { // type is already determined unsigned int s; std::string n; is >> entity_id; is >> entity_moduletypeid; is >> entity_flags; is >> entity_location; is >> entity_color; is >> s; // shape is >> entity_radius; is >> entity_axis[0]; is >> entity_axis[1]; entity_axis[2] = math::crossproduct(entity_axis.forward(), entity_axis.left()); entity_shape = (Shape) s ; char c; while ( (is.get(c)) && (c != '"')); while ( (is.get(c)) && (c != '"')) n += c; entity_name = n; n.clear(); while ( (is.get(c)) && (c != '"')); while ( (is.get(c)) && (c != '"')) n += c; entity_modelname = n; entity_model = 0; // this will be resolved later entity_created = true; entity_destroyed = false; entity_dirty = false; // this entity is created clientside entity_clientstate = 0; add(this, entity_id); } Entity::~Entity() { if (entity_clientstate) delete entity_clientstate; } void Entity::serialize(std::ostream & os) const { os << type() << " " << entity_id << " " << entity_moduletypeid << " " << entity_flags << " " << entity_location << " " << entity_color << " " << entity_shape << " " << entity_radius << " " << entity_axis.forward() << " " << entity_axis.left() << " " << "\"" << entity_name << "\" " << "\"" << entity_modelname << "\""; } void Entity::serialize_client_update(std::ostream & os) const { } void Entity::recieve_client_update(std::istream &is) { } void Entity::serialize_server_update(std::ostream & os) const { } void Entity::recieve_server_update(std::istream &is) { } void Entity::frame(float seconds) { } /* ---- EntityDynamic ---------------------------------------------- */ EntityDynamic::EntityDynamic(unsigned int flags) : Entity(flags) { entity_speed = 0.0f; } EntityDynamic::EntityDynamic(std::istream & is) : Entity(is) { is >> entity_speed; } EntityDynamic::~EntityDynamic() { } void EntityDynamic::frame(float seconds) { if ((flags() & Static) == Static) return; if (entity_speed == 0) return; entity_location += entity_axis.forward() * entity_speed * seconds; entity_dirty = true; } void EntityDynamic::serialize(std::ostream & os) const { Entity::serialize(os); os << " " << entity_speed; } void EntityDynamic::serialize_client_update(std::ostream & os) const { } void EntityDynamic::recieve_client_update(std::istream &is) { } void EntityDynamic::serialize_server_update(std::ostream & os) const { os << entity_location << " "; os << entity_axis.forward() << " "; os << entity_axis.left() << " "; os << entity_speed; } void EntityDynamic::recieve_server_update(std::istream &is) { 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; } /*----- EntityControlable ------------------------------------------ */ EntityControlable::EntityControlable(Player *player, 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; } EntityControlable::EntityControlable(std::istream & is) : EntityDynamic(is) { unsigned int o; is >> entity_thrust; is >> o; // FIXME resolve owner entity_owner = 0; } EntityControlable::~EntityControlable() { if (entity_owner) entity_owner->remove_asset(this); } void EntityControlable::serialize(std::ostream & os) const { EntityDynamic::serialize(os); os << " " << entity_thrust; os << " " << entity_owner->id(); } void EntityControlable::serialize_client_update(std::ostream & os) const { EntityDynamic::serialize_client_update(os); os << " " << target_direction; os << " " << target_pitch; os << " " << target_thrust; os << " " << target_roll; } void EntityControlable::recieve_client_update(std::istream &is) { EntityDynamic::recieve_client_update(is); is >> target_direction; is >> target_pitch; is >> target_thrust; is >> target_roll; } void EntityControlable::serialize_server_update(std::ostream & os) const { EntityDynamic::serialize_server_update(os); os << " " << entity_thrust; } void EntityControlable::recieve_server_update(std::istream &is) { EntityDynamic::recieve_server_update(is); is >> entity_thrust; } void EntityControlable::frame(float seconds) { //entity_direction = target_direction; //entity_thrust = target_thrust; //entity_dirty = true; EntityDynamic::frame(seconds); } void EntityControlable::set_thrust(float thrust) { if ((flags() & Static) == Static) return; if (thrust != target_thrust) { target_thrust = thrust; entity_dirty = true; } } void EntityControlable::set_direction(float direction) { if ((flags() & Static) == Static) return; if (target_direction != direction) { target_direction = direction; entity_dirty = true; } } void EntityControlable::set_pitch(float pitch) { if ((flags() & Static) == Static) return; if (target_pitch != pitch) { target_pitch = pitch; entity_dirty = true; } } void EntityControlable::set_roll(float roll) { if ((flags() & Static) == Static) return; if (target_roll != roll) { target_roll = roll; entity_dirty = true; } } /*----- EntityGlobe ------------------------------------------------ */ EntityGlobe::EntityGlobe(unsigned int flags) : Entity(flags) { render_texture = 0; entity_shape = Sphere; } EntityGlobe::EntityGlobe(std::istream & is) : Entity(is) { render_texture = 0; entity_shape = Sphere; std::string n; char c; while ( (is.get(c)) && (c != '"')); while ( (is.get(c)) && (c != '"')) n += c; entity_texture = n; n.clear(); } EntityGlobe::~EntityGlobe() { } void EntityGlobe::serialize(std::ostream & os) const { Entity::serialize(os); os << " \"" << entity_texture << "\""; } }