/* base/weapon.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 #include #include "sys/sys.h" #include "filesystem/inifile.h" #include "auxiliary/functions.h" #include "core/func.h" #include "base/cargopod.h" #include "base/game.h" #include "base/weapon.h" namespace game { core::InfoType *Weapon::weapon_infotype = 0; void func_list_weapons(const std::string &args) { Weapon::list(); } // load weapon types from ini file bool Weapon::init() { // initialize weapon InfoType weapon_infotype = new core::InfoType("weapon"); filesystem::IniFile inifile; inifile.open("ini/weapons"); if (!inifile.is_open()) { con_error << "Could not open " << inifile.name() << "!" << std::endl; return false; } con_print << "^BLoading weapons..." << std::endl; size_t count = 0; Weapon *weapon = 0; std::string str; long l; float f; while (inifile.getline()) { if (inifile.got_key()) { if (inifile.section().compare("mine") == 0) { if (inifile.got_key_label("label", str)) { weapon->set_label(str); continue; } else if (inifile.got_key_string("name", str)) { weapon->set_name(str); continue; } else if (inifile.got_key_string("info", str)) { weapon->add_text(str); continue; } else if (inifile.got_key_string("model", str)) { weapon->set_modelname(str); continue; } else if (inifile.got_key("level")) { core::Level level; std::istringstream str(inifile.value()); if (str >> level) { weapon->set_level(level); } else { inifile.unknown_value(); } } else if (inifile.got_key_long("price", l)) { weapon->set_price(l); continue; } else if (inifile.got_key_float("volume", f)) { weapon->set_volume(f); continue; } else if (inifile.got_key_long("level", l)) { weapon->set_level(l); continue; } else if (inifile.got_key_float("damage", f)) { weapon->set_damage(f); continue; } else { inifile.unknown_key(); } } else if (inifile.section().compare("cannon") == 0) { if (inifile.got_key_label("label", str)) { weapon->set_label(str); continue; } else if (inifile.got_key_string("name", str)) { weapon->set_name(str); continue; } else if (inifile.got_key_string("info", str)) { weapon->add_text(str); continue; } else if (inifile.got_key_string("model", str)) { weapon->set_modelname(str); continue; } else if (inifile.got_key_long("price", l)) { weapon->set_price(l); continue; } else if (inifile.got_key_float("volume", f)) { weapon->set_volume(f); continue; } else if (inifile.got_key_long("level", l)) { weapon->set_level(l); continue; } else { inifile.unknown_key(); } } else if (inifile.section().compare("turret") == 0) { if (inifile.got_key_label("label", str)) { weapon->set_label(str); continue; } else if (inifile.got_key_string("name", str)) { weapon->set_name(str); continue; } else if (inifile.got_key_string("info", str)) { weapon->add_text(str); continue; } else if (inifile.got_key_string("model", str)) { weapon->set_modelname(str); continue; } else if (inifile.got_key_long("price", l)) { weapon->set_price(l); continue; } else if (inifile.got_key_float("volume", f)) { weapon->set_volume(f); continue; } else if (inifile.got_key_long("level", l)) { weapon->set_level(l); continue; } else { inifile.unknown_key(); } } else if (inifile.section().compare("projectile") == 0) { if (weapon) { if (inifile.got_key_float("speed", f)) { // convert speed from meters/second to game units/second weapon->set_projectile_speed(f * 0.01f); continue; } else if (inifile.got_key_long("interval", l)) { weapon->set_projectile_interval((unsigned long) l); continue; } else if (inifile.got_key_long("lifespan", l)) { // lifespan in milliseconds weapon->set_projectile_lifespan((unsigned long) l); continue; } else if (inifile.got_key_float("range", f)) { // range in meters, one game unit is 100 meters if (weapon->projectile_speed() == 0) { inifile.unknown_error("cannot set range if projectile speed is 0!"); } else { weapon->set_projectile_lifespan((unsigned long) (10.0f * f / weapon->projectile_speed())); } continue; } else if (inifile.got_key_float("damage", f)) { weapon->set_damage(f); continue; } else if (inifile.got_key_string("model", str)) { weapon->set_projectile_modelname(str); continue; } else if (inifile.got_key_string("sound", str)) { weapon->set_projectile_soundname(str); continue; } else { inifile.unknown_key(); } } } } else if (inifile.got_section()) { Weapon *previous = 0; if (inifile.got_section("mine")) { previous = weapon; weapon = new Weapon(); weapon->set_subtype(Mine); count++; } else if (inifile.got_section("cannon")) { previous = weapon; weapon = new Weapon(); weapon->set_subtype(Cannon); count++; } else if (inifile.got_section("turret")) { previous = weapon; weapon = new Weapon(); weapon->set_subtype(Turret); count++; } else if (inifile.got_section("projectile")) { if (!weapon) { inifile.unknown_error("projectile section without weapon section"); } } else if (inifile.got_section()) { inifile.unknown_section(); } if (previous) { previous->generate_info(); } } } if (weapon) { weapon->generate_info(); } // add weapon infos con_debug << " " << inifile.name() << " " << count << " weapon types" << std::endl; inifile.close(); core::Func *func = core::Func::add("list_weapons", func_list_weapons); func->set_info("list available weapon types"); return true; } void Weapon::done() { core::Func::remove("list_weapons"); } Weapon *Weapon::find(const std::string & label) { if (!label.size()) { return 0; } return (Weapon *) core::Info::find(weapon_infotype, label); } void Weapon::list() { core::Info::list(weapon_infotype); } /* ---- class Weapon ------------------------------------------- */ Weapon::Weapon() : core::Info(weapon_infotype) { set_volume(1); set_level(1); set_subtype(Ammo); set_damage(0); set_projectile_interval(0); set_projectile_lifespan(0); set_projectile_speed(0); } Weapon::~Weapon() { } void Weapon::set_level(const int level) { weapon_level = level; } void Weapon::set_subtype(const SubType subtype) { weapon_subtype = subtype; } void Weapon::generate_info() { if (text().size()) add_line(""); add_line("^BSpecifications:^N"); std::stringstream str; str << "price: ^B" << price() << " ^Ncredits"; add_line(str.str()); str.str(""); str << "volume: ^B" << volume() << " ^Ncubic meter"; add_line(str.str()); str.str(""); add_line(""); if ((subtype() == Cannon) || (subtype() == Turret)) { str << "damage: ^B" << damage() << "^N"; add_line(str.str()); str.str(""); str << "range: ^B" << floor(((float) projectile_lifespan() * projectile_speed()) / 10.0f) << " ^Nmeter"; add_line(str.str()); str.str(""); str << "speed: ^B" << floor(projectile_speed()) * 100.0f << " ^Nmeter/sec"; add_line(str.str()); str.str(""); str << "fire rate: ^B" << "1/" << projectile_interval() << " ^Nmilliseconds"; add_line(str.str()); str.str(""); } else { str << "damage: ^B" << damage() << "^N"; add_line(str.str()); str.str(""); } } } // namespace game