/* core/zone.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 "auxiliary/functions.h" #include "core/zone.h" #include "sys/sys.h" namespace core { /* ---- Static functions for the Zone registry ------------------- */ // zone registry Zone::Registry Zone::zone_registry; // info type for zone information const InfoType *Zone::zone_infotype = 0; void Zone::add(Zone *zone) { unsigned int id = 1; for (Registry::iterator it = zone_registry.begin(); it != zone_registry.end() && id == (*it).second->zone_id; it++) { id++; } zone->zone_id = id; zone_registry[id] = zone; } void Zone::add(Zone *zone, unsigned int id) { Registry::iterator it = zone_registry.find(id); if (it == zone_registry.end()) { zone->zone_id = id; zone_registry[id] = zone; } } Zone *Zone::find(unsigned int id) { Registry::iterator it = zone_registry.find(id); if (it == zone_registry.end()) return 0; else return (*it).second; } Zone *Zone::find(std::string const & name) { for (Registry::iterator it = zone_registry.begin(); it != zone_registry.end(); it++) { if ((*it).second->label().compare(name) == 0) { return (*it).second; } } return 0; } Zone *Zone::search(std::string const & searchname) { std::string strsearchkey(aux::lowercase(searchname)); std::stringstream str(strsearchkey); unsigned int id; if (str >> id) return find(id); if (strsearchkey.size() < 3) { return 0; } std::string label; std::string name; for (Registry::iterator it = zone_registry.begin(); it != zone_registry.end(); it++) { Zone *zone = (*it).second; label.assign(zone->label()); if (label.size() && (label.find(strsearchkey) != std::string::npos)) { return zone; } name.assign(aux::lowercase(zone->name())); if (name.size() && (name.find(strsearchkey) != std::string::npos)) { return zone; } } return 0; } void Zone::list() { con_print << " " << " id " << "label " << "name" << std::endl; for (Registry::iterator it = zone_registry.begin(); it != zone_registry.end(); it++) { Zone *zone = (*it).second; con_print << " " << "^B" << std::setw(4) << zone->id() << " " << "^N" << aux::pad_right(zone->label(), 24) << " " << "^N" << zone->name() << std::endl; } con_print << "^B " << zone_registry.size() << " zones" << std::endl; } void Zone ::clear() { for (Registry::iterator it = zone_registry.begin(); it != zone_registry.end(); it++) { delete(*it).second; } zone_registry.clear(); } /* ---- class Zone ------------------------------------------------- */ Zone::Zone(std::string const & label) : Label(label), zone_location(), zone_color(1.0f), zone_ambient_color(0.1f) { zone_id = 0; zone_defaultview = 0; zone_info = 0; zone_flags = 0; btVector3 worldAabbMin(-10000, -10000, -10000); btVector3 worldAabbMax(10000, 10000, 10000); const int maxProxies = 1024; zone_bullet_cache = new btAxisSweep3(worldAabbMin, worldAabbMax, maxProxies); zone_bullet_world = new btDiscreteDynamicsWorld(Physics::dispatcher(), zone_bullet_cache, Physics::solver(), Physics::configuration()); zone_bullet_raycaster = new btDefaultVehicleRaycaster(zone_bullet_world); // disable gravity zone_bullet_world->setGravity(btVector3(0.0f, 0.0f, 0.0f)); } Zone::Zone(std::istream & is) : Label(), zone_location(), zone_color(1.0f), zone_ambient_color(0.1f) { zone_id = 0; zone_defaultview = 0; zone_info = 0; zone_flags = 0; // client side does not setup a bullet physics environment zone_bullet_cache = 0; zone_bullet_world = 0; zone_bullet_raycaster = 0; receive_server_update(is); } Zone::~Zone() { for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) { (*it) = 0; } zone_content.clear(); if (zone_bullet_world) delete zone_bullet_world; if (zone_bullet_raycaster) delete zone_bullet_raycaster; if (zone_bullet_cache) delete zone_bullet_cache; } void Zone::set_info(const Info *info) { zone_info = info; } void Zone::set_color(const math::Color & color) { zone_color.assign(color); } void Zone::set_color(float r, float g, float b) { zone_color.assign(r, g, b); } void Zone::print() { con_print << " zone id ^B" << id() << " ^Nlabel ^B" << label() << " ^Nname ^B" << name() << std::endl; Entity::list_header(); for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) { Entity *entity = (*it); Entity::list(entity); } con_print << " ^B" << zone_content.size() << " zone entities" << std::endl; } void Zone::add(Entity *entity) { zone_content.push_back(entity); } void Zone::remove(Entity *entity) { for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) { if ((*it) == entity) { zone_content.erase(it); return; } } } Entity *Zone::find_entity(const Entity *entity) { for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) { if ((*it) == entity) { return (*it); } } return 0; } Entity *Zone::find_entity(unsigned int id) { for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) { if ((*it)->id() == id) { return (*it); } } return 0; } Entity *Zone::find_entity(const std::string & label) { for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) { if ((*it)->label().compare(label) == 0) { return (*it); } } return 0; } Entity *Zone::search_entity(const std::string & searchname) { std::string strsearchkey(aux::lowercase(searchname)); std::stringstream str(strsearchkey); unsigned int id; if (str >> id) return find_entity(id); if (strsearchkey.size() < 3) { return 0; } std::string label; std::string name; for (Content::iterator it = zone_content.begin(); it != zone_content.end(); it++) { Entity *entity = (*it); if (!entity->serverside()) { label.assign(entity->label()); if (label.size() && (label.find(strsearchkey) != std::string::npos)) { return entity; } name.assign(aux::lowercase(entity->name())); if (name.size() && (name.find(strsearchkey) != std::string::npos)) { return entity; } } } return 0; } void Zone::serialize_server_update(std::ostream & os) const { os << label() << " "; os << "\"" << name() << "\" "; os << "\"" << zone_sky << "\" "; os << zone_ambient_color.r << " "; os << zone_ambient_color.g << " "; os << zone_ambient_color.b << " "; os << (zone_defaultview ? zone_defaultview->id() : 0) << " "; os << zone_location << " "; os << zone_flags << " "; os << zone_color.r << " "; os << zone_color.g << " "; os << zone_color.b; } void Zone::receive_server_update(std::istream &is) { unsigned int id = 0; float r = 0.1f, g = 0.1f, b = 0.1f; std::string n; char c; // zone label is >> n; set_label(n); n.clear(); // zone name while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; set_name(n); n.clear(); // sky name while ((is.get(c)) && (c != '"')); while ((is.get(c)) && (c != '"')) n += c; zone_sky.assign(n); n.clear(); // ambient light color is >> r >> g >> b; zone_ambient_color.assign(r, g, b); // default view is >> id; zone_defaultview = Entity::find(id); // location is >> zone_location; // flags is >> zone_flags; // zone color is >> r >> g >> b; zone_color.assign(r, g, b); } }