diff options
-rw-r--r-- | src/client/trademenu.cc | 54 | ||||
-rw-r--r-- | src/client/trademenu.h | 5 | ||||
-rw-r--r-- | src/core/entity.h | 5 | ||||
-rw-r--r-- | src/core/inventory.cc | 14 | ||||
-rw-r--r-- | src/core/inventory.h | 23 | ||||
-rw-r--r-- | src/core/item.cc | 16 | ||||
-rw-r--r-- | src/core/item.h | 37 | ||||
-rw-r--r-- | src/game/base/cargo.cc | 133 | ||||
-rw-r--r-- | src/game/base/cargo.h | 5 | ||||
-rw-r--r-- | src/game/base/game.cc | 298 | ||||
-rw-r--r-- | src/game/base/game.h | 1 | ||||
-rw-r--r-- | src/game/base/ship.cc | 1 | ||||
-rw-r--r-- | src/game/base/shipdealer.cc | 75 | ||||
-rw-r--r-- | src/game/base/shipmodel.cc | 96 | ||||
-rw-r--r-- | src/game/base/shipmodel.h | 2 | ||||
-rw-r--r-- | src/ui/listitem.cc | 18 | ||||
-rw-r--r-- | src/ui/listitem.h | 8 | ||||
-rw-r--r-- | src/ui/listview.cc | 22 | ||||
-rw-r--r-- | src/ui/listview.h | 24 | ||||
-rw-r--r-- | src/ui/widget.h | 6 |
20 files changed, 588 insertions, 255 deletions
diff --git a/src/client/trademenu.cc b/src/client/trademenu.cc index e96f1a6..837ee87 100644 --- a/src/client/trademenu.cc +++ b/src/client/trademenu.cc @@ -59,6 +59,12 @@ TradeMenu::TradeMenu(ui::Widget *parent, const char * label) : ui::Window(parent menu_closebutton = new ui::Button(menu_tradewindow, "Return", "view hide"); + menu_buyallbutton = new ui::Button(menu_modelview, "<<"); + menu_buybutton = new ui::Button(menu_modelview, "<"); + menu_sellallbutton = new ui::Button(menu_modelview, ">"); + menu_sellbutton = new ui::Button(menu_modelview, ">>"); + + std::string test("test"); set_item_type(0); @@ -74,7 +80,6 @@ void TradeMenu::set_item_type(core::InfoType *item_type) { // reset menu_namelabel->set_text(0); - menu_infotext.clear(); core::Inventory *inventory_player = 0; core::Inventory *inventory_view = 0; @@ -93,21 +98,55 @@ void TradeMenu::set_item_type(core::InfoType *item_type) void TradeMenu::set_item(ui::ListItem *item) { + menu_infotext.clear(); menu_namelabel->clear(); if (!item || !item->info()) { + menu_traderlistview->deselect(); + menu_inventorylistview->deselect(); + menu_scrollpane->hide(); menu_modelview->hide(); return; } if (item->parent() == menu_inventorylistview) { + menu_traderlistview->deselect(); // item in ship inventory selected (SELL) menu_namelabel->set_text("Sell " + item->text()); + menu_buyallbutton->hide(); + menu_buybutton->hide(); + + menu_sellallbutton->show(); + menu_sellallbutton->set_command("remote sell " + item->info()->type()->label() + " " + item->info()->label() + " -1"); + + menu_sellbutton->show(); + menu_sellbutton->set_command("remote sell " + item->info()->type()->label() + " " + item->info()->label() + " 1"); + } else if (item->parent() == menu_traderlistview) { + menu_inventorylistview->deselect(); // item in trader inventory selected (BUY) menu_namelabel->set_text("Buy " + item->text()); + + menu_buyallbutton->show(); + menu_buyallbutton->set_command("remote buy " + item->info()->type()->label() + " " + item->info()->label() + " -1"); + + menu_buybutton->show(); + menu_buybutton->set_command("remote buy " + item->info()->type()->label() + " " + item->info()->label() + " 1; "); + + menu_sellallbutton->hide(); + menu_sellbutton->hide(); + + } else { + menu_traderlistview->deselect(); + menu_inventorylistview->deselect(); + + menu_buyallbutton->hide(); + menu_buybutton->hide(); + + menu_sellallbutton->hide(); + menu_sellbutton->hide(); } if (item->info()) { @@ -145,6 +184,19 @@ void TradeMenu::resize() menu_modelview->set_size(menu_tradewindow->width() - 2.0f * ui::UI::elementsize.width() - fontmargin * 4.0f, ui::UI::elementsize.width()); menu_modelview->set_location(fontmargin * 2.0f + ui::UI::elementsize.width(), fontmargin * 3.0f); + // resize buttons + menu_buyallbutton->set_size(fontmargin, fontmargin); + menu_buyallbutton->set_location(0, menu_modelview->height() - fontmargin); + + menu_buybutton->set_size(fontmargin, fontmargin); + menu_buybutton->set_location(2.0f * fontmargin, menu_modelview->height() - fontmargin); + + menu_sellallbutton->set_size(fontmargin, fontmargin); + menu_sellallbutton->set_location(menu_modelview->width() - fontmargin, menu_modelview->height() - fontmargin); + + menu_sellbutton->set_size(fontmargin, fontmargin); + menu_sellbutton->set_location(menu_modelview->width() - 3.0f * fontmargin, menu_modelview->height() - fontmargin); + // resize scrollpane menu_scrollpane->set_size(menu_tradewindow->width() - 2.0f * ui::UI::elementsize.width() - fontmargin * 4.0f, menu_inventorylistview->height() - fontmargin - ui::UI::elementsize.width()); menu_scrollpane->set_location(fontmargin * 2.0f + ui::UI::elementsize.width(), fontmargin * 4.0f + ui::UI::elementsize.width()); diff --git a/src/client/trademenu.h b/src/client/trademenu.h index b95ee57..477a372 100644 --- a/src/client/trademenu.h +++ b/src/client/trademenu.h @@ -46,6 +46,11 @@ private: ui::ModelView *menu_modelview; ui::ScrollPane *menu_scrollpane; + ui::Button *menu_buyallbutton; + ui::Button *menu_buybutton; + ui::Button *menu_sellallbutton; + ui::Button *menu_sellbutton; + InventoryListView *menu_inventorylistview; InventoryListView *menu_traderlistview; diff --git a/src/core/entity.h b/src/core/entity.h index 8bf637d..f00e192 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -234,6 +234,11 @@ public: */ virtual void set_zone(Zone *zone); + /// current speed of the entity in game units per second + inline void set_speed(const float speed) { + entity_speed = speed; + } + /// set visibility inline void set_visible(const bool visible = true) { entity_visible = visible; diff --git a/src/core/inventory.cc b/src/core/inventory.cc index e1a74dc..6afa76f 100644 --- a/src/core/inventory.cc +++ b/src/core/inventory.cc @@ -4,6 +4,7 @@ the terms of the GNU General Public License version 2 */ +#include "core/application.h" #include "core/inventory.h" #include "sys/sys.h" @@ -14,12 +15,23 @@ namespace core Inventory::Inventory() { - + inventory_timestamp = 0; } Inventory::~Inventory() { clear(); + inventory_timestamp = 0; +} + +void Inventory::set_timestamp(const unsigned long timestamp) +{ + inventory_timestamp = timestamp; +} + +void Inventory::mark() +{ + inventory_timestamp = core::game()->timestamp(); } void Inventory::add(Item *item) diff --git a/src/core/inventory.h b/src/core/inventory.h index c924683..c715116 100644 --- a/src/core/inventory.h +++ b/src/core/inventory.h @@ -55,12 +55,31 @@ public: */ Item *find(const Info *info); - inline Items &items() { + inline Items &items() { return inventory_items; }; + + /** + * @brief return the timestamp + */ + inline const unsigned long timestamp() const { + return inventory_timestamp; + } + + /** + * @brief set the timestamp + */ + void set_timestamp(const unsigned long timestamp); + + /** + * @brief set the timestamp to the current game time + */ + void mark(); private: - Items inventory_items; + Items inventory_items; + // timestamp when inventory was last updated + unsigned long inventory_timestamp; }; } // namsepace core diff --git a/src/core/item.cc b/src/core/item.cc index a6cc89f..3528c1a 100644 --- a/src/core/item.cc +++ b/src/core/item.cc @@ -16,6 +16,7 @@ Item::Item(const Info *info) { item_info = info; item_amount = 0; + item_price = 0; } Item::~Item() @@ -29,5 +30,20 @@ void Item::set_amount(const int amount) item_amount = amount; } +void Item::inc_amount(const int amount) +{ + item_amount += amount; +} + +void Item::dec_amount(const int amount) +{ + item_amount -= amount; +} + +void Item::set_price(const long price) +{ + item_price = price; +} + } // namespace core diff --git a/src/core/item.h b/src/core/item.h index f1d6bb5..cc81249 100644 --- a/src/core/item.h +++ b/src/core/item.h @@ -19,8 +19,6 @@ namespace core class Item { public: - enum Flags { Mount = 1, Trade = 2 }; - Item(const Info *info); ~Item(); @@ -35,12 +33,12 @@ public: /** * @brief information card */ - inline const Info *info() const { return item_info; } + inline const Info *info() const { return item_info; } - /** - * @brief flags - */ - inline int flags() const { return item_flags; } + + inline const long price() const { + return item_price; + } /* ---- mutators ----------------------------------------------- */ @@ -49,25 +47,16 @@ public: */ void set_amount(const int amount); - /** - * @brief set specified flags - */ - inline void set_flag(Flags flag) { - item_flags |= flag; - } - - /** - * @brief unset specified flags - */ - inline void unset_flag(Flags flag) { - item_flags &= ~flag; - } + void inc_amount(const int amount); + + void dec_amount(const int amount); + + void set_price(const long price); private: - const Info *item_info; - int item_amount; - - int item_flags; + const Info *item_info; + long item_price; + int item_amount; }; } // namespace core diff --git a/src/game/base/cargo.cc b/src/game/base/cargo.cc index 258aecf..420d4d3 100644 --- a/src/game/base/cargo.cc +++ b/src/game/base/cargo.cc @@ -6,16 +6,86 @@ #include "base/game.h" #include "base/cargo.h" +#include "filesystem/inifile.h" #include "auxiliary/functions.h" #include "sys/sys.h" namespace game { -/* ---- class Cargo -------------------------------------------- */ - 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) { } @@ -33,6 +103,65 @@ Cargo *Cargo::find(const std::string & label) return (Cargo *) core::Info::find(cargo_infotype, label); } +// main 'buy cargo' function +void Cargo::buy(core::EntityControlable *buyer, core::Entity *seller, const int amount) +{ + if (!buyer || !seller) + return; + + if (!buyer->owner()) + return; + + if (!buyer->inventory() || !seller->inventory()) { + 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); + + // 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 diff --git a/src/game/base/cargo.h b/src/game/base/cargo.h index 808b4c0..9b2bca5 100644 --- a/src/game/base/cargo.h +++ b/src/game/base/cargo.h @@ -17,9 +17,14 @@ public: Cargo(); ~Cargo(); + void buy(core::EntityControlable *buyer, core::Entity *seller, const int amount); + + /* -- static functions -- */ static core::InfoType *cargo_infotype; static Cargo *find(const std::string & label); + + static bool init(); }; } // namespace game diff --git a/src/game/base/game.cc b/src/game/base/game.cc index bf139a3..9f8dabc 100644 --- a/src/game/base/game.cc +++ b/src/game/base/game.cc @@ -183,12 +183,97 @@ void Game::func_dock(core::Player *player, core::Entity *entity) } } +// cheats +void Game::func_give(core::Player *player, const std::string &args) +{ + if (!Game::g_devel->value()) { + player->send("Cheats disabled"); + return; + } + + std::istringstream is(args); + std::string str; + + is >> str; + aux::to_label(str); + + if (str.compare("ship") == 0) { + std::string labelstr; + + if (!player->control()) { + player->send("^WNeed a ship to swap!"); + } + + if (!(is >> labelstr)) { + player->send("Usage: give ship [string]"); + return; + } + + ShipModel *shipmodel = ShipModel::find(labelstr); + if (!shipmodel) { + // enable rcon buffering + sys::ConsoleInterface::instance()->set_rcon(true); + ShipModel::list(); + // disable rcon buffering + sys::ConsoleInterface::instance()->set_rcon(false); + + while (sys::ConsoleInterface::instance()->rconbuf().size()) { + player->send((*sys::ConsoleInterface::instance()->rconbuf().begin())); + sys::ConsoleInterface::instance()->rconbuf().pop_front(); + } + + player->send("Unkown ship type '" + labelstr + "'"); + return; + } + + Ship * ship = new Ship(player, shipmodel); + + // FIME move this into a method in the Ship class + ship->set_zone(player->control()->zone()); + ship->get_location().assign(player->control()->location()); + ship->set_state(player->control()->state()); + ship->get_axis().assign(player->control()->axis()); + ship->set_speed(player->control()->speed()); + ship->set_thrust(player->control()->thrust()); + + if (player->view() == player->control()) { + player->set_view(ship); + } + player->remove_asset(player->control()); + player->set_control(ship); + + player->sound("game/buy-ship"); + + } else if (str.compare("credits") == 0) { + long credits; + + if (!(is >> credits)) { + player->send("Usage: give credits [int]"); + return; + } + + if (player->credits() + credits > 0 ) { + player->set_credits(player->credits() + credits); + } else { + player->set_credits(0); + } + + player->sound("game/buy"); + + } else { + player->send("Usage: give ship [string]"); + player->send(" give credits [int]"); + return; + } +} + // buy request from a player void Game::func_buy(core::Player *player, const std::string &args) { std::istringstream is(args); std::string typestr; std::string labelstr; + int amount = 0; if (!(is >> typestr)) { player->send("Usage: buy [string] [string] buy an item, specify type and label"); @@ -202,11 +287,21 @@ void Game::func_buy(core::Player *player, const std::string &args) } else { aux::to_label(labelstr); } + + if (!(is >> amount)) + amount = 0; if (typestr.compare("ship") == 0) { ShipDealer::func_buy(player, labelstr); + + } else if (typestr.compare("cargo") == 0) { - player->send("Buying cargo is not supported"); + Cargo *cargo = Cargo::find(labelstr); + if (cargo) { + cargo->buy(player->control(), player->view(), amount); + } else { + player->send("Unkown cargo type '" + labelstr + "'"); + } } else { player->send("Unkown item type '" + typestr + "'"); } @@ -360,16 +455,19 @@ void Game::func_goto(core::Player *player, const std::string &args) Game::Game() : core::Module("Project::OSiRiON", true) { + // reset default player values Default::clear(); Physics::init(); - if (!load_commodities()) { + // read cargo.ini + if (!Cargo::init()) { abort(); return; } - if (!load_ships()) { + // read ships.ini + if (!ShipModel::init()) { abort(); return; } @@ -399,6 +497,9 @@ Game::Game() : core::Module("Project::OSiRiON", true) func = core::Func::add("buy", Game::func_buy); func->set_info("[string] [string] buy type of item, name of item"); + func = core::Func::add("give", Game::func_give); + func->set_info("cheat functions"); + func = core::Func::add("jump", Game::func_jump); func->set_info("[string] activate or deactivate hyperspace jump drive"); @@ -746,13 +847,12 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) if ((entity->moduletype() != planet_enttype) && (entity->moduletype() != station_enttype)) { return false; } - - - filesystem::IniFile inifile; std::string strval; + long l; + MenuDescription *menu_dealer = 0; ButtonDescription *button = 0; ShipDealer *shipdealer = 0; @@ -774,8 +874,8 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) // dealer menu if (!menu_dealer) { menu_dealer = new MenuDescription(); - menu_dealer->set_label("dealer"); - menu_dealer->set_text("Ship dealer"); + menu_dealer->set_label("ships"); + menu_dealer->set_text("Ships"); shipdealer = new ShipDealer(); if (entity->moduletype() == planet_enttype) { @@ -831,6 +931,7 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) if (!item) { item = new core::Item(cargo); item->set_amount(-1); + item->set_price(cargo->price()); inventory->add(item); } } else { @@ -840,6 +941,10 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) inifile.unknown_error(msg); } + } else if (inifile.got_key_long("price", l)) { + if (item) { + item->set_price(l); + } } else { inifile.unkown_key(); } @@ -855,6 +960,7 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) item = inventory->find(shipmodel); if (!item) { item = new core::Item(shipmodel); + item->set_price(shipmodel->price()); item->set_amount(-1); inventory->add(item); } @@ -864,7 +970,10 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) msg.append("'"); inifile.unknown_error(msg); } - + } else if (inifile.got_key_long("price", l)) { + if (item) { + item->set_price(l); + } } else { inifile.unkown_key(); } @@ -887,6 +996,12 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) button->set_command("launch", ButtonDescription::CommandGame); button->set_alignment(ButtonDescription::Center); menu_main->add_button(button); + + button = new ButtonDescription(); + button->set_text("Trade"); + button->set_command("trade cargo", ButtonDescription::CommandMenu); + button->set_alignment(ButtonDescription::Center); + menu_main->add_button(button); if (menu_dealer) { button = new ButtonDescription(); @@ -898,8 +1013,8 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) entity->add_menu(menu_dealer); button = new ButtonDescription(); - button->set_text("Ship dealer"); - button->set_command("dealer", ButtonDescription::CommandMenu); + button->set_text("Ships"); + button->set_command("ships", ButtonDescription::CommandMenu); button->set_alignment(ButtonDescription::Center); menu_main->add_button(button); } @@ -913,167 +1028,6 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) return true; } -// read commodities -bool Game::load_commodities() -{ - // 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; - - 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 { - 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; -} - -// read ship model specifications -bool Game::load_ships() -{ - // 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; -} - // load default player settings bool Game::load_player() { diff --git a/src/game/base/game.h b/src/game/base/game.h index fc0274b..e091630 100644 --- a/src/game/base/game.h +++ b/src/game/base/game.h @@ -107,6 +107,7 @@ private: static void func_respawn(core::Player *player, std::string const &args); static void func_goto(core::Player *player, const std::string &args); static void func_buy(core::Player *player, std::string const &args); + static void func_give(core::Player *player, const std::string &args); }; /// factory function diff --git a/src/game/base/ship.cc b/src/game/base/ship.cc index 0da57ab..23929ea 100644 --- a/src/game/base/ship.cc +++ b/src/game/base/ship.cc @@ -45,6 +45,7 @@ Ship::Ship(core::Player *owner, ShipModel *shipmodel) : core::EntityControlable( std::string str(aux::text_strip(owner->name())); aux::to_label(str); set_label(str); + set_inventory(new core::Inventory()); } else { set_label(shipmodel->label()); } diff --git a/src/game/base/shipdealer.cc b/src/game/base/shipdealer.cc index adb97ea..e6df18f 100644 --- a/src/game/base/shipdealer.cc +++ b/src/game/base/shipdealer.cc @@ -68,33 +68,19 @@ ShipModel *ShipDealer::find(ShipModel *shipmodel) const void ShipDealer::func_buy(core::Player *player, const std::string &args) { core::Entity *dock = player->view(); - ShipDealer *shipdealer = 0; - - // find the ship model - ShipModel *shipmodel = ShipModel::find(args); - if (!shipmodel) { - if (!Game::g_devel->value()) { - player->send("Cheats disabled"); - return; - } else { - shipmodel = ShipModel::search(args); - } + + std::istringstream is(args); + std::string labelstr; + + if (!(is >> labelstr)) { + player->send("Usage: buy ship [string]"); } - if (!shipmodel) { - // enable rcon buffering - sys::ConsoleInterface::instance()->set_rcon(true); - ShipModel::list(); - // disable rcon buffering - sys::ConsoleInterface::instance()->set_rcon(false); - - while (sys::ConsoleInterface::instance()->rconbuf().size()) { - player->send((*sys::ConsoleInterface::instance()->rconbuf().begin())); - sys::ConsoleInterface::instance()->rconbuf().pop_front(); - } - - player->send("Usage: buy ship label"); + // find the ship model + ShipModel *shipmodel = ShipModel::find(labelstr); + if (!shipmodel) { + player->send("Unkown ship type '" + labelstr + "'"); return; } @@ -107,29 +93,26 @@ void ShipDealer::func_buy(core::Player *player, const std::string &args) } } - if (!Game::g_devel->value()) { - - if (!shipdealer) { - player->send("No ship dealer available"); - return; - } - - if (!shipdealer->find(shipmodel)) { - player->send("Ship dealer does not sell the " + shipmodel->name()); - return; - } + if (!shipdealer) { + player->send("No ship dealer available"); + return; + } - // check price - if (shipmodel->price() > player->credits()) { - std::stringstream msgstr; - msgstr << "You require " << (shipmodel->price() - player->credits()) << " additional credits to buy the " << shipmodel->name(); - player->send(msgstr.str()); - return; - } + if (!shipdealer->find(shipmodel)) { + player->send("Ship dealer does not sell the " + shipmodel->name()); + return; + } - player->add_credits(-shipmodel->price()); + // check price + if (shipmodel->price() > player->credits()) { + std::stringstream msgstr; + msgstr << "You require " << (shipmodel->price() - player->credits()) << " additional credits to buy the " << shipmodel->name(); + player->send(msgstr.str()); + return; } + player->add_credits(-shipmodel->price()); + // player has only ship for now if (player->control()) { player->remove_asset(player->control()); @@ -151,10 +134,8 @@ void ShipDealer::func_buy(core::Player *player, const std::string &args) // send the ship purchased message std::stringstream msgstr; - msgstr << "^BPurchased " << aux::article(shipmodel->name()); - if (!Game::g_devel->value()) { - msgstr << " for " << shipmodel->price() << " credits"; - } + msgstr << "^BPurchased " << aux::article(shipmodel->name()) << " for " << shipmodel->price() << " credits"; + player->send(msgstr.str()); player->sound("game/buy-ship"); } diff --git a/src/game/base/shipmodel.cc b/src/game/base/shipmodel.cc index 1dc8ba1..8710aad 100644 --- a/src/game/base/shipmodel.cc +++ b/src/game/base/shipmodel.cc @@ -16,6 +16,102 @@ 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 diff --git a/src/game/base/shipmodel.h b/src/game/base/shipmodel.h index 38e9d5d..c5da05e 100644 --- a/src/game/base/shipmodel.h +++ b/src/game/base/shipmodel.h @@ -96,6 +96,8 @@ public: static ShipModel *search(const std::string & searchstr); + static bool init(); + static void list(); static core::InfoType *shipmodel_infotype; diff --git a/src/ui/listitem.cc b/src/ui/listitem.cc index 3ff108f..dcd4e2a 100644 --- a/src/ui/listitem.cc +++ b/src/ui/listitem.cc @@ -22,8 +22,6 @@ ListItem::~ListItem() { void ListItem::draw_border() { - // FIXME glow if selected, not on_mouseover - if (has_mouse_focus()) { math::Color color(palette()->foreground()); float t = core::application()->time(); @@ -33,7 +31,23 @@ void ListItem::draw_border() color.a = 0.5f + t; paint::color(color); paint::border(global_location(), size()); + } else if ((static_cast<ListView *>(parent()))->selected() == this) { + paint::color(palette()->border()); + paint::border(global_location(), size()); + } +} + +void ListItem::draw() +{ + if (!text().size()) + return; + + if ( has_mouse_focus() || ((static_cast<ListView *>(parent()))->selected() == this)) { + paint::color(palette()->highlight()); + } else { + paint::color(palette()->foreground()); } + paint::label(global_location(), size(), font(), text(), alignment()); } bool ListItem::on_keypress(const int key, const unsigned int modifier) diff --git a/src/ui/listitem.h b/src/ui/listitem.h index a107ed5..cc03621 100644 --- a/src/ui/listitem.h +++ b/src/ui/listitem.h @@ -11,6 +11,12 @@ #include "core/info.h" #include "ui/label.h" + +namespace ui +{ +class ListItem; +} + #include "ui/listview.h" namespace ui @@ -34,6 +40,8 @@ protected: /// draw the button border virtual void draw_border(); + + virtual void draw(); private: const core::Info *listitem_info; diff --git a/src/ui/listview.cc b/src/ui/listview.cc index da320c5..646b168 100644 --- a/src/ui/listview.cc +++ b/src/ui/listview.cc @@ -15,6 +15,7 @@ ListView::ListView(Widget *parent) : Widget(parent) set_border(true); listview_scroll = 0.0f; + listview_selecteditem = 0; } ListView::~ListView() @@ -66,5 +67,26 @@ void ListView::resize() content_top += (*it)->height(); } } + +void ListView::deselect() +{ + listview_selecteditem = 0; +} + +void ListView::clear() +{ + listview_selecteditem = 0; + remove_children(); +} + +bool ListView::on_emit(Widget *sender, const Event event, void *data) +{ + if ((sender->parent() == this) && (event == Widget::EventListItemClicked)) { + listview_selecteditem = static_cast<ListItem *>(sender); + return false; // return false because parent widgets might want to handle this event + } + return ui::Widget::on_emit(sender, event, data); +} + } diff --git a/src/ui/listview.h b/src/ui/listview.h index 25fd07c..a650348 100644 --- a/src/ui/listview.h +++ b/src/ui/listview.h @@ -12,6 +12,13 @@ namespace ui { +class ListView; +} + +#include "ui/listitem.h" + +namespace ui +{ /** * @brief a list of selectable items @@ -27,6 +34,11 @@ public: return listview_scroll; } + /// return last selected listitem + inline ListItem *selected() const { + return listview_selecteditem; + } + /* -- mutators --------------------------------------------- */ /// set scroll @@ -38,11 +50,21 @@ public: /// scroll up void dec_scroll(float scroll); + /// clear all listitems + void clear(); + + /// set selection to nothing + void deselect(); + protected: virtual void resize(); + /// emit event handler + virtual bool on_emit(Widget *sender, const Event event, void *data); + private: - float listview_scroll; + float listview_scroll; + ListItem *listview_selecteditem; }; } // namespacd ui diff --git a/src/ui/widget.h b/src/ui/widget.h index 856fca0..880b71c 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -241,9 +241,6 @@ public: event_emit(this, event, data); } - /// remove all child widgets - virtual void remove_children(); - protected: /// type definition for child widgets typedef std::list<Widget *> Children; @@ -343,6 +340,9 @@ protected: /// remove a child widget virtual void remove_child(Widget *child); + + /// remove all child widgets + virtual void remove_children(); private: void draw_debug_border(); |