/* base/cargo.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/cargo.h" #include "filesystem/inifile.h" #include "auxiliary/functions.h" #include "sys/sys.h" namespace game { core::InfoType *Cargo::cargo_infotype = 0; // loads cargo types from ini file bool Cargo::init() { // initialize commodities InfoType Cargo::cargo_infotype = new core::InfoType("cargo"); filesystem::IniFile cargoini; cargoini.open("cargo"); if (!cargoini.is_open()) { con_error << "Could not open " << cargoini.name() << "!" << std::endl; return false; } con_print << "^BLoading cargo..." << std::endl; size_t count = 0; Cargo *cargo = 0; std::string str; long l; while (cargoini.getline()) { if (cargoini.got_key()) { if (cargoini.section().compare("cargo") == 0) { if (cargoini.got_key_label("label", str)) { cargo->set_label(std::string(str)); count++; continue; } else if (cargoini.got_key_string("name", str)) { cargo->set_name(str); continue; } else if (cargoini.got_key_string("info", str)) { cargo->add_text(str); continue; } else if (cargoini.got_key_string("model", str)) { cargo->set_modelname(str); continue; } else if (cargoini.got_key_long("price", l)) { cargo->set_price(l); continue; } else { cargoini.unkown_key(); } } } else if (cargoini.got_section()) { if (cargoini.got_section("cargo")) { cargo = new Cargo(); } else if (cargoini.got_section()) { cargoini.unknown_section(); } } } // add cargo infos con_debug << " " << cargoini.name() << " " << count << " cargo types" << std::endl; cargoini.close(); return true; } /* ---- class Cargo -------------------------------------------- */ Cargo::Cargo() : core::Info(cargo_infotype) { } Cargo::~Cargo() { } Cargo *Cargo::find(const std::string & label) { if (!label.size()) { return 0; } return (Cargo *) core::Info::find(cargo_infotype, label); } // main 'sell cargo' function void Cargo::sell(core::EntityControlable *seller, core::Entity *buyer, const int amount) { if (!buyer || !seller) return; // can only sell at planets and stations if ((buyer->moduletype() != station_enttype) && (buyer->moduletype() != planet_enttype)) { seller->owner()->send("^BCan not sell here"); return; } if (!seller->owner()) return; if (!buyer->inventory() || !seller->inventory()) { seller->owner()->send("^BCan not sell here"); return; } if (!amount) { return; } core::Item *seller_item = seller->inventory()->find(this); if (!seller_item) { if (seller->owner()) { seller->owner()->send("^BYou do not own any " + name()); } return; } int negotiated_amount = amount; if (negotiated_amount < 0) { negotiated_amount = seller_item->amount(); } else if (negotiated_amount > seller_item->amount()) { negotiated_amount = seller_item->amount(); } int negotiated_price = price(); // base price core::Item *buyer_item = buyer->inventory()->find(this); if (buyer_item) { negotiated_price = buyer_item->price(); } seller_item->set_amount(seller_item->amount() - negotiated_amount); seller->owner()->set_credits(seller->owner()->credits() + negotiated_price * negotiated_amount); seller->inventory()->set_dirty(); // send a cargo purchased message std::stringstream msgstr; msgstr << "^BSold " << negotiated_amount << " " << aux::plural("unit", negotiated_amount) << " of " << name() << " for " << negotiated_price * negotiated_amount << " credits"; seller->owner()->send(msgstr.str()); seller->owner()->sound("game/buy"); } // main 'buy cargo' function void Cargo::buy(core::EntityControlable *buyer, core::Entity *seller, const int amount) { 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 (!buyer->inventory() || !seller->inventory()) { buyer->owner()->send("^BCan not buy here"); return; } if (!amount) { return; } core::Item *buyer_item = buyer->inventory()->find(this); core::Item *seller_item = seller->inventory()->find(this); if (!seller_item) { if (buyer->owner()) { buyer->owner()->send("^B" + seller->name() + " ^Bdoes not sell " + name()); } return; } int negotiated_amount = amount; int negotiated_price = seller_item->price(); long cash = buyer->owner()->credits(); // negative means 'as much as possible' if (negotiated_amount < 0) { negotiated_amount = cash / negotiated_price; } if (cash < negotiated_amount * negotiated_price) { negotiated_amount = cash / negotiated_price; } if (!negotiated_amount) { buyer->owner()->send("^WCan not afford transaction!"); return; } // TODO cargo size check if (!buyer_item) { buyer_item = new core::Item(this); buyer->inventory()->add(buyer_item); } buyer_item->inc_amount(negotiated_amount); buyer->owner()->set_credits(buyer->owner()->credits() - negotiated_price * negotiated_amount); buyer->inventory()->set_dirty(); // send a cargo purchased message std::stringstream msgstr; msgstr << "^BPurchased " << negotiated_amount << " " << aux::plural("unit", negotiated_amount) << " of " << name() << " for " << negotiated_price * negotiated_amount << " credits"; buyer->owner()->send(msgstr.str()); buyer->owner()->sound("game/buy"); } } // namespace game