From c62fe609a69058e2e30f757e9a06f72a98464232 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Fri, 17 Sep 2010 15:19:34 +0000 Subject: Bump network protocol version to 19, menudescriptions use the info infrastructure, client-side lazy info update requests. Updated ROADMAP --- doc/ROADMAP | 130 +++++++++++++++++++++++++++++++-------------- src/client/buymenu.cc | 52 ++++++++++-------- src/client/buymenu.h | 2 +- src/client/map.cc | 10 ++-- src/client/playerview.cc | 16 +++--- src/client/trademenu.cc | 122 +++++++++++++++++++++++++++++++++--------- src/client/trademenu.h | 18 ++++--- src/core/descriptions.cc | 36 +++++++------ src/core/descriptions.h | 26 ++++----- src/core/entity.cc | 12 +++-- src/core/gameconnection.cc | 15 +++--- src/core/gameconnection.h | 4 +- src/core/gameinterface.h | 4 +- src/core/info.cc | 34 +++++------- src/core/info.h | 15 +++--- src/core/inventory.h | 4 ++ src/core/label.cc | 11 ++++ src/core/label.h | 3 ++ src/core/net.h | 2 +- src/core/netconnection.cc | 12 ++--- src/core/netconnection.h | 6 ++- src/core/netserver.cc | 53 +++--------------- src/game/base/game.cc | 6 ++- src/ui/Makefile.am | 4 +- src/ui/button.cc | 3 ++ src/ui/listview.cc | 2 + src/ui/modelview.cc | 4 +- src/ui/widget.cc | 2 +- src/ui/widget.h | 16 +++--- 29 files changed, 369 insertions(+), 255 deletions(-) diff --git a/doc/ROADMAP b/doc/ROADMAP index 88b25e4..8e907f9 100644 --- a/doc/ROADMAP +++ b/doc/ROADMAP @@ -1,15 +1,30 @@ ------------------------------------------------------------------ - The Osirion Project - ROADMAP (outdated) + The Osirion Project - ROADMAP ------------------------------------------------------------------ - NOTE: the ROADMAP needs updating + General: + + This document describes the gameplay objectives for each + milestone of the project. Currently, milestone 0.1 has been + reached and the game universe is ready to be refined and + expanded. + + Features of the engine itself, like support for new file + formats, rendering options and game server commands + are implemented along the way and, unless required, + happen independent of the gamplay roadmap. + + This roadmap is not to be used as a roadplanner but as a + guide to reach a playable game. + + ------------------------------------------------------------------ -* version 0.1.0 - The Universe + version 0.1.0 - The Universe (done) -Description: + Description: The game world is divided into zones, the zones can be populated with entities. Players can use their impulse drive or jump to @@ -26,7 +41,8 @@ Description: Players can dock at a space station or planets. Docking a jumpgate enables hyperspace travel. -Requires: + Requires: + client console entities ship instances @@ -37,68 +53,100 @@ Requires: zones basic travelling: impulse drive, jump engine basic docking - basic docking gui ------------------------------------------------------------------ -* version 0.2.0 - Interaction + version 0.2.0 - Items -Description: - Players can shoot at each other. They can crash into a star - or a planet. Player ships explode on destruction. + Description: -Requires: - targetting - explosions, weapons fire and related sounds - cannons and turrets - turret and cannon models - particle systems - clip brushes and collision detection + Ships and stations have inventories, players can buy and sell + cargo at a space station. Each item can have a text description + and a model. + + Requires: + + player credits + item info + lazy server-client exchange + + trading + + Related: + + map entity descriptions + equipment trading + player-to-player trading + eject cargo/tractor beam + model weapon slots and positioning + + Optional: + fuel system + economy + tool to generate item icons from models + dockable player ships with trade ------------------------------------------------------------------ -* version 0.3.0 - Commodities + version 0.3.0 - Equipment -Description: - Players can buy and sell cargo at dockable entities. + Description: + + Players can buy and sell ship upgrades like armor and scanners, + this will require additional game mechanics. + Players can buy and sell weapons. + + Requires: -Requires: - player credits - enhanced docking - enhanced docking gui - commodities market - fuel system? - economy? + cannons and turrets + cannon and turret models ------------------------------------------------------------------ -* version 0.4.0 - Equipment + version 0.4.0 - Physics -Description: - Players can buy and sell ship upgrades like armor and scanners. + Requires: -Requires: - ship market - equipment market + collision physics + targetting + explosions, weapons fire and related sounds + particle systems ------------------------------------------------------------------ -* version 0.5.0 - public alpha + version 0.5.0 - public alpha + + version 0.5.1 - bugfix release + + Description: -Goals: All the general large features of the engine are implemented. - Create a somewhat polished release with a limited universe - to create a platform for bug-fixes. + Create a somewhat polished release with a playable universe + to create a platform for bug-fixes and improvements. -Requires: - general polishing + The main goal if the alpha is to create interest for the project + and to attract an initial playerbase. At this point, a dedicated + 'Official' server is necessary. + + Requires: + playable, consistent universe + general polishing + master server + player guid + player saving ------------------------------------------------------------------ -* version 0.8.0 - public beta + version 0.6.0 - public beta + + version 0.6.1 - bugfix release + + Description: + + Requires: + improved network play ------------------------------------------------------------------ @@ -107,3 +155,5 @@ Requires: Requires: stable network protocol background story + zip archive support + http downloads diff --git a/src/client/buymenu.cc b/src/client/buymenu.cc index c3878a8..a106659 100644 --- a/src/client/buymenu.cc +++ b/src/client/buymenu.cc @@ -9,7 +9,7 @@ #include "ui/paint.h" #include "client/buymenu.h" #include "core/info.h" -#include "core/application.h" + namespace client { @@ -30,7 +30,7 @@ BuyMenu::BuyMenu(ui::Widget *parent, const char * label) : ui::Window(parent) menu_buywindow->set_border(true); menu_namelabel = new ui::Label(menu_buywindow); - menu_namelabel->set_label("infolabel"); + menu_namelabel->set_label("label"); menu_namelabel->set_background(false); menu_namelabel->set_border(false); menu_namelabel->set_font(ui::root()->font_large()); @@ -60,35 +60,41 @@ BuyMenu::~BuyMenu() } -void BuyMenu::set_item(std::string const & itemtype, std::string const & itemname) +void BuyMenu::set_item(core::Info *info) { - menu_itemtype.assign(itemtype); - aux::to_label(menu_itemtype); - - menu_itemname.assign(itemname); - aux::to_label(menu_itemname); - - menu_buybutton->set_command("remote buy " + menu_itemtype + ' ' + menu_itemname + "; view hide"); - menu_buybutton->set_label("buy " + menu_itemname); - menu_infotext.clear(); menu_namelabel->set_text(0); menu_modelview->set_modelname(0); - menu_inforecord = core::game()->info(menu_itemtype, menu_itemname); + // if the information timestamp is 0, the info is available + menu_inforecord = info; - if (menu_inforecord) { - menu_namelabel->set_text(menu_inforecord->name()); - menu_modelview->set_modelname(menu_inforecord->modelname()); - + if (!menu_inforecord) { + menu_buybutton->hide(); + menu_modelview->hide(); + + menu_infotext.push_back("Information is not available"); + menu_infotimestamp = 0; + } else { for (core::Info::Text::const_iterator it = menu_inforecord->text().begin(); it != menu_inforecord->text().end(); it++) { menu_infotext.push_back((*it)); } + + menu_infotimestamp = menu_inforecord->timestamp(); + if (menu_inforecord->type() && !menu_inforecord->timestamp()) { + menu_namelabel->set_text(menu_inforecord->name()); + menu_modelview->set_modelname(menu_inforecord->modelname()); + + menu_buybutton->set_command("remote buy " + menu_inforecord->type()->label() + ' ' + menu_inforecord->label() + "; view hide"); + menu_buybutton->set_label("buy " + menu_inforecord->name()); + + menu_buybutton->show(); + menu_modelview->show(); + } else { + menu_buybutton->hide(); + menu_modelview->hide(); + } menu_infotimestamp = menu_inforecord->timestamp(); - } else { - menu_infotext.push_back("Information is not available"); - menu_infotimestamp = 0; - menu_inforecord = 0; } } @@ -129,8 +135,8 @@ void BuyMenu::resize() void BuyMenu::draw() { // update content if necessary - if (menu_infotimestamp && menu_inforecord && (menu_infotimestamp != menu_inforecord->timestamp())) - set_item(menu_itemtype, menu_itemname); + if (menu_inforecord && (menu_infotimestamp != menu_inforecord->timestamp())) + set_item(menu_inforecord); } bool BuyMenu::on_keypress(const int key, const unsigned int modifier) diff --git a/src/client/buymenu.h b/src/client/buymenu.h index 016f473..85801ce 100644 --- a/src/client/buymenu.h +++ b/src/client/buymenu.h @@ -26,7 +26,7 @@ public: BuyMenu(ui::Widget *parent, const char * label = 0); ~BuyMenu(); - void set_item(std::string const & itemtype, std::string const & itemname); + void set_item(core::Info *info); protected: /// resize event diff --git a/src/client/map.cc b/src/client/map.cc index 34dcb40..46f96fd 100644 --- a/src/client/map.cc +++ b/src/client/map.cc @@ -244,11 +244,11 @@ void Map::draw() gl::end(); gl::disable(GL_TEXTURE_2D); - if (map_target != current_target) { + if (map_target != current_target ) { // this makes sure the map target exists set_target(current_target); - } else if (map_infotimestamp && map_inforecord && (map_infotimestamp != map_inforecord->timestamp())) { + } else if (map_inforecord && (map_infotimestamp != map_inforecord->timestamp())) { set_target(map_target); } } @@ -265,7 +265,10 @@ void Map::set_target(const core::Entity *entity) { map_targetlabel->set_text(map_target->name()); map_targetlabel->show(); - map_inforecord = map_target->info(); + if (map_target->info()) + map_inforecord = core::game()->info(map_target->info()->id()); + else + map_inforecord = 0; if (map_inforecord) { for (core::Info::Text::const_iterator it = map_inforecord->text().begin(); it != map_inforecord->text().end(); it++) { @@ -274,6 +277,7 @@ void Map::set_target(const core::Entity *entity) { map_infotimestamp = map_inforecord->timestamp(); } else { map_infotext.push_back("Information is not available"); + map_infotimestamp = 0; } map_scrollpane->show(); diff --git a/src/client/playerview.cc b/src/client/playerview.cc index de4c704..4be64d2 100644 --- a/src/client/playerview.cc +++ b/src/client/playerview.cc @@ -7,6 +7,8 @@ #include #include +#include "core/info.h" +#include "core/application.h" #include "audio/audio.h" #include "client/playerview.h" #include "ui/ui.h" @@ -119,19 +121,19 @@ void PlayerView::show_menu(const std::string & args) if (label.compare("buy") == 0) { // buy menu, single item - std::string itemtype; - std::string itemname; + unsigned long id; - if ((argstr >> itemtype) && (argstr >> itemname)) { + if (argstr >> id) { // hide other menus view_entitymenu->hide(); view_trademenu->hide(); + + // requesting the info through game makes sure it is retreived from the server + view_buymenu->set_item( core::game()->info(id) ); // show buy menu - view_buymenu->set_item(itemtype, itemname); - view_buymenu->show(); - + view_buymenu->show(); } else { - con_print << "usage: view buy [string] [string] buy menu for item type and name" << std::endl; + con_print << "usage: view buy [infoid] show the buy menu for this kind of item" << std::endl; } } else if (label.compare("trade") == 0) { diff --git a/src/client/trademenu.cc b/src/client/trademenu.cc index 75b9d67..7e9be4f 100644 --- a/src/client/trademenu.cc +++ b/src/client/trademenu.cc @@ -7,6 +7,7 @@ #include "ui/button.h" #include "ui/paint.h" #include "ui/ui.h" +#include "ui/listitem.h" #include "client/trademenu.h" namespace client @@ -25,18 +26,30 @@ TradeMenu::TradeMenu(ui::Widget *parent, const char * label) : ui::Window(parent menu_tradewindow->set_label("tradewindow"); menu_tradewindow->set_border(true); - menu_listview = new ui::ListView(menu_tradewindow); - menu_listview->set_label("listview"); - menu_listview->set_background(false); - menu_listview->set_border(true); + menu_namelabel = new ui::Label(menu_tradewindow); + menu_namelabel->set_label("label"); + menu_namelabel->set_background(false); + menu_namelabel->set_border(false); + menu_namelabel->set_font(ui::root()->font_large()); + menu_namelabel->set_alignment(ui::AlignCenter); + menu_namelabel->show(); + + menu_inventorylistview = new ui::ListView(menu_tradewindow); + menu_inventorylistview->set_label("inventorylistview"); + menu_inventorylistview->set_background(false); + menu_inventorylistview->set_border(true); + + + menu_traderlistview = new ui::ListView(menu_tradewindow); + menu_traderlistview->set_label("traderlistview"); + menu_traderlistview->set_background(false); + menu_traderlistview->set_border(true); - menu_scrollpane = new ui::ScrollPane(menu_tradewindow, menu_infotext); - menu_scrollpane->set_background(false); - menu_scrollpane->set_border(true); - menu_scrollpane->set_alignment(ui::AlignTop); - menu_closebutton = new ui::Button(menu_tradewindow, "Return", "view hide"); + std::string test("test"); + set_item_type(test); + hide(); } @@ -45,6 +58,56 @@ TradeMenu::~TradeMenu() } +void TradeMenu::set_item_type(std::string const & itemtype) +{ + ui::ListItem *item_label = 0; + + menu_namelabel->set_text(0); + + // update inventorylistview + menu_inventorylistview->remove_children(); + + //core::Inventory *inventory = 0; + + + item_label = new ui::ListItem(menu_inventorylistview, "Inventory item 1"); + item_label->set_height(item_label->font()->height() * 2.0f); + + item_label = new ui::ListItem(menu_inventorylistview, "Inventory item 2"); + item_label->set_height(item_label->font()->height() * 2.0f); + + item_label = new ui::ListItem(menu_inventorylistview, "Inventory item 3"); + item_label->set_height(item_label->font()->height() * 2.0f); + + item_label = new ui::ListItem(menu_inventorylistview, "Inventory item 4"); + item_label->set_height(item_label->font()->height() * 2.0f); + + item_label = new ui::ListItem(menu_inventorylistview, "Inventory item 5"); + item_label->set_height(item_label->font()->height() * 2.0f); + + menu_inventorylistview->event_resize(); + + // update traderlistview + menu_traderlistview->remove_children(); + + item_label = new ui::ListItem(menu_traderlistview, "Shop item 1"); + item_label->set_height(item_label->font()->height() * 2.0f); + + item_label = new ui::ListItem(menu_traderlistview, "Shop item 2"); + item_label->set_height(item_label->font()->height() * 2.0f); + + item_label = new ui::ListItem(menu_traderlistview, "Shop item 3"); + item_label->set_height(item_label->font()->height() * 2.0f); + + item_label = new ui::ListItem(menu_traderlistview, "Shop item 4"); + item_label->set_height(item_label->font()->height() * 2.0f); + + item_label = new ui::ListItem(menu_traderlistview, "Shop item 5"); + item_label->set_height(item_label->font()->height() * 2.0f); + + menu_traderlistview->event_resize(); +} + void TradeMenu::resize() { const float smallmargin = ui::UI::elementsize.height(); @@ -58,25 +121,36 @@ void TradeMenu::resize() menu_tradewindow->set_location(smallmargin, smallmargin * 2.0f); // resize label - //menu_namelabel->set_size(menu_tradewindow->width() - fontmargin * 2.0f, menu_namelabel->font()->height()); - //menu_namelabel->set_location(fontmargin, fontmargin); - - // resize listview - menu_listview->set_size(ui::UI::elementsize.width() * 1.5f, menu_tradewindow->height() - smallmargin * 2.0f - fontmargin * 3.0f); - menu_listview->set_location(fontmargin, fontmargin * 3.0f); - - // resize infotext pane - menu_scrollpane->set_size(menu_tradewindow->width() - ui::UI::elementsize.width() * 1.5f - fontmargin * 3.0f, - menu_tradewindow->height() - smallmargin * 2.0f - fontmargin * 3.0f); - menu_scrollpane->set_location(ui::UI::elementsize.width() * 1.5f + fontmargin * 2.0f, fontmargin * 3.0f); + menu_namelabel->set_size(menu_tradewindow->width() - fontmargin * 2.0f, menu_namelabel->font()->height()); + menu_namelabel->set_location(fontmargin, fontmargin); - // resize buttons - //menu_buybutton->set_size(ui::UI::elementsize); - //menu_buybutton->set_location(menu_tradewindow->width() * 0.5f - ui::UI::elementsize.width() - smallmargin * 2.0f, menu_tradewindow->height() - smallmargin * 1.5f); + // resize inventory listview + menu_inventorylistview->set_size(ui::UI::elementsize.width(), menu_tradewindow->height() - smallmargin * 2.0f - fontmargin * 3.0f); + menu_inventorylistview->set_location(fontmargin, fontmargin * 3.0f); + // resize trader listview + menu_traderlistview->set_size(ui::UI::elementsize.width(), menu_tradewindow->height() - smallmargin * 2.0f - fontmargin * 3.0f); + menu_traderlistview->set_location(menu_tradewindow->width() - menu_traderlistview->width() - fontmargin, fontmargin * 3.0f); + + // resize close button menu_closebutton->set_size(ui::UI::elementsize); - //menu_closebutton->set_location(menu_tradewindow->width() * 0.5f + smallmargin * 2.0f, menu_tradewindow->height() - smallmargin * 1.5f); menu_closebutton->set_location(0.5f * (menu_tradewindow->width() - ui::UI::elementsize.width()), menu_tradewindow->height() - smallmargin * 1.5f ); } +bool TradeMenu::on_emit(Widget *sender, const Event event, void *data) +{ + if (event == ui::Widget::EventListItemClicked) { + if (sender->parent() == menu_inventorylistview) { + // item from inventory selected + menu_namelabel->set_text("SELL " + static_cast(sender)->text()); + } else if (sender->parent() == menu_traderlistview) { + // item from trader selected + menu_namelabel->set_text("BUY " + static_cast(sender)->text()); + } + return true; + } + + return ui::Window::on_emit(sender, event, data); +} + } diff --git a/src/client/trademenu.h b/src/client/trademenu.h index 98cf71d..37823b1 100644 --- a/src/client/trademenu.h +++ b/src/client/trademenu.h @@ -23,21 +23,25 @@ public: /// create a new trade menu TradeMenu(ui::Widget *parent, const char * label = 0); ~TradeMenu(); + + /// set the item type to trade + void set_item_type(std::string const & itemtype); protected: - /// resize event + /// resize event handler virtual void resize(); + + /// emit event handler + virtual bool on_emit(Widget *sender, const Event event, void *data); private: ui::Window *menu_tradewindow; - ui::ListView *menu_listview; - ui::ScrollPane *menu_scrollpane; + ui::ListView *menu_inventorylistview; + ui::ListView *menu_traderlistview; ui::Button *menu_closebutton; - core::Info *menu_inforecord; - ui::Text menu_infotext; - - unsigned long menu_infotimestamp; + ui::Label *menu_namelabel; + }; } diff --git a/src/core/descriptions.cc b/src/core/descriptions.cc index 307cc87..26a5858 100644 --- a/src/core/descriptions.cc +++ b/src/core/descriptions.cc @@ -15,7 +15,7 @@ namespace core ButtonDescription::ButtonDescription() { - button_model = 0; + button_info = 0; button_align = Center; button_commandtype = CommandNone; } @@ -35,16 +35,14 @@ void ButtonDescription::set_command(const std::string &command, const CommandTyp button_command.assign(command); } -void ButtonDescription::set_modelname(const std::string &modelname) +void ButtonDescription::set_alignment(Align align) { - button_modelname.assign(modelname); - - button_model = model::Model::load(modelname); + button_align = align; } -void ButtonDescription::set_alignment(Align align) +void ButtonDescription::set_info(Info *info) { - button_align = align; + button_info = info; } /* ---- class MenuDescription -------------------------------------- */ @@ -92,7 +90,7 @@ void Descriptions::serialize(MenuDescription *menu, std::ostream & os) << button->alignment() << " " << button->command_type() << " " << "\"" << button->command() << "\" " - << "\"" << button->modelname() << "\" "; + << (button->info() ? button->info()->id() : 0) << " "; } } @@ -105,6 +103,7 @@ MenuDescription * Descriptions::receive(std::istream &is) std::string n; size_t nb; char c; + long id; // menu label is >> n; @@ -157,12 +156,17 @@ MenuDescription * Descriptions::receive(std::istream &is) } } - // button modelname - n.clear(); - while ((is.get(c)) && (c != '"')); - while ((is.get(c)) && (c != '"')) - n += c; - if (n.size()) button->set_modelname(n); + // button info record id + Info *info = 0; + if (is >> id) { + info = Info::find(id); + if (id && !info) { + info = new Info(id); + } + } else { + id = 0; + } + button->set_info(info); menu->add_button(button); } @@ -231,9 +235,7 @@ bool Descriptions::load_entity_menus(core::Entity *entity, const std::string &me // default command is a game command button->set_command(strval, ButtonDescription::CommandGame); - - } else if (inifile.got_key_string("model", strval)) { - button->set_modelname(strval); + } else if (inifile.got_key_string("align", strval)) { aux::to_label(strval); if (strval.compare("left") == 0) { diff --git a/src/core/descriptions.h b/src/core/descriptions.h index 2b4b1e0..05e92af 100644 --- a/src/core/descriptions.h +++ b/src/core/descriptions.h @@ -17,8 +17,8 @@ class ButtonDescription; class MenuDescription; } +#include "core/info.h" #include "core/entity.h" -#include "model/model.h" #include "filesystem/inifile.h" namespace core @@ -52,21 +52,16 @@ public: return button_command; } - /// button info view model name - inline const std::string & modelname() const { - return button_modelname; - } - - /// button info view model - inline const model::Model *model() { - return button_model; - } - /// button text alignment inline Align alignment() const { return button_align; } + /// button info record + inline Info *info() { + return button_info; + } + /* -- mutators -------------------------------------------- */ /// set button text @@ -75,19 +70,18 @@ public: /// set button command void set_command(const std::string &command, const CommandType command_type); - /// set button name - void set_modelname(const std::string &modelname); - /// set text alignment void set_alignment(Align align); + + /// set info record + void set_info(Info *info); private: std::string button_text; CommandType button_commandtype; std::string button_command; - std::string button_modelname; Align button_align; - model::Model *button_model; + Info *button_info; }; /// description of an entity menu diff --git a/src/core/entity.cc b/src/core/entity.cc index baefcea..fdcce59 100644 --- a/src/core/entity.cc +++ b/src/core/entity.cc @@ -343,11 +343,13 @@ void Entity::receive_server_create(std::istream &is) set_modelname(n); // read info id - is >> o; - if (o) - set_info(game()->info(o)); - else - set_info(0); + if(is >> o) { + entity_info = Info::find(o); + if (o && !entity_info) + entity_info = new Info(o); + } else { + entity_info = 0; + } entity_dirty = false; } diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc index ce33dc6..3167790 100644 --- a/src/core/gameconnection.cc +++ b/src/core/gameconnection.cc @@ -100,20 +100,16 @@ Info *GameConnection::info(unsigned int id) // find the info record Info *info = Info::find(id); - if (info) { - if (!info->timestamp() || (connection_timestamp - info->timestamp()) < INFOTIMEOUT) - return info; - } else { + if (!info) { info = new Info(id); - info->add_text("Requesting information..."); } - + if ( !info->timestamp() || (connection_timestamp < info->timestamp() + INFOTIMEOUT) ) + return info; + // send an information request to the server if (connection_network) { - //con_debug << "Requesting info for " << info->id() << std::endl; info->set_timestamp(connection_timestamp); - connection_network->send_info_request(info); connection_network->transmit(); } else { @@ -121,9 +117,9 @@ Info *GameConnection::info(unsigned int id) info->set_timestamp(0); } return info; - } +/* Info *GameConnection::info(const std::string &type, const std::string &label) { if (!type.size()) { @@ -166,6 +162,7 @@ Info *GameConnection::info(const std::string &type, const std::string &label) } return info; } +*/ void GameConnection::abort() { diff --git a/src/core/gameconnection.h b/src/core/gameconnection.h index 90b45a0..bb615c1 100644 --- a/src/core/gameconnection.h +++ b/src/core/gameconnection.h @@ -57,10 +57,10 @@ public: /// localplayer sends a private message to another player void private_message(std::string const &args); - +/* /// returns an info record virtual Info *info(const std::string &type, const std::string &label); - +*/ /// returns an info record virtual Info *info(unsigned int id); diff --git a/src/core/gameinterface.h b/src/core/gameinterface.h index 1460c45..11cc0de 100644 --- a/src/core/gameinterface.h +++ b/src/core/gameinterface.h @@ -61,10 +61,10 @@ public: /// return the current game time virtual unsigned long timestamp() const = 0; - +/* /// returns an info record virtual Info *info(const std::string &type, const std::string &label) = 0; - +*/ /// returns an info record virtual Info *info(unsigned int id) = 0; diff --git a/src/core/info.cc b/src/core/info.cc index 5615f8b..1a4f68f 100644 --- a/src/core/info.cc +++ b/src/core/info.cc @@ -8,6 +8,7 @@ #include "core/info.h" #include "sys/sys.h" #include "core/info.h" +#include "core/gameinterface.h" #include @@ -16,11 +17,8 @@ namespace core /* ---- class InfoType --------------------------------------------- */ -InfoType::InfoType(const char *label) +InfoType::InfoType(const char *label) : Label(label) { - if (label) - set_label(label); - infotype_registry.push_back(this); } @@ -59,7 +57,7 @@ InfoType *InfoType::find(const std::string & label) unsigned int info_id_counter = 0; // server-side constructor, assigns an id -Info::Info(const InfoType *type) +Info::Info(const InfoType *type, const char *label) : Label(label) { info_id_counter++; info_id = info_id_counter; @@ -71,30 +69,19 @@ Info::Info(const InfoType *type) info_price = 0; } -// client-side constructor, does not assign an id -Info::Info(const InfoType *type, const std::string & label) -{ - info_id = 0; - info_type = type; - info_registry.push_back(this); - - info_model = 0; - info_timestamp = 0; - info_price = 0; - - set_label(label); -} - -// client-side constructor, does not assign an id +// client-side constructor, id is passed as param Info::Info(const unsigned int id) { info_id = id; info_type = 0; info_registry.push_back(this); - info_model = 0; - info_timestamp = 0; + info_model = 0; info_price = 0; + + info_timestamp = 1; + + add_text("Requesting server information..."); } Info::~Info() @@ -209,6 +196,9 @@ void Info::receive_server_update(std::istream &is) add_text(n); } + + // set timestamp to 0 + info_timestamp = 0; } void Info::print() const diff --git a/src/core/info.h b/src/core/info.h index 8822f2f..4b9c445 100644 --- a/src/core/info.h +++ b/src/core/info.h @@ -64,13 +64,7 @@ public: * @brief create a new server-side information card * This constructor assigns an id */ - Info(const InfoType *type); - - /** - * @brief create a new client-side information card - * This constructor doesn not assign an id - */ - Info(const InfoType *type, const std::string & label); + Info(const InfoType *type, const char *label = 0); /** * @brief create a new client-side information card @@ -102,6 +96,13 @@ public: return info_price; } + /** + * @brief timestamp + * The timestamp is used client-side, a non-zero value + * indicates the time when the info was last requested. + * If the info has been received from the server, the timestamp + * is set to 0 + */ inline const unsigned long ×tamp() const { return info_timestamp; } diff --git a/src/core/inventory.h b/src/core/inventory.h index da30715..c924683 100644 --- a/src/core/inventory.h +++ b/src/core/inventory.h @@ -55,6 +55,10 @@ public: */ Item *find(const Info *info); + inline Items &items() { + return inventory_items; + }; + private: Items inventory_items; }; diff --git a/src/core/label.cc b/src/core/label.cc index d3a7b99..d7dabc2 100644 --- a/src/core/label.cc +++ b/src/core/label.cc @@ -12,6 +12,17 @@ Label::Label() { } +Label::Label(const char *label) +{ + if (label) + labelstr.assign(label); +} + +Label::Label(const std::string & label) +{ + labelstr.assign(label); +} + Label::~Label() { labelstr.clear(); diff --git a/src/core/label.h b/src/core/label.h index 12a417c..2ca40f7 100644 --- a/src/core/label.h +++ b/src/core/label.h @@ -19,6 +19,9 @@ namespace core { class Label { public: Label(); + Label(const char *label); + Label(const std::string & label); + ~Label(); /* --- inspectors ------------------------------------------------- */ diff --git a/src/core/net.h b/src/core/net.h index a217d94..f6904b2 100644 --- a/src/core/net.h +++ b/src/core/net.h @@ -11,7 +11,7 @@ namespace core { /// network protocol version -const unsigned int PROTOCOLVERSION = 18; +const unsigned int PROTOCOLVERSION = 19; /// maximum lenght of a (compressed) network message block const unsigned int FRAMESIZE = 1152; diff --git a/src/core/netconnection.cc b/src/core/netconnection.cc index fa959be..684e6b3 100644 --- a/src/core/netconnection.cc +++ b/src/core/netconnection.cc @@ -425,13 +425,11 @@ void NetConnection::send_ping_reply(unsigned long timestamp) void NetConnection::send_info_request(Info *info) { std::ostringstream msg; - if (info->id()) { - msg << "inf " << info->id() << "\n"; - } else { - if (!info->type()) - return; - msg << "inf " << info->id() << " \"" << info->type()->label() << "\" \"" << info->label() << "\"\n"; + if (!info->id()) { + return; } + + msg << "inf " << info->id() << "\n"; this->send_raw(msg.str()); info->set_timestamp(timestamp()); @@ -838,7 +836,7 @@ void NetConnection::parse_incoming_message(const std::string & message) info->receive_server_update(msgstream); info->clear_timestamp(); - //con_debug << "Received info for " << info->id() << " " << info->type()->label() << ":" << info->label() << std::endl; + con_debug << "Received info for " << info->id() << " " << info->type()->label() << ":" << info->label() << std::endl; } } diff --git a/src/core/netconnection.h b/src/core/netconnection.h index 99b8794..8aa0727 100644 --- a/src/core/netconnection.h +++ b/src/core/netconnection.h @@ -35,7 +35,11 @@ namespace core { -/// a client to server connection +/** + * @brief client-side network methods + * This class contains the necessary methods for the client-side + * of network communication. It handles both sending and receiving. + **/ class NetConnection { public: diff --git a/src/core/netserver.cc b/src/core/netserver.cc index 0e44189..c632284 100644 --- a/src/core/netserver.cc +++ b/src/core/netserver.cc @@ -730,54 +730,13 @@ void NetServer::parse_incoming_message(NetClient *client, const std::string & me } Info *info = 0; - if (id == 0) { - // the client is requesting an information record by type and label - std::string typelabelstr; - std::string infolabelstr; - std::string n; - char c; - - // read type label - n.clear(); - while ((msgstream.get(c)) && (c != '"')); - while ((msgstream.get(c)) && (c != '"')) - n +=c; - typelabelstr.assign(n); - if (!typelabelstr.size()) { - con_warn << "^B" << client->player()->name() << "^W invalid info request" << std::endl; - return; - } - - InfoType *infotype = InfoType::find(typelabelstr); - if (!infotype) - return; - - // read info label - n.clear(); - while ((msgstream.get(c)) && (c != '"')); - while ((msgstream.get(c)) && (c != '"')) - n +=c; - infolabelstr.assign(n); - if (!infolabelstr.size()) { - con_warn << "^B" << client->player()->name() << "^W invalid info request" << std::endl; - return; + if (id) { + info = Info::find(id); + if (info) { + con_debug << "Sending info for " << info->id() << " " << info->type()->label() << ":" << info->label() << std::endl; + send_info_update(client, info); + client->transmit(); } - - //con_debug << "Received info request for " << infotype << ":" << infolabelstr << std::endl; - - info = Info::find(infotype, infolabelstr); - } else { - //con_debug << "Received info request for id " << id << std::endl; - - // the client is requesting an information record by id - info = Info::find(id); - } - - if (info) { - //con_debug << "Sending info for " << info->id() << " " << info->type()->label() << ":" << info->label() << std::endl; - - send_info_update(client, info); - client->transmit(); } return; diff --git a/src/game/base/game.cc b/src/game/base/game.cc index 729e4f8..1d4536a 100644 --- a/src/game/base/game.cc +++ b/src/game/base/game.cc @@ -748,8 +748,10 @@ bool Game::load_menus(core::Entity *entity, const std::string &menufilename) if (model) { button = new ButtonDescription(); button->set_text("buy " + model->name()); - button->set_command("buy ship " + model->label(), ButtonDescription::CommandMenu); - button->set_modelname(model->modelname()); + std::ostringstream str(""); + str << "buy " << model->id(); + button->set_command(str.str() , ButtonDescription::CommandMenu); + button->set_info(model); button->set_alignment(ButtonDescription::Left); menu_dealer->add_button(button); } diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index 98c8dab..d12571d 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -8,12 +8,12 @@ noinst_LTLIBRARIES = libui.la endif noinst_HEADERS = bitmap.h button.h console.h container.h definitions.h font.h \ - iconbutton.h inputbox.h label.h listview.h menu.h modelview.h paint.h \ + iconbutton.h inputbox.h label.h listitem.h listview.h menu.h modelview.h paint.h \ palette.h scrollpane.h toolbar.h ui.h widget.h \ window.h libui_la_SOURCES = bitmap.cc button.cc console.cc container.cc \ - font.cc iconbutton.cc inputbox.cc label.cc listview.cc \ + font.cc iconbutton.cc inputbox.cc label.cc listitem.cc listview.cc \ menu.cc modelview.cc paint.cc palette.cc scrollpane.cc \ toolbar.cc ui.cc widget.cc window.cc libui_la_LDFLAGS = -avoid-version -no-undefined diff --git a/src/ui/button.cc b/src/ui/button.cc index 85cad7e..9196b90 100644 --- a/src/ui/button.cc +++ b/src/ui/button.cc @@ -81,6 +81,9 @@ bool Button::on_keypress(const int key, const unsigned int modifier) if (key == 512 + SDL_BUTTON_LEFT) { core::cmd() << button_command << std::endl; audio::play("ui/button"); + + emit(EventButtonClicked); + return true; } diff --git a/src/ui/listview.cc b/src/ui/listview.cc index 56fa324..da320c5 100644 --- a/src/ui/listview.cc +++ b/src/ui/listview.cc @@ -13,6 +13,8 @@ ListView::ListView(Widget *parent) : Widget(parent) { set_label("listview"); set_border(true); + + listview_scroll = 0.0f; } ListView::~ListView() diff --git a/src/ui/modelview.cc b/src/ui/modelview.cc index f247e5b..18cc091 100755 --- a/src/ui/modelview.cc +++ b/src/ui/modelview.cc @@ -83,9 +83,9 @@ void ModelView::draw() } paint::color(1.0f, 1.0f, 1.0f); - model::Model *model = model::Model::find(modelview_modelname); + model::Model *model = model::Model::load(modelview_modelname); if (!model) { - paint::bitmap(global_location(), size(), "bitmap/notex"); + paint::bitmap(global_location(), size(), "bitmaps/notex"); return; } diff --git a/src/ui/widget.cc b/src/ui/widget.cc index 39fbe98..5fe6f17 100644 --- a/src/ui/widget.cc +++ b/src/ui/widget.cc @@ -327,7 +327,7 @@ bool Widget::event_emit(Widget *sender, const Event event, void *data) if (on_emit(sender, event, data)) { return true; } else if (parent()) { - return (parent()->on_emit(sender, event, data)); + return (parent()->event_emit(sender, event, data)); } else { return false; } diff --git a/src/ui/widget.h b/src/ui/widget.h index 50678fa..856fca0 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -28,7 +28,7 @@ class Widget public: /// types of custom events a widget can emit - enum Event {EventNone = 0, EventSelected = 1}; + enum Event {EventNone = 0, EventButtonClicked, EventListItemClicked}; /// create a new widget Widget(Widget *parent = 0); @@ -202,9 +202,6 @@ public: /// enable or disable widget background void set_background(bool background = true); - /// emit a custom event - void emit(const Event event, const void *data=0); - /* -- event distributors --------------------------------------- */ /** @@ -239,6 +236,14 @@ public: **/ bool event_emit(Widget *sender, const Event event, void *data = 0); + /// emit a custom event + inline void emit(const Event event, void *data=0) { + event_emit(this, event, data); + } + + /// remove all child widgets + virtual void remove_children(); + protected: /// type definition for child widgets typedef std::list Children; @@ -339,9 +344,6 @@ protected: /// remove a child widget virtual void remove_child(Widget *child); - /// remove all child widgets - virtual void remove_children(); - private: void draw_debug_border(); -- cgit v1.2.3