Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/trademenu.cc54
-rw-r--r--src/client/trademenu.h5
-rw-r--r--src/core/entity.h5
-rw-r--r--src/core/inventory.cc14
-rw-r--r--src/core/inventory.h23
-rw-r--r--src/core/item.cc16
-rw-r--r--src/core/item.h37
-rw-r--r--src/game/base/cargo.cc133
-rw-r--r--src/game/base/cargo.h5
-rw-r--r--src/game/base/game.cc298
-rw-r--r--src/game/base/game.h1
-rw-r--r--src/game/base/ship.cc1
-rw-r--r--src/game/base/shipdealer.cc75
-rw-r--r--src/game/base/shipmodel.cc96
-rw-r--r--src/game/base/shipmodel.h2
-rw-r--r--src/ui/listitem.cc18
-rw-r--r--src/ui/listitem.h8
-rw-r--r--src/ui/listview.cc22
-rw-r--r--src/ui/listview.h24
-rw-r--r--src/ui/widget.h6
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();