/* base/shipmodel.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 "auxiliary/functions.h" #include "base/shipmodel.h" #include "base/game.h" #include "sys/sys.h" namespace game { core::InfoType *ShipModel::shipmodel_infotype = 0; bool ShipModel::init() { // initialize shipmodel InfoType ShipModel::shipmodel_infotype = new core::InfoType("ship"); using math::Vector3f; using math::Color; filesystem::IniFile shipsini; shipsini.open("ships"); if (!shipsini.is_open()) { con_error << "Could not open " << shipsini.name() << "!" << std::endl; return false; } con_print << "^BLoading ships..." << std::endl; size_t count = 0; ShipModel *shipmodel = 0; std::string str; long l; float f; bool b; while (shipsini.getline()) { if (shipsini.got_key()) { if (shipsini.section().compare("ship") == 0) { if (shipsini.got_key_label("label", str)) { shipmodel->set_label(str); count++; continue; } else if (shipsini.got_key_string("name", str)) { shipmodel->set_name(str); continue; } else if (shipsini.got_key_string("info", str)) { shipmodel->add_text(str); continue; } else if (shipsini.got_key_string("model", str)) { shipmodel->set_modelname(str); continue; } else if (shipsini.got_key_long("price", l)) { shipmodel->set_price(l); continue; } else if (shipsini.got_key_float("cargo", f)) { shipmodel->set_maxcargo(f); continue; } else if (shipsini.got_key_bool("jumpdrive", b)) { shipmodel->set_jumpdrive(b); continue; } else if (shipsini.got_key_bool("dock", b)) { shipmodel->set_dock(b); continue; } else if (shipsini.got_key_float("acceleration", f)) { shipmodel->set_acceleration(f); continue; } else if (shipsini.got_key_float("maxspeed", f)) { shipmodel->set_maxspeed(f); continue; } else if (shipsini.got_key_float("turnspeed", f)) { math::clamp(f, 0.0f, 90.0f); shipmodel->set_turnspeed(f); continue; } else { shipsini.unkown_key(); } } } else if (shipsini.got_section("ship")) { // generate info for the last loaded ship model if (shipmodel) { shipmodel->generate_info(); } // add a new shipmodel shipmodel = new ShipModel(); if (!Default::shipmodel) { Default::shipmodel = shipmodel; } } else if (shipsini.got_section()) { shipsini.unknown_section(); } } // generate info for the last loaded ship model if (shipmodel) { shipmodel->generate_info(); } con_debug << " " << shipsini.name() << " " << count << " ship types" << std::endl; shipsini.close(); return true; } ShipModel::ShipModel() : core::Info(shipmodel_infotype) { //default specifications shipmodel_acceleration = 1.0f; // thruster acceleration in game untits/second^2 shipmodel_maxspeed = 3.0f; // maximum thruster speed in game units/second shipmodel_turnspeed = 45.0f; // 45 degrees per second shipmodel_maxcargo = 0; shipmodel_jumpdrive = false; // no jumpdrive capability shipmodel_dock = false; // not dockable } ShipModel::~ShipModel() { } void ShipModel::generate_info() { //clear_text(); if (text().size()) add_text(""); add_text("^BSpecifications:^N"); std::stringstream str; str << "price: ^B" << price() << " ^Ncredits"; add_text(str.str()); str.str(""); str << "cargo hold: ^B" << maxcargo() << " ^Ncubic meters"; add_text(str.str()); str.str(""); str << "top speed: ^B" << 100.0f * maxspeed() << " ^Nmps"; add_text(str.str()); str.str(""); str << "response: ^B" << turnspeed() << " ^Ndps"; add_text(str.str()); str.str(""); str << "acceleration: ^B" << acceleration() << " ^Nstandard"; add_text(str.str()); str.str(""); if (jumpdrive()) { add_text("^Bhyperspace jump drive"); } if (dock()) { add_text("^Bdockable"); } } ShipModel *ShipModel::find(const std::string & label) { if (!label.size()) { return 0; } return (ShipModel *) core::Info::find(shipmodel_infotype, label); } ShipModel *ShipModel::search(const std::string & searchstr) { if (!searchstr.size()) { return 0; } return (ShipModel *) core::Info::search(shipmodel_infotype, searchstr); } void ShipModel::list() { core::Info::list(shipmodel_infotype); } // a player buys a ship void ShipModel::buy(core::EntityControlable *buyer, core::Entity *seller) { if (!buyer || !seller) return; // can only buy at planets and stations if ((seller->moduletype() != station_enttype) && (seller->moduletype() != planet_enttype)) { buyer->owner()->send("^BCan not buy here"); return; } if (!buyer->owner()) return; if (!seller->inventory()) { buyer->owner()->send("^BCan not buy here"); return; } core::Player *player = buyer->owner(); // seller is the station or planet core::Item *seller_item = seller->inventory()->find(this); if (!seller_item) { if (player) { player->send("^B" + seller->name() + " ^Bdoes not sell " + name()); } return; } else { assert(seller_item->info() == this); } // check price if (price() > player->credits()) { player->send("^WCan not afford transaction!"); return; } player->add_credits(-price()); // player has only ship for now if (player->control()) { player->remove_asset(player->control()); } Ship * ship = new Ship(player, this); ship->set_zone(seller->zone()); ship->get_location().assign(seller->location()); ship->set_state(core::Entity::Docked); ship->get_axis().assign(seller->axis()); ship->get_axis().change_direction(180.0f); player->set_control(ship); player->set_view(seller); // send the ship purchased message std::stringstream msgstr; msgstr << "^BPurchased " << aux::article(name()) << " for " << price() << " credits"; player->send(msgstr.str()); player->sound("game/buy-ship"); } }