/* base/jumppoint.cc This file is part of the Osirion project and is distributed under the terms and conditions of the GNU General Public License version 2 */ #include "base/game.h" #include "base/jumppoint.h" #include "base/ship.h" namespace game { /* ---- class JumpPoint -------------------------------------------- */ const Template *JumpPoint::jumppoint_template = 0; JumpPoint::JumpPoint() : core::EntityDynamic() { set_shape(core::Entity::Diamond); // FIXME jumppoints should be harder to find set_flag(core::Entity::ShowOnMap); set_flag(core::Entity::NonSolid); get_color().assign(0.0f, 0.8f, 0.8f, 1.0f); get_color_second().assign(0.6f, 1.0f); set_radius(0.25f); set_flag(core::Entity::Bright); if (jumppoint_template) jumppoint_template->apply(this); entity_moduletypeid = jumppoint_enttype; jumppoint_target = 0; set_serverside(false); } JumpPoint::~JumpPoint() { } void JumpPoint::set_target_label(const std::string &label) { jumppoint_target_label.assign(label); } void JumpPoint::validate() { jumppoint_target = 0; if (target_label().size() == 0) return; if (target_label().size() < 3) { con_warn << " Jumppoint '" << label() << "' has invalid target '" << target_label() << "'\n"; return; } size_t pos = target_label().find(':'); if ((pos == std::string::npos) || (pos < 1) || (pos >= (target_label().size() - 1))) { con_warn << " Jumppoint '" << label() << "' has invalid target '" << target_label() << "'\n"; return; } std::string zonelabel(target_label().substr(0, pos)); std::string entitylabel(target_label().substr(pos + 1, target_label().size() - pos)); core::Zone *targetzone = core::Zone::find(zonelabel); if (!targetzone) { con_warn << " Jumppoint '" << label() << "' has invalid target zone '" << zonelabel << "'\n"; return; } core::Entity *targetentity = targetzone->find_entity(entitylabel); if (!targetentity) { con_warn << " Jumppoint '" << label() << "' has unknown target '" << entitylabel << "' in zone '" << zonelabel << "'\n"; return; } if ((targetentity->moduletype() != jumppoint_enttype) && (targetentity->moduletype() != jumpgate_enttype)) { con_warn << " Jumppoint '" << label() << "' has invalid target '" << entitylabel << "' in zone '" << zonelabel << "'\n"; return; } jumppoint_target = static_cast(targetentity); // overwrite name and info, remove the "system" part from the name std::string name("Jumppoint " + zone()->name() + " -> " + target()->zone()->name()); for (size_t pos = name.find(" system"); pos != std::string::npos; pos = name.find(" system")) { name.erase(pos, 7); } set_name(name); // info is const, core::Info::find returns a non-const pointer core::Info *entity_info = core::Info::find(info()); if (!entity_info) { std::string labelstr(zone()->label()); labelstr += ':'; labelstr.append(label()); entity_info = new core::Info(core::Entity::infotype(), labelstr.c_str()); set_info(entity_info); } entity_info->set_name("Jumppoint"); entity_info->clear_text(); entity_info->add_text("Jumppoint to the " + target()->zone()->name()); con_debug << " " << label() << " jumppoint to " << target()->zone()->label() << ":" << target()->label() << std::endl; } /* ---- class JumpGate --------------------------------------------- */ const Template *JumpGate::jumpgate_template = 0; JumpGate::JumpGate() : JumpPoint() { entity_moduletypeid = jumpgate_enttype; unset_flag(core::Entity::Bright); unset_flag(core::Entity::NonSolid); set_flag(core::Entity::ShowOnMap); set_radius(0.0f); set_state(core::Entity::NoPower); if (jumpgate_template) jumpgate_template->apply(this); jumpgate_timer = 0; } JumpGate::~JumpGate() { } void JumpGate::validate() { JumpPoint::validate(); if (target()) { set_flag(core::Entity::Dockable); // overwrite name and info // overwrite name and info, remove the "system" part from the name std::string name("Jumpgate " + zone()->name() + " -> " + target()->zone()->name()); for (size_t pos = name.find(" system"); pos != std::string::npos; pos = name.find(" system")) { name.erase(pos, 7); } set_name(name); core::Info *entity_info = core::Info::find(info()); entity_info->set_name("Jumpgate"); entity_info->clear_text(); // FIXME if 'system' was erased from the name, 'the' should not appear in the info text // e.g. Jumpgate to Kor Telos entity_info->add_text("Jumpgate to the " + target()->zone()->name()); } else { unset_flag(core::Entity::Dockable); std::string name("Inactive Jumpgate"); set_name(name); } } void JumpGate::func_dock(Ship *ship) { if (target()) { // check if this jumpgate is in use if (activated()) { if (ship->owner()) { ship->owner()->send("Jumpgate in use"); } return; } if (target()->moduletype() == jumpgate_enttype) { // check if the target jumpgate is in use if (static_cast(target())->activated()) { if (ship->owner()) { ship->owner()->send("Jumpgate in use"); } return; } // activate target jumpgate static_cast(target())->activate(); } // activate jumpgate activate(); ship->initiate_jump(this); if (ship->owner() && ship->owner()->control() == ship) { ship->owner()->set_view(this); } } else { if (ship->owner()) ship->owner()->send("Jumpgate inactive"); return; } } void JumpGate::activate() { jumpgate_timer = (jump_timer_delay + jump_cooldown_delay) * 1000; set_state(core::Entity::Normal); } void JumpGate::frame(const unsigned long elapsed) { if (jumpgate_timer > 0) { if (jumpgate_timer > elapsed) { jumpgate_timer -= elapsed; } else if (state() != core::Entity::NoPower) { set_state(core::Entity::NoPower); jumpgate_timer = 0; } } } }