From a95028547981614e06ea7a6d22b853b85418cea3 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 15 Apr 2009 17:08:51 +0000 Subject: added info registry, list_info added network info transfer added info based buy menu and related game changes --- src/client/Makefile.am | 8 +-- src/client/buymenu.cc | 132 +++++++++++++++++++++++++++++++++++++++++++++++ src/client/buymenu.h | 58 +++++++++++++++++++++ src/client/client.cc | 21 +++++--- src/client/client.h | 4 ++ src/client/entitymenu.cc | 75 +++++++++++++++++++++++++-- src/client/entitymenu.h | 2 +- src/client/input.cc | 7 ++- src/client/playerview.cc | 79 ++++++++++++++++++++++------ src/client/playerview.h | 10 +++- src/client/targets.cc | 5 +- src/client/trademenu.cc | 32 ++++++++++++ src/client/trademenu.h | 29 +++++++++++ 13 files changed, 426 insertions(+), 36 deletions(-) create mode 100644 src/client/buymenu.cc create mode 100644 src/client/buymenu.h create mode 100644 src/client/trademenu.cc create mode 100644 src/client/trademenu.h (limited to 'src/client') diff --git a/src/client/Makefile.am b/src/client/Makefile.am index 557adc1..2786d80 100644 --- a/src/client/Makefile.am +++ b/src/client/Makefile.am @@ -7,9 +7,9 @@ else noinst_LTLIBRARIES = libclient.la endif -libclient_la_SOURCES = action.cc chat.cc client.cc clientext.cc entitymenu.cc \ - hud.cc infowidget.cc input.cc joystick.cc key.cc keyboard.cc map.cc \ - notifications.cc playerview.cc soundext.cc targets.cc video.cc worldview.cc +libclient_la_SOURCES = action.cc buymenu.cc chat.cc client.cc clientext.cc \ + entitymenu.cc hud.cc infowidget.cc input.cc joystick.cc key.cc keyboard.cc map.cc \ + notifications.cc playerview.cc soundext.cc targets.cc trademenu.cc video.cc worldview.cc libclient_la_CFLAGS = $(LIBSDL_CFLAGS) $(GL_CFLAGS) libclient_la_LDFLAGS = -avoid-version -no-undefined $(GL_LIBS) $(LIBSDL_LIBS) @@ -19,3 +19,5 @@ noinst_HEADERS = action.h chat.h client.h clientext.h hud.h entitymenu.h \ libclient_la_LIBADD = $(top_builddir)/src/core/libcore.la $(top_builddir)/src/audio/libaudio.la \ $(top_builddir)/src/render/librender.la $(top_builddir)/src/ui/libui.la +_SOURCES = trademenu.h +_SOURCES = buymenu.h diff --git a/src/client/buymenu.cc b/src/client/buymenu.cc new file mode 100644 index 0000000..b0a0b48 --- /dev/null +++ b/src/client/buymenu.cc @@ -0,0 +1,132 @@ +/* + client/buymenu.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "ui/ui.h" +#include "ui/button.h" +#include "ui/paint.h" +#include "client/buymenu.h" +#include "core/info.h" +#include "core/application.h" +namespace client +{ + +BuyMenu::BuyMenu(ui::Widget *parent, const char * label) : ui::Window(parent) +{ + set_border(false); + set_background(true); + + if (label) + set_label(label); + else + set_label("buymenu"); + + // model pane (left) + menu_modelpane = new ui::Window(this); + menu_modelpane->set_label("modelpane"); + menu_modelpane->set_background(true); + menu_modelpane->set_border(true); + + menu_closebutton = new ui::Button(menu_modelpane, "Close","view hide"); + + // text pane (right) + menu_textpane = new ui::Window(this); + menu_textpane->set_label("textpane"); + menu_textpane->set_background(true); + menu_textpane->set_border(true); + + menu_namelabel = new ui::Label(menu_textpane); + menu_namelabel->set_label("infolabel"); + 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_buybutton = new ui::Button(menu_textpane, "Buy"); + menu_scrollpane = new ui::ScrollPane(menu_textpane, menu_infotext); + menu_scrollpane->set_background(false); + menu_scrollpane->set_border(false); + menu_scrollpane->set_alignment(ui::AlignTop); + + menu_infotimestamp = 0; + menu_inforecord = 0; + + hide(); +} + +BuyMenu::~BuyMenu() +{ + +} + +void BuyMenu::set_item(std::string const & itemtype, std::string const & itemname) +{ + menu_itemtype.assign(itemtype); + aux::to_label(menu_itemtype); + + menu_itemname.assign(itemname); + aux::to_label(menu_itemname); + + menu_buybutton->set_command("remote buy " + itemtype + ' ' + itemname + "; view hide"); + menu_buybutton->set_label("buy " + itemname); + + menu_infotext.clear(); + menu_namelabel->set_text(0); + + core::Info *info = core::game()->info(itemtype+'/'+itemname); + if (info) { + menu_namelabel->set_text(info->name()); + for (core::Info::Text::iterator it = info->text().begin(); it != info->text().end(); it++) { + menu_infotext.push_back((*it)); + } + menu_infotimestamp = info->timestamp(); + } else { + menu_infotext.push_back("Information is not available"); + menu_infotimestamp = 0; + } + + menu_inforecord = info; +} + +void BuyMenu::resize() +{ + const float smallmargin = ui::UI::elementsize.height(); + + set_size(parent()->size()); + + // reposition model pane (left) + menu_modelpane->set_size(ui::UI::elementsize.width() * 1.5f, height() - smallmargin * 4.0f); + menu_modelpane->set_location(smallmargin, smallmargin * 2.0f); + + menu_closebutton->set_size(ui::UI::elementsize); + menu_closebutton->set_location((menu_modelpane->width() - menu_closebutton->width()) * 0.5f, + menu_modelpane->height() - menu_closebutton->height() - ui::UI::elementsize.height() * 0.5f); + + // reposition text pane (right) + menu_textpane->set_size(width() - smallmargin * 3.0f - menu_modelpane->width(), height() - smallmargin * 4.0f); + menu_textpane->set_location(smallmargin * 2.0f + menu_modelpane->width(), smallmargin * 2.0f); + + menu_buybutton->set_size(ui::UI::elementsize); + menu_buybutton->set_location((menu_textpane->width() - menu_buybutton->width()) * 0.5f, + menu_textpane->height() - menu_buybutton->height() - ui::UI::elementsize.height() * 0.5f); + + menu_namelabel->set_size(menu_textpane->width(), menu_namelabel->font()->height() * 2.0f); + menu_namelabel->set_location(0, 4); + + menu_scrollpane->set_size(menu_textpane->width() - 8, menu_buybutton->top() - menu_namelabel->bottom() - 8 ); + menu_scrollpane->set_location(4, menu_namelabel->bottom() + 4); + +} + +void BuyMenu::draw() +{ + // update content if necessary + if (menu_infotimestamp && (menu_infotimestamp != menu_inforecord->timestamp())) + set_item(menu_itemtype, menu_itemname); + + ui::Window::draw(); +} + +} + diff --git a/src/client/buymenu.h b/src/client/buymenu.h new file mode 100644 index 0000000..81a87bd --- /dev/null +++ b/src/client/buymenu.h @@ -0,0 +1,58 @@ +/* + client/buymenu.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CLIENT_BUYMENU_H__ +#define __INCLUDED_CLIENT_BUYMENU_H__ + +#include "core/info.h" +#include "ui/container.h" +#include "ui/button.h" +#include "ui/label.h" +#include "ui/window.h" +#include "ui/scrollpane.h" + +namespace client +{ + +/// The buy menu is used to trade a single item, like a ship or an upgrade +class BuyMenu : public ui::Window +{ +public: + /// create a new menu + BuyMenu(ui::Widget *parent, const char * label = 0); + ~BuyMenu(); + + void set_item(std::string const & itemtype, std::string const & itemname); + +protected: + /// resize event + virtual void resize(); + + /// draw event + virtual void draw(); + +private: + + ui::Window *menu_modelpane; + ui::Window *menu_textpane; + ui::Label *menu_namelabel; + ui::ScrollPane *menu_scrollpane; + + ui::Button *menu_closebutton; + ui::Button *menu_buybutton; + + std::string menu_itemtype; + std::string menu_itemname; + + core::Info *menu_inforecord; + ui::Text menu_infotext; + unsigned long menu_infotimestamp; +}; + +} + +#endif // __INCLUDED_CLIENT_BUYMENU_H__ + diff --git a/src/client/client.cc b/src/client/client.cc index dffa1ca..47af682 100644 --- a/src/client/client.cc +++ b/src/client/client.cc @@ -144,6 +144,9 @@ void Client::init(int count, char **arguments) func = core::Func::add("menu", func_menu); func->set_info("[command] menu functions"); + func = core::Func::add("view", func_view); + func->set_info("[command] view menu functions"); + previous_timestamp = 0; } @@ -256,6 +259,7 @@ void Client::shutdown() core::Func::remove("ui_map"); core::Func::remove("ui_menu"); core::Func::remove("menu"); + core::Func::remove("view"); audio::shutdown(); @@ -495,6 +499,15 @@ void Client::func_ui_menu(std::string const &args) } } +// entity menus +void Client::func_view(std::string const &args) +{ + if (client()->worldview()) { + client()->worldview()->playerview()->show_menu(args); + } +} + +// global menus void Client::func_menu(std::string const &args) { if (!ui::root()) { @@ -535,14 +548,6 @@ void Client::func_menu(std::string const &args) } else if (command.compare("list") == 0) { ui::root()->list_menus(); - } else if (command.compare("view") == 0) { - if (client()->worldview()) { - std::string label; - if (!(argstr >> label)) { - label.assign("main"); - } - client()->worldview()->playerview()->show_menu(label); - } } else { ui::root()->show_menu(command.c_str()); } diff --git a/src/client/client.h b/src/client/client.h index 375a9ce..dbb2c44 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -76,13 +76,17 @@ private: static void func_ui_restart(std::string const &args); static void func_ui_console(std::string const &args); static void func_list_menu(std::string const &args); + static void func_ui_help(); + static void func_ui(std::string const &args); static void func_ui_chat(std::string const &args); static void func_ui_chatbar(std::string const &args); static void func_ui_map(std::string const &args); static void func_ui_menu(std::string const &args); + static void func_menu(std::string const &args); + static void func_view(std::string const &args); WorldView *client_worldview; diff --git a/src/client/entitymenu.cc b/src/client/entitymenu.cc index f727ff3..f1529e1 100644 --- a/src/client/entitymenu.cc +++ b/src/client/entitymenu.cc @@ -16,8 +16,10 @@ EntityMenu::EntityMenu(ui::Widget *parent, const char * label) : ui::Window(pare { set_border(false); set_background(false); - set_label(label); - set_label("entitymenu"); + if (label) + set_label(label); + else + set_label("entitymenu"); menu_container = new ui::Container(this); hide(); @@ -73,7 +75,74 @@ void EntityMenu::generate(core::Entity *entity, const char *menulabel) for (core::MenuDescription::Buttons::iterator it = menudescr->buttons().begin(); it != menudescr->buttons().end(); it++) { core::ButtonDescription *buttondescr = (*it); - Button *button = new Button(menu_container, buttondescr->text().c_str(), buttondescr->command().c_str()); + + // parse the command sequence + size_t i = 0; + std::string result; + std::string current; + bool quote = false; + + while (i < buttondescr->command().size()) { + const char c = buttondescr->command()[i]; + + if (c == '"') { + quote = !quote; + result += c; + + } else if (c == ';') { + + if (quote) { + current += c; + + } else if (current.size()) { + if (buttondescr->command_type() == core::ButtonDescription::CommandGame) { + if (result.size()) { + result += ';'; + } + + result.append("remote "); + result.append(current); + + } else if (buttondescr->command_type() == core::ButtonDescription::CommandMenu) { + if (result.size()) { + result += ';'; + } + + result.append("view "); + result.append(current); + } + current.clear(); + } + + } else { + current += c; + } + + i++; + } + + if (current.size()) { + if (buttondescr->command_type() == core::ButtonDescription::CommandGame) { + if (result.size()) { + result += ';'; + } + + result.append("remote "); + result.append(current); + + } else if (buttondescr->command_type() == core::ButtonDescription::CommandMenu) { + if (result.size()) { + result += ';'; + } + + result.append("view "); + result.append(current); + } + + } + + Button *button = new Button(menu_container, buttondescr->text().c_str(), result.c_str()); + switch (buttondescr->alignment()) { case core::ButtonDescription::Center: button->set_alignment(AlignCenter); diff --git a/src/client/entitymenu.h b/src/client/entitymenu.h index ac5a793..adc31a9 100644 --- a/src/client/entitymenu.h +++ b/src/client/entitymenu.h @@ -15,7 +15,7 @@ namespace client { -/// entity menus +/// entity menu class EntityMenu : public ui::Window { public: diff --git a/src/client/input.cc b/src/client/input.cc index 3ccf15c..943bed1 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -516,6 +516,9 @@ void key_pressed(Key *key) } if (ui::root()->input_key(true, Keyboard::translate_keysym(key->sym(), keyboard_modifiers), keyboard_modifiers)) { + + // work-around for the mouse release event FIXME + //key->key_pressed = 0; return; } else if (!core::localplayer()->view() && core::application()->connected() && core::localcontrol()) { @@ -549,12 +552,14 @@ void key_released(Key *key) if (core::application()->connected() && core::localcontrol()) { + // FIXME mouse release selection should be handled inside the hud if ((key->sym() == 512 + SDL_BUTTON_LEFT) && targets::hover() && (key->waspressed() <= (input_mousedelay->value()/1000.0f) ) ) { // hovering target selected targets::select_target(targets::hover()); } - // the release event still must be processed as usual + + // the release event must still be processed as usual char c = 0; c = key->bind(Key::None).c_str()[0]; if (c == '+') { diff --git a/src/client/playerview.cc b/src/client/playerview.cc index 54d444d..e4a889a 100644 --- a/src/client/playerview.cc +++ b/src/client/playerview.cc @@ -4,6 +4,9 @@ the terms and conditions of the GNU General Public License version 2 */ +#include +#include + #include "audio/audio.h" #include "client/playerview.h" #include "ui/ui.h" @@ -32,10 +35,11 @@ PlayerView::PlayerView(ui::Widget *parent) : ui::Widget(parent) view_chat = new Chat(this); view_map = new Map(this); view_hud = new HUD(this); - view_menu = new EntityMenu(this); + view_entitymenu = new EntityMenu(this); + view_buymenu = new BuyMenu(this); view_hud->lower(); - view_menu->raise(); + view_entitymenu->raise(); } PlayerView::~PlayerView() @@ -49,7 +53,7 @@ void PlayerView::clear() view_chat->hide(); view_map->hide(); - view_menu->hide(); + view_entitymenu->hide(); view_lastentity = 0; } @@ -67,8 +71,8 @@ void PlayerView::toggle_map() if(chat()->visible() && !chat()->small_view()) chat()->hide(); - if (view_menu->visible()) - view_menu->hide(); + if (view_entitymenu->visible()) + view_entitymenu->hide(); } map()->toggle(); @@ -85,8 +89,8 @@ void PlayerView::toggle_chat() if(map()->visible()) map()->hide(); - if (view_menu->visible()) - view_menu->hide(); + if (view_entitymenu->visible()) + view_entitymenu->hide(); } chat()->set_small_view(false); chat()->toggle(); @@ -99,16 +103,47 @@ void PlayerView::toggle_chatbar() chat()->toggle(); } -void PlayerView::show_menu(const std::string & label) +void PlayerView::show_menu(const std::string & args) { + if (!args.size()) + return; + if (!core::localplayer()->view()) return; if (!core::localplayer()->view()->menus().size()) return; - view_menu->generate(core::localplayer()->view(), label.c_str()); - view_menu->show(); + std::stringstream argstr(args); + std::string label; + if (!(argstr >> label)) + return; + + if (label.compare("buy") == 0) { + // buy menu, single item + std::string itemtype; + std::string itemname; + + if ((argstr >> itemtype) && (argstr >> itemname)) { + view_buymenu->set_item(itemtype, itemname); + view_buymenu->show(); + view_entitymenu->hide(); + } else { + con_print << "usage: view buy [string] [string] buy menu for item type and name" << std::endl; + } + + } else if (label.compare("trade") == 0) { + // trade menu, multiple items + + } else if (label.compare("hide") == 0) { + view_buymenu->hide(); + view_entitymenu->hide(); + + } else { + view_entitymenu->generate(core::localplayer()->view(), label.c_str()); + view_entitymenu->show(); + view_buymenu->hide(); + } if (chat()->visible() && chat()->small_view()) chat()->raise(); @@ -121,6 +156,9 @@ void PlayerView::resize() set_size(parent()->size()); + // reposition buy menu + view_buymenu->event_resize(); + // set hud geometry view_hud->set_geometry(0,0, width(), height()); view_hud->event_resize(); @@ -142,6 +180,8 @@ void PlayerView::resize() void PlayerView::draw() { + const float smallmargin = ui::UI::elementsize.height(); + if (core::localplayer()->view()) { // hide hide when a view is set @@ -164,12 +204,17 @@ void PlayerView::draw() audio::play("ui/menu"); view_lastentity = core::localplayer()->view(); - } else if (!view_menu->visible() && !map()->visible() && (!chat()->visible() || chat()->small_view()) ) { + } else if (!view_entitymenu->visible() && !view_buymenu->visible() && + !map()->visible() && (!chat()->visible() || chat()->small_view()) ) { + // show the menu if there's no other window open menu()->show(); audio::play("ui/menu"); } + view_notify->set_size(width() - smallmargin * 3.0f - ui::UI::elementsize.width() * 1.5f, height() - smallmargin * 4.0f); + view_notify->set_location(smallmargin * 2.0f + ui::UI::elementsize.width() * 1.5f, smallmargin * 2.0f); + } else { // entity without menus, plain view view_lastentity = 0; @@ -179,8 +224,13 @@ void PlayerView::draw() } } else { - if (view_menu->visible()) { - view_menu->hide(); + view_notify->set_geometry(view_map->location(), view_map->size()); + + if (view_entitymenu->visible()) { + view_entitymenu->hide(); + } + if (view_buymenu->visible()) { + view_buymenu->hide(); } label_viewname->hide(); @@ -193,9 +243,6 @@ void PlayerView::draw() label_zonename->set_text(core::localplayer()->zone()->name()); } - //const float largemargin = ui::UI::elementsize.width() * 0.25; - const float smallmargin = ui::UI::elementsize.height(); - // reposition chat widget if (view_chat->small_view()) { view_chat->set_size(width() - smallmargin * 2, font()->height() * 2); diff --git a/src/client/playerview.h b/src/client/playerview.h index 9cf8a94..a09f5ca 100644 --- a/src/client/playerview.h +++ b/src/client/playerview.h @@ -8,7 +8,9 @@ #define __INCLUDED_CLIENT_PLAYERVIEW_H__ #include "client/chat.h" +#include "client/buymenu.h" #include "client/entitymenu.h" +#include "client/trademenu.h" #include "client/hud.h" #include "client/map.h" #include "client/notifications.h" @@ -40,10 +42,11 @@ public: /// show entity menus void show_menu(const std::string & label); + inline HUD *hud() { return view_hud; } inline Map *map() { return view_map; } inline Chat *chat() { return view_chat; } inline Notifications *notify() { return view_notify; } - inline EntityMenu *menu() { return view_menu; } + inline EntityMenu *menu() { return view_entitymenu; } protected: virtual void draw(); @@ -54,7 +57,10 @@ private: HUD *view_hud; Chat *view_chat; Map *view_map; - EntityMenu *view_menu; + + EntityMenu *view_entitymenu; + BuyMenu *view_buymenu; + TradeMenu *view_trademenu; core::Entity *view_lastentity; diff --git a/src/client/targets.cc b/src/client/targets.cc index 8a50510..af8ec17 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -362,7 +362,7 @@ void frame() if (entity->id() == current_target_id) { current_target = entity; } - + // check if the mouse is hovering the entity Vector3f v(entity->location() - render::Camera::eye()); v.normalize(); @@ -390,10 +390,11 @@ void frame() } } } + } } - + if (!current_target) { current_target_id = 0; } else { diff --git a/src/client/trademenu.cc b/src/client/trademenu.cc new file mode 100644 index 0000000..9db1299 --- /dev/null +++ b/src/client/trademenu.cc @@ -0,0 +1,32 @@ +/* + client/trademenu.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#include "ui/ui.h" +#include "ui/button.h" +#include "ui/paint.h" +#include "client/trademenu.h" + +namespace client +{ + +TradeMenu::TradeMenu(ui::Widget *parent, const char * label) : ui::Window(parent) +{ + set_border(false); + set_background(false); + if (label) + set_label(label); + else + set_label("trademenu"); + + hide(); +} + +TradeMenu::~TradeMenu() +{ + +} + +} diff --git a/src/client/trademenu.h b/src/client/trademenu.h new file mode 100644 index 0000000..feb91f4 --- /dev/null +++ b/src/client/trademenu.h @@ -0,0 +1,29 @@ +/* + client/trademenu.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +#ifndef __INCLUDED_CLIENT_TRADEMENU_H__ +#define __INCLUDED_CLIENT_TRADEMENU_H__ + +#include "ui/container.h" +#include "ui/label.h" +#include "ui/window.h" + +namespace client +{ + +/// trade menu +class TradeMenu : public ui::Window +{ +public: + /// create a new menu + TradeMenu(ui::Widget *parent, const char * label = 0); + ~TradeMenu(); +}; + +} + +#endif // __INCLUDED_CLIENT_TRADEMENU_H__ + -- cgit v1.2.3