Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/ROADMAP130
-rw-r--r--src/client/buymenu.cc52
-rw-r--r--src/client/buymenu.h2
-rw-r--r--src/client/map.cc10
-rw-r--r--src/client/playerview.cc16
-rw-r--r--src/client/trademenu.cc122
-rw-r--r--src/client/trademenu.h18
-rw-r--r--src/core/descriptions.cc36
-rw-r--r--src/core/descriptions.h26
-rw-r--r--src/core/entity.cc12
-rw-r--r--src/core/gameconnection.cc15
-rw-r--r--src/core/gameconnection.h4
-rw-r--r--src/core/gameinterface.h4
-rw-r--r--src/core/info.cc34
-rw-r--r--src/core/info.h15
-rw-r--r--src/core/inventory.h4
-rw-r--r--src/core/label.cc11
-rw-r--r--src/core/label.h3
-rw-r--r--src/core/net.h2
-rw-r--r--src/core/netconnection.cc12
-rw-r--r--src/core/netconnection.h6
-rw-r--r--src/core/netserver.cc53
-rw-r--r--src/game/base/game.cc6
-rw-r--r--src/ui/Makefile.am4
-rw-r--r--src/ui/button.cc3
-rw-r--r--src/ui/listview.cc2
-rwxr-xr-xsrc/ui/modelview.cc4
-rw-r--r--src/ui/widget.cc2
-rw-r--r--src/ui/widget.h16
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 <string>
#include <sstream>
+#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<ui::ListItem *>(sender)->text());
+ } else if (sender->parent() == menu_traderlistview) {
+ // item from trader selected
+ menu_namelabel->set_text("BUY " + static_cast<ui::ListItem *>(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 <iomanip>
@@ -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 &timestamp() 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<Widget *> 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();