From e55638d081e2e1ff6fbc06e0e8ac0381a04308e7 Mon Sep 17 00:00:00 2001 From: Stijn Buys Date: Wed, 15 Sep 2010 21:29:18 +0000 Subject: updated comments, updated buy menu, info support for map window, added const to target selection --- src/client/Makefile.am | 8 ++-- src/client/buymenu.cc | 91 +++++++++++++++++++++------------------------- src/client/buymenu.h | 9 ++--- src/client/chat.cc | 30 ++++++++++++++- src/client/chat.h | 4 ++ src/client/client.h | 6 +-- src/client/hud.cc | 2 +- src/client/infowidget.cc | 2 +- src/client/input.cc | 2 +- src/client/map.cc | 76 +++++++++++++++++++++++++++++++------- src/client/map.h | 20 ++++++++-- src/client/playerview.cc | 4 -- src/client/targets.cc | 26 ++++++------- src/client/targets.h | 10 ++--- src/client/trademenu.cc | 8 +++- src/client/trademenu.h | 9 ++++- src/core/commandbuffer.cc | 4 +- src/core/entity.h | 43 +++++++++++++++------- src/core/gameconnection.cc | 16 +++----- src/core/info.h | 14 +++---- src/core/inventory.h | 6 +-- src/core/item.h | 11 +++++- src/math/functions.cc | 6 +-- src/math/functions.h | 9 ++--- src/render/draw.cc | 2 +- src/render/draw.h | 2 +- src/render/tgafile.cc | 15 ++++---- src/ui/container.cc | 6 +-- src/ui/widget.cc | 19 ++++++++++ src/ui/widget.h | 51 ++++++++++++++++++++------ 30 files changed, 332 insertions(+), 179 deletions(-) (limited to 'src') diff --git a/src/client/Makefile.am b/src/client/Makefile.am index a90bfdb..3169525 100644 --- a/src/client/Makefile.am +++ b/src/client/Makefile.am @@ -8,16 +8,16 @@ noinst_LTLIBRARIES = libclient.la endif 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 targeticonbutton.cc targets.cc trademenu.cc \ - video.cc worldview.cc + entitymenu.cc hud.cc infowidget.cc input.cc inventorywindow.cc joystick.cc key.cc \ + keyboard.cc map.cc notifications.cc playerview.cc soundext.cc targeticonbutton.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) noinst_HEADERS = action.h chat.h client.h clientext.h hud.h entitymenu.h \ - input.h joystick.h key.h keyboard.h map.h notifications.h soundext.h \ + input.h inventorywindow.h joystick.h key.h keyboard.h map.h notifications.h soundext.h \ targets.h video.h infowidget.h playerview.h worldview.h trademenu.h buymenu.h \ targeticonbutton.h diff --git a/src/client/buymenu.cc b/src/client/buymenu.cc index d708511..c3878a8 100644 --- a/src/client/buymenu.cc +++ b/src/client/buymenu.cc @@ -16,50 +16,42 @@ namespace client BuyMenu::BuyMenu(ui::Widget *parent, const char * label) : ui::Window(parent) { set_border(false); - set_background(true); + set_background(false); 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_modelview = new ui::ModelView(menu_modelpane); - menu_modelview->set_label("modelview"); - menu_modelview->set_background(false); - menu_modelview->set_border(false); - - menu_closebutton = new ui::Button(menu_modelpane, "Return", "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_buywindow = new ui::Window(this); + menu_buywindow->set_label("buywindow"); + menu_buywindow->set_background(true); + menu_buywindow->set_border(true); - menu_namelabel = new ui::Label(menu_textpane); + menu_namelabel = new ui::Label(menu_buywindow); 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_scrollpane = new ui::ScrollPane(menu_textpane, menu_infotext); + menu_modelview = new ui::ModelView(menu_buywindow); + menu_modelview->set_label("modelview"); + menu_modelview->set_background(false); + menu_modelview->set_border(false); + + menu_scrollpane = new ui::ScrollPane(menu_buywindow, menu_infotext); menu_scrollpane->set_background(false); menu_scrollpane->set_border(false); menu_scrollpane->set_alignment(ui::AlignTop); - menu_buybutton = new ui::Button(menu_textpane, "Buy"); + menu_closebutton = new ui::Button(menu_buywindow, "Return", "view hide"); + menu_buybutton = new ui::Button(menu_buywindow, "Buy"); menu_infotimestamp = 0; menu_inforecord = 0; - menu_modelpane->raise(); // DEBUG hide(); } @@ -89,7 +81,7 @@ void BuyMenu::set_item(std::string const & itemtype, std::string const & itemnam menu_namelabel->set_text(menu_inforecord->name()); menu_modelview->set_modelname(menu_inforecord->modelname()); - for (core::Info::Text::iterator it = menu_inforecord->text().begin(); it != menu_inforecord->text().end(); it++) { + 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(); @@ -103,34 +95,35 @@ void BuyMenu::set_item(std::string const & itemtype, std::string const & itemnam void BuyMenu::resize() { const float smallmargin = ui::UI::elementsize.height(); + const float fontmargin = menu_namelabel->font()->height(); + // this menu takes the entire screen 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); - + + // resize the subwindow + menu_buywindow->set_size(width() - smallmargin * 2.0f, height()- smallmargin * 4.0f); + menu_buywindow->set_location(smallmargin, smallmargin * 2.0f); + + // resize label + menu_namelabel->set_size(menu_buywindow->width() - fontmargin * 2.0f, menu_namelabel->font()->height()); + menu_namelabel->set_location(fontmargin, fontmargin); + + // resize model view + menu_modelview->set_size(ui::UI::elementsize.width() * 1.5f, + menu_buywindow->height() - smallmargin * 2.0f - fontmargin * 3.0f); + menu_modelview->set_location(fontmargin, fontmargin * 3.0f); + + // resize infotext pane + menu_scrollpane->set_size(menu_buywindow->width() - ui::UI::elementsize.width() * 1.5f - fontmargin * 3.0f, + menu_buywindow->height() - smallmargin * 2.0f - fontmargin * 3.0f); + menu_scrollpane->set_location(ui::UI::elementsize.width() * 1.5f + fontmargin * 2.0f, fontmargin * 3.0f); + + // resize buttons + menu_buybutton->set_size(ui::UI::elementsize); + menu_buybutton->set_location(menu_buywindow->width() * 0.5f - ui::UI::elementsize.width() - smallmargin * 2.0f, menu_buywindow->height() - smallmargin * 1.5f); + 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); - - menu_modelview->set_size(menu_modelpane->width() - 8, menu_modelpane->width() - 8); - menu_modelview->set_location(4, 4); - - // 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); - + menu_closebutton->set_location(menu_buywindow->width() * 0.5f + smallmargin * 2.0f, menu_buywindow->height() - smallmargin * 1.5f); } void BuyMenu::draw() diff --git a/src/client/buymenu.h b/src/client/buymenu.h index f624ec3..016f473 100644 --- a/src/client/buymenu.h +++ b/src/client/buymenu.h @@ -39,22 +39,21 @@ protected: virtual bool on_keypress(const int key, const unsigned int modifier); private: - ui::Window *menu_modelpane; - ui::Window *menu_textpane; + ui::Window *menu_buywindow; ui::Label *menu_namelabel; ui::ScrollPane *menu_scrollpane; + ui::ModelView *menu_modelview; ui::Button *menu_closebutton; ui::Button *menu_buybutton; - ui::ModelView *menu_modelview; - std::string menu_itemtype; std::string menu_itemname; core::Info *menu_inforecord; ui::Text menu_infotext; - unsigned long menu_infotimestamp; + + unsigned long menu_infotimestamp; }; } diff --git a/src/client/chat.cc b/src/client/chat.cc index 5eb1922..c1fc78f 100644 --- a/src/client/chat.cc +++ b/src/client/chat.cc @@ -8,6 +8,7 @@ #include "client/chat.h" #include "client/client.h" #include "core/core.h" +#include "core/gameinterface.h" #include "sys/sys.h" #include "ui/ui.h" @@ -26,6 +27,12 @@ Chat::Chat(ui::Widget *parent) : ui::Window(parent) chat_scrollpane = new ui::ScrollPane(this, chat_log); chat_scrollpane->set_border(false); + chat_scrollpane->set_label("text"); + + chat_playerpane = new ui::ScrollPane(this, chat_players); + chat_playerpane->set_border(false); + chat_playerpane->set_label("players"); + chat_playerpane->set_alignment(ui::AlignLeft | ui::AlignTop); chat_input = new ui::InputBox(this); chat_input->set_border(false); @@ -46,6 +53,7 @@ Chat::~Chat() void Chat::clear() { + chat_players.clear(); chat_log.clear(); chat_input->clear(); } @@ -172,10 +180,24 @@ void Chat::event_draw() } if (chat_small) { + chat_playerpane->hide(); chat_scrollpane->hide(); } else { + chat_playerpane->show(); chat_scrollpane->show(); + + chat_players.clear(); + std::ostringstream ostr; + + ostr << "^B" << core::game()->players().size() << " " << aux::plural("player", core::game()->players().size()); + chat_players.push_back(ostr.str()); + + for (core::GameInterface::Players::iterator it = core::game()->players().begin(); it != core::game()->players().end(); it++) { + core::Player *player = (*it); + chat_players.push_back(player->name() + "^N"); + } } + Widget::event_draw(); } @@ -187,9 +209,15 @@ void Chat::resize() s[0] -= margin * 2; s[1] -= margin * 2; + // player names + chat_playerpane->set_size(ui::UI::elementsize.width() , s.height() - font()->height() * 2.5f); + chat_playerpane->set_location(s.width() - chat_playerpane->width() + 2.0f * margin, margin + font()->height()); + + // chat text + chat_scrollpane->set_size(s.width() - chat_playerpane->width() - margin, s.height() - font()->height() * 1.5f); chat_scrollpane->set_location(margin, margin); - chat_scrollpane->set_size(s.width(), s.height() - font()->height() *1.5f); + // input bar chat_input->set_location(margin, height() - font()->height() - margin); chat_input->set_size(s.width(), font()->height()); } diff --git a/src/client/chat.h b/src/client/chat.h index 41837c5..61f5bd1 100644 --- a/src/client/chat.h +++ b/src/client/chat.h @@ -48,6 +48,10 @@ private: ui::Text chat_log; ui::ScrollPane *chat_scrollpane; + + ui::Text chat_players; + ui::ScrollPane *chat_playerpane; + ui::InputBox *chat_input; typedef std::deque History; diff --git a/src/client/client.h b/src/client/client.h index fd762c6..2de731d 100644 --- a/src/client/client.h +++ b/src/client/client.h @@ -98,17 +98,17 @@ private: Client *client(); -inline ClientExt *ext_client(core::Entity *entity) +inline ClientExt *ext_client(const core::Entity *entity) { return static_cast(entity->extension(core::Extension::Client)); } -inline SoundExt *ext_sound(core::Entity *entity) +inline SoundExt *ext_sound(const core::Entity *entity) { return static_cast(entity->extension(core::Extension::Sound)); } -inline render::RenderExt *ext_render(core::Entity *entity) +inline render::RenderExt *ext_render(const core::Entity *entity) { return static_cast(entity->extension(core::Extension::Render)); } diff --git a/src/client/hud.cc b/src/client/hud.cc index c42431c..3a7601b 100644 --- a/src/client/hud.cc +++ b/src/client/hud.cc @@ -285,7 +285,7 @@ void HUD::draw() } */ - core::Entity *target = targets::current(); + const core::Entity *target = targets::current(); std::stringstream strdistance; if (target) { diff --git a/src/client/infowidget.cc b/src/client/infowidget.cc index cf7c684..3081b8d 100644 --- a/src/client/infowidget.cc +++ b/src/client/infowidget.cc @@ -44,7 +44,7 @@ DevInfoWidget::DevInfoWidget(ui::Widget *parent) : ui::Widget(parent) void DevInfoWidget::draw() { std::stringstream textstream; - core::Entity *target = targets::current(); + const core::Entity *target = targets::current(); float d = 0; textstream << "^Ncore ^B"; diff --git a/src/client/input.cc b/src/client/input.cc index e8f0725..16ba048 100644 --- a/src/client/input.cc +++ b/src/client/input.cc @@ -583,7 +583,7 @@ void key_released(Key *key) // note: mouse button can double as an action key if ((key->sym() == 512 + SDL_BUTTON_LEFT) && targets::hover() && (key->waspressed() <= (input_mousedelay->value() / 1000.0f))) { // hovering target selected - targets::select_target(targets::hover()); + targets::set_target(targets::hover()); } if (key->action()) { diff --git a/src/client/map.cc b/src/client/map.cc index 7a6fedc..34dcb40 100644 --- a/src/client/map.cc +++ b/src/client/map.cc @@ -32,8 +32,13 @@ Map::Map(ui::Widget *parent) : ui::Window(parent) map_targetlabel->set_border(false); map_targetlabel->set_font(ui::root()->font_large()); map_targetlabel->set_alignment(ui::AlignCenter); + + map_scrollpane = new ui::ScrollPane(this, map_infotext); + map_scrollpane->set_background(false); + map_scrollpane->set_border(false); + map_scrollpane->set_alignment(ui::AlignTop); - map_target = 0; + set_target(0); map_hover = 0; hide(); } @@ -68,14 +73,29 @@ void Map::toggle() show(); } +void Map::resize() +{ + const float fontmargin = map_targetlabel->font()->height(); + + // resize label + map_targetlabel->set_size(width() - fontmargin * 2.0f, fontmargin); + map_targetlabel->set_location(fontmargin, fontmargin); + + // resize infotext pane + map_scrollpane->set_size(width() - ui::UI::elementsize.width() * 1.5f - fontmargin * 3.0f, + height() - ui::UI::elementsize.height() * 2.0f - fontmargin * 3.0f); + map_scrollpane->set_location(ui::UI::elementsize.width() * 1.5f + fontmargin * 2.0f, fontmargin * 3.0f); +} + void Map::draw() { - const float margin = font()->width() * 2.0f; - const float s = ui::UI::elementsize.width() * 2.0f; + const float fontmargin = map_targetlabel->font()->height(); + const float s = ui::UI::elementsize.width() * 1.5f; + const float blue = 0.8f; const float gridsize = 16; - core::Entity *entity; + const core::Entity *entity; const core::Entity *current_target = map_target; map_target = 0; @@ -84,8 +104,8 @@ void Map::draw() math::Vector2f v(global_location()); math::Vector2f l; - v[0] += margin; - v[1] += (height() - s - 2.0f * margin) * 0.5f; + v[0] += fontmargin; + v[1] += fontmargin + (height() - s) * 0.5f; map_hover = 0; gl::color(0, 0, blue); @@ -147,20 +167,20 @@ void Map::draw() if (draw_icon) { if (entity->type() == core::Entity::Globe) { if (entity->flag_is_set(core::Entity::Bright)) { - if (texture_current != texture_bright) { + if (texture_current != texture_bright) { gl::end(); texture_current = render::Textures::bind(texture_bright); gl::begin(gl::Quads); } } else { - if (texture_current != texture_globe) { + if (texture_current != texture_globe) { gl::end(); texture_current = render::Textures::bind(texture_globe); gl::begin(gl::Quads); } } } else { - if (texture_current != texture_entity) { + if (texture_current != texture_entity) { gl::end(); texture_current = render::Textures::bind(texture_entity); gl::begin(gl::Quads); @@ -224,13 +244,42 @@ void Map::draw() gl::end(); gl::disable(GL_TEXTURE_2D); + 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())) { + set_target(map_target); + } +} + +void Map::set_target(const core::Entity *entity) { + + map_target = entity; + map_infotimestamp = 0; + map_inforecord = 0; + map_infotext.clear(); + if (map_target) { - map_targetlabel->set_size(width() - s - margin * 3.0f, map_targetlabel->font()->height() * 2.0f); - map_targetlabel->set_location(s + margin * 2.0f, 4); + // set title label to target name map_targetlabel->set_text(map_target->name()); map_targetlabel->show(); + + map_inforecord = map_target->info(); + + if (map_inforecord) { + for (core::Info::Text::const_iterator it = map_inforecord->text().begin(); it != map_inforecord->text().end(); it++) { + map_infotext.push_back((*it)); + } + map_infotimestamp = map_inforecord->timestamp(); + } else { + map_infotext.push_back("Information is not available"); + } + + map_scrollpane->show(); } else { map_targetlabel->hide(); + map_scrollpane->hide(); } } @@ -240,9 +289,8 @@ bool Map::on_keypress(const int key, const unsigned int modifier) if (hover()) { core::Entity *target = core::localplayer()->zone()->find_entity(hover()); if (targets::is_valid_map_target(target)) { - map_target = target; - targets::select_target(map_target); - //audio::play("ui/target"); + set_target(target); + targets::set_target(map_target); } } return true; diff --git a/src/client/map.h b/src/client/map.h index 1fc1547..e0d8a2d 100644 --- a/src/client/map.h +++ b/src/client/map.h @@ -7,9 +7,11 @@ #ifndef __INCLUDED_CLIENT_MAP_H__ #define __INCLUDED_CLIENT_MAP_H__ -#include "ui/window.h" -#include "ui/label.h" #include "core/entity.h" +#include "core/info.h" +#include "ui/label.h" +#include "ui/scrollpane.h" +#include "ui/window.h" namespace client { @@ -24,6 +26,9 @@ public: return map_hover; } + /// set the map target + void set_target(const core::Entity *entity); + /// toggle the map window void toggle(); @@ -37,12 +42,19 @@ public: virtual bool on_keypress(const int key, const unsigned int modifier); protected: + virtual void resize(); + virtual void draw(); + ui::Label *map_targetlabel; + ui::ScrollPane *map_scrollpane; + unsigned int map_hover; + const core::Entity *map_target; - core::Entity *map_target; - ui::Label *map_targetlabel; + const core::Info *map_inforecord; + unsigned long map_infotimestamp; + ui::Text map_infotext; }; diff --git a/src/client/playerview.cc b/src/client/playerview.cc index 7ec8031..578e97f 100644 --- a/src/client/playerview.cc +++ b/src/client/playerview.cc @@ -146,7 +146,6 @@ void PlayerView::show_menu(const std::string & args) void PlayerView::resize() { - //const float largemargin = ui::UI::elementsize.width() * 0.25; const float smallmargin = ui::UI::elementsize.height(); set_size(parent()->size()); @@ -166,9 +165,6 @@ void PlayerView::resize() view_notify->set_geometry(view_map->location(), view_map->size()); // reposition labels - //label_viewname->set_size(ui::UI::elementsize.width() * 1.5f, ui::UI::elementsize.height()); - //label_viewname->set_location(smallmargin, smallmargin * 0.5f); - label_viewname->set_size(ui::UI::elementsize.width() * 1.5f, ui::UI::elementsize.height()); label_viewname->set_location(width() - label_viewname->width() - smallmargin, height() - label_viewname->height() - smallmargin * 0.5f); } diff --git a/src/client/targets.cc b/src/client/targets.cc index cc7f29f..46643bb 100644 --- a/src/client/targets.cc +++ b/src/client/targets.cc @@ -38,9 +38,9 @@ const float TARGETBOXRADIUS = 0.025f; unsigned int current_target_id = 0; unsigned int current_hover = 0; -core::Entity *current_target = 0; +const core::Entity *current_target = 0; -bool is_valid_hud_target(core::Entity *entity) +bool is_valid_hud_target(const core::Entity *entity) { if (entity->serverside()) { return false; @@ -53,7 +53,7 @@ bool is_valid_hud_target(core::Entity *entity) } } -bool is_valid_map_target(core::Entity *entity) +bool is_valid_map_target(const core::Entity *entity) { if (entity->serverside()) { return false; @@ -68,7 +68,7 @@ bool is_valid_map_target(core::Entity *entity) } } -core::Entity* current() +const core::Entity* current() { return current_target; } @@ -83,7 +83,7 @@ unsigned int hover() return current_hover; } -void select_target(core::Entity *entity) +void set_target(const core::Entity *entity) { current_target = entity; if (entity) { @@ -94,7 +94,7 @@ void select_target(core::Entity *entity) } } -void select_target(unsigned int id) +void set_target(unsigned int id) { if (!core::localcontrol()) return; @@ -105,7 +105,7 @@ void select_target(unsigned int id) core::Entity *entity = zone->find_entity(id); if (entity && is_valid_hud_target(entity)) - select_target(entity); + set_target(entity); } void func_target_next(std::string const &args) @@ -154,7 +154,7 @@ void func_target_next(std::string const &args) } if (it != zone->content().end()) { - select_target((*it)); + set_target((*it)); } else { current_target = 0; current_target_id = 0; @@ -206,7 +206,7 @@ void func_target_prev(std::string const &args) } if (rit != zone->content().rend()) { - select_target((*rit)); + set_target((*rit)); } else { current_target = 0; current_target_id = 0; @@ -225,12 +225,12 @@ void func_target_center(std::string const &args) return; // this is essentialy the hover algorithm with the cursor in the center - core::Entity *new_target = 0; + const core::Entity *new_target = 0; math::Vector3f center = render::Camera::eye() + render::Camera::axis().forward() * (render::FRUSTUMFRONT + 0.001); float smallest_d = -1; - for (core::Zone::Content::iterator it = core::localcontrol()->zone()->content().begin(); it != core::localcontrol()->zone()->content().end(); it++) { - core::Entity *entity = (*it); + for (core::Zone::Content::const_iterator it = core::localcontrol()->zone()->content().begin(); it != core::localcontrol()->zone()->content().end(); it++) { + const core::Entity *entity = (*it); math::Vector3f v(entity->location() - render::Camera::eye()); v.normalize(); @@ -249,7 +249,7 @@ void func_target_center(std::string const &args) } if (new_target) - select_target(new_target); + set_target(new_target); } void reset() diff --git a/src/client/targets.h b/src/client/targets.h index 5a3a655..e66ff97 100644 --- a/src/client/targets.h +++ b/src/client/targets.h @@ -25,16 +25,16 @@ void shutdown(); void reset(); /// return true if the entity is a legal hud target -bool is_valid_hud_target(core::Entity *entity); +bool is_valid_hud_target(const core::Entity *entity); /// return true if the entity is a legal map target -bool is_valid_map_target(core::Entity *entity); +bool is_valid_map_target(const core::Entity *entity); /// render targets and sounds void frame(); /// currently selected target, 0 if there is none -core::Entity *current(); +const core::Entity *current(); /// id of the currently selected target, 0 if there is none unsigned int current_id(); @@ -43,10 +43,10 @@ unsigned int current_id(); unsigned int hover(); /// target a specific entity -void select_target(unsigned int id); +void set_target(unsigned int id); /// target a specific entity -void select_target(core::Entity *entity); +void set_target(const core::Entity *entity); } diff --git a/src/client/trademenu.cc b/src/client/trademenu.cc index dcab2f1..c60791f 100644 --- a/src/client/trademenu.cc +++ b/src/client/trademenu.cc @@ -12,15 +12,19 @@ namespace client { -TradeMenu::TradeMenu(ui::Widget *parent, const char * label) : ui::Window(parent) +TradeMenu::TradeMenu(ui::Window *parent, const char * label) : ui::Window(parent) { set_border(false); - set_background(false); + set_background(false); if (label) set_label(label); else set_label("trademenu"); + menu_tradewindow = new ui::Window(this); + menu_tradewindow->set_label("tradewindow"); + menu_tradewindow->set_border(true); + hide(); } diff --git a/src/client/trademenu.h b/src/client/trademenu.h index baf3544..03b5077 100644 --- a/src/client/trademenu.h +++ b/src/client/trademenu.h @@ -19,8 +19,15 @@ class TradeMenu : public ui::Window { public: /// create a new menu - TradeMenu(ui::Widget *parent, const char * label = 0); + TradeMenu(ui::Window *parent, const char * label = 0); ~TradeMenu(); + +protected: + /// resize event + virtual void resize(); + +private: + ui::Window *menu_tradewindow; }; } diff --git a/src/core/commandbuffer.cc b/src/core/commandbuffer.cc index 00a3486..3c7fc35 100644 --- a/src/core/commandbuffer.cc +++ b/src/core/commandbuffer.cc @@ -79,7 +79,7 @@ void func_list_info(std::string const &args) return; } - con_print << "Unkown info record '" << typestr << "'" << std::endl; + con_print << "Unknown info record '" << typestr << "'" << std::endl; } else { // two arguments @@ -97,7 +97,7 @@ void func_list_info(std::string const &args) return; } - con_print << "Unkown info record '" << typestr << "' for type '" << typestr << "'" << std::endl; + con_print << "Unknown info record '" << labelstr << "' for type '" << typestr << "'" << std::endl; } } diff --git a/src/core/entity.h b/src/core/entity.h index 1bc93a1..5ddce3a 100644 --- a/src/core/entity.h +++ b/src/core/entity.h @@ -92,7 +92,7 @@ public: } /// pointer to the model, is used client-side - inline model::Model * model() { + inline model::Model * model() const { return entity_model; } @@ -197,23 +197,31 @@ public: entity_color_second.assign(color); } - /// set dirty flag + /** + * @brief set dirty flag + * setting the dirty flag will cause the server to broadcast changes + * to the clients. + */ inline void set_dirty(const bool dirty = true) { entity_dirty = dirty; } - /// mark the entity as destroyed + /** + * @brief mark the entity as destroyed + * die() should be called by the game module when it needs to destroy an entity, + * the game server will broadcast the delete event to the clients. + * The game module should not delete an entity directly. + */ virtual void die(); - /// runs one game frame for the entity /** + * @brief runs one game frame for the entity * The default implementation does nothing */ virtual void frame(float seconds); /** * @brief set the zone the entity is currently in - * * this fuction removes the entity from its previous zone * and removes it to the new one, if it is not 0 */ @@ -552,8 +560,8 @@ public: /// set afterburner/reverse void set_afterburner(float afterburner); - /// runs one game frame for the entity /** + * @brief runs one game frame for the entity * The default implementation will set direction() and thrust() to the desired targets * and calls its parent frame() funcion. */ @@ -564,18 +572,27 @@ public: protected: /* target_ variables can be set by the client */ - /// target thrust as set by the client + + /** + * @brief target thrust as set by the client + */ float target_thrust; - /// target direction as set by the client - /** target_direction must be in the [-1, 1] range + + /** + * @brief target direction as set by the client + * target_direction must be in the [-1, 1] range */ float target_direction; - /// target pitch as set by the client - /** target_pitch must be in the [-1, 1] range + + /** + * @brief target pitch as set by the client + * target_pitch must be in the [-1, 1] range */ float target_pitch; - /// target roll as set by the client - /** target_roll must be in the [-1, 1] range + + /** + * @brief target roll as set by the client + * target_roll must be in the [-1, 1] range */ float target_roll; diff --git a/src/core/gameconnection.cc b/src/core/gameconnection.cc index 46b50f5..ce33dc6 100644 --- a/src/core/gameconnection.cc +++ b/src/core/gameconnection.cc @@ -105,7 +105,7 @@ Info *GameConnection::info(unsigned int id) return info; } else { info = new Info(id); - info->text().push_back("Requesting information..."); + info->add_text("Requesting information..."); } @@ -113,12 +113,11 @@ Info *GameConnection::info(unsigned int id) if (connection_network) { //con_debug << "Requesting info for " << info->id() << std::endl; info->set_timestamp(connection_timestamp); - info->set_id(0); - + connection_network->send_info_request(info); connection_network->transmit(); } else { - info->text().push_back("^RNot connected."); + info->add_text("^RNot connected."); info->set_timestamp(0); } return info; @@ -151,21 +150,18 @@ Info *GameConnection::info(const std::string &type, const std::string &label) return info; } else { // create a new info record and set the label - info = new Info(infotype); - info->set_label(label); - info->text().push_back("Requesting information..."); + info = new Info(infotype, label); + info->add_text("Requesting information..."); } // send an information request to the server if (connection_network) { //con_debug << "Requesting info for " << info->type()->label() << ":" << info->label() << std::endl; info->set_timestamp(connection_timestamp); - info->set_id(0); - connection_network->send_info_request(info); connection_network->transmit(); } else { - info->text().push_back("^RNot connected."); + info->add_text("^RNot connected."); info->set_timestamp(0); } return info; diff --git a/src/core/info.h b/src/core/info.h index 8b9a89b..8822f2f 100644 --- a/src/core/info.h +++ b/src/core/info.h @@ -19,14 +19,14 @@ namespace core { /** - * @brief an information record type + * @brief an information card category * The InfoType groups information records of the same type */ class InfoType : public Label { public: /** - * @brief create a new information record type + * @brief create a new information card category * The constructor automaticly adds the instance to the registry */ InfoType(const char* label); @@ -49,7 +49,7 @@ private: }; // class InfoType /** - * @brief an information record + * @brief an information card * An information record holds extended information about a specific entity or item class. * This information is exchanged between server and the client, and can be used to build * HUD widgets. @@ -61,19 +61,19 @@ public: typedef std::deque Text; /** - * @brief create a new server-side information record + * @brief create a new server-side information card * This constructor assigns an id */ Info(const InfoType *type); /** - * @brief create a new client-side information record + * @brief create a new client-side information card * This constructor doesn not assign an id */ Info(const InfoType *type, const std::string & label); /** - * @brief create a new client-side information record + * @brief create a new client-side information card */ Info(const unsigned int id); @@ -107,7 +107,7 @@ public: } /// text description - inline Text & text() { + inline const Text & text() const { return info_text; } diff --git a/src/core/inventory.h b/src/core/inventory.h index a451dc7..da30715 100644 --- a/src/core/inventory.h +++ b/src/core/inventory.h @@ -47,12 +47,12 @@ public: /** * @brief removes all items from the inventory and delete them - */ + */ void clear(); /** - * @brief search the inventory for a specific item type - */ + * @brief search the inventory for a specific item type + */ Item *find(const Info *info); private: diff --git a/src/core/item.h b/src/core/item.h index 21eae87..397d259 100644 --- a/src/core/item.h +++ b/src/core/item.h @@ -19,6 +19,8 @@ namespace core class Item { public: + enum Flags { Mount = 1, Trade = 2 }; + Item(const Info *info); ~Item(); @@ -31,10 +33,15 @@ public: inline int amount() const { return item_amount; } /** - * @brief information record + * @brief information card */ inline const Info *info() const { return item_info; } + /** + * @brief flags + */ + inline int flags() const { return item_flags; } + /* ---- mutators ----------------------------------------------- */ /** @@ -45,6 +52,8 @@ public: private: const Info *item_info; int item_amount; + + int item_flags; }; } // namespace core diff --git a/src/math/functions.cc b/src/math/functions.cc index c4b832c..7fb40be 100644 --- a/src/math/functions.cc +++ b/src/math/functions.cc @@ -66,10 +66,10 @@ float sgnf(float value) { if (value < 0) return -1; - else if (value == 0) - return 0; + else if (value > 0) + return 1; - return 1; + return 0; } } // namespace math diff --git a/src/math/functions.h b/src/math/functions.h index c301969..5a53d44 100644 --- a/src/math/functions.h +++ b/src/math/functions.h @@ -31,7 +31,7 @@ int max(int a, int b); /** The value returned will be in the interval [0-max] * @param max the maximum value returned **/ -float randomf(const float max = 1); +float randomf(const float max = 1.0f); /// returns a random integer /** The value returned will be in the interval [0-(max-1)] @@ -58,12 +58,9 @@ inline void clamp(float &value, const float min = 0.0f, const float max = 1.0f) } /// return the absolute value of a float -inline float absf(float f) +inline float absf(const float f) { - if (f < 0) - return -f; - else - return f; + return ( f < 0.0f ? -f : f ); } } // namespace math diff --git a/src/render/draw.cc b/src/render/draw.cc index 9e6bb5a..7d0242d 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -1344,7 +1344,7 @@ void draw(float seconds) } // draw HUD target world space geometry, like dock indicators -void draw_target(core::Entity *entity) +void draw_target(const core::Entity *entity) { model::Model *model = entity->model(); if (!model) diff --git a/src/render/draw.h b/src/render/draw.h index b13c7b0..54e8507 100644 --- a/src/render/draw.h +++ b/src/render/draw.h @@ -18,7 +18,7 @@ namespace render /// draw the world void draw(float seconds); -void draw_target(core::Entity *entity); +void draw_target(const core::Entity *entity); /// reset void reset(); diff --git a/src/render/tgafile.cc b/src/render/tgafile.cc index db54645..10082e6 100644 --- a/src/render/tgafile.cc +++ b/src/render/tgafile.cc @@ -270,20 +270,20 @@ void TGA::save(const char *filename, Image & image) pixel_data[3] = *image[index+3]; if (block_length == 0) { + // if the block is empty, copy the first pixel memcpy(block_data, pixel_data, image.channels()); block_length++; + // by default, the block is not compressed compress = false; } else { + // if the current block is not compressed if (!compress) { - - // uncompressed block and pixel_data differs from the last pixel + // if the previous pixel differs from the pixel data if (memcmp(&block_data[(block_length-1)*image.channels()], pixel_data, image.channels()) != 0) { // append pixel memcpy(&block_data[block_length*image.channels()], pixel_data, image.channels()); - block_length++; } else { - // uncompressed block and pixel data is identical if (block_length > 1) { // write the uncompressed block @@ -292,17 +292,16 @@ void TGA::save(const char *filename, Image & image) ofs.write((char *)block_data, (block_length - 1) * image.channels()); block_length = 1; } + // create a commpressed block memcpy(block_data, pixel_data, image.channels()); block_length++; compress = true; } - + // if the current block is compressed } else { - - // compressed block and pixel data are identical + // if the previous pixel and the pixel data are identical if (memcmp(block_data, pixel_data, image.channels()) == 0) { block_length++; - } else { // compressed block and pixel data differs diff --git a/src/ui/container.cc b/src/ui/container.cc index 04e1ec2..31d7549 100644 --- a/src/ui/container.cc +++ b/src/ui/container.cc @@ -45,11 +45,7 @@ void Container::resize() void Container::draw_border() { - if (focus()) { - paint::color(palette()->foreground()); - } else { - paint::color(palette()->border()); - } + paint::color(palette()->foreground()); paint::border(global_location(), size()); } diff --git a/src/ui/widget.cc b/src/ui/widget.cc index 2e2f291..39fbe98 100644 --- a/src/ui/widget.cc +++ b/src/ui/widget.cc @@ -321,7 +321,21 @@ bool Widget::has_input_focus() const /* -- event distributors ------------------------------------------- */ +bool Widget::event_emit(Widget *sender, const Event event, void *data) +// Unhandled events are sent to the parent widget +{ + if (on_emit(sender, event, data)) { + return true; + } else if (parent()) { + return (parent()->on_emit(sender, event, data)); + } else { + return false; + } +} + + bool Widget::event_key(const bool pressed, const int key, const unsigned int modifier) +// Unhandled key events are sent to the parent widget { bool handled = false; @@ -400,6 +414,11 @@ bool Widget::on_keyrelease(const int key, const unsigned int modifier) return false; } +bool Widget::on_emit(Widget *sender, const Event event, void *data) +{ + return false; +} + /* -- draw functions ----------------------------------------------- */ void Widget::draw_debug_border() diff --git a/src/ui/widget.h b/src/ui/widget.h index 1f87695..50678fa 100644 --- a/src/ui/widget.h +++ b/src/ui/widget.h @@ -27,6 +27,9 @@ class Widget { public: + /// types of custom events a widget can emit + enum Event {EventNone = 0, EventSelected = 1}; + /// create a new widget Widget(Widget *parent = 0); @@ -196,22 +199,45 @@ public: /// enable or disable widget border void set_border(bool border = true); - ///enable or disable widget background + /// 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 ----------------------------------- */ + /* -- event distributors --------------------------------------- */ - /// distribute resize event - virtual void event_resize(); - - /// distribute draw event - virtual void event_draw(); + /** + * @brief calls the resize event handler and sends the event to all child widgets + * @see resize + **/ + void event_resize(); + + /** + * @brief calls the draw event handler and sends the event to all child widgets + * @see draw + **/ + void event_draw(); - /// distribute keyboard events - virtual bool event_key(const bool pressed, const int key, const unsigned int modifier); + /** + * @brief calls the key event handlers and sends unhandled keys to the parent widget + * @see on_keypress + * @see on_keyrelease + **/ + bool event_key(const bool pressed, const int key, const unsigned int modifier); - /// distribute mouse movement events - virtual bool event_mouse(const math::Vector2f &cursor); + /** + * @brief calls the mouse event handlers and sends unhandled keys to the parent widget + * @see on_mousemove + * @see on_mouseover + **/ + bool event_mouse(const math::Vector2f &cursor); + + /** + * @brief calls the custom event handler and sends unhandled events to the parent widget + * @see on_event + **/ + bool event_emit(Widget *sender, const Event event, void *data = 0); protected: /// type definition for child widgets @@ -289,6 +315,9 @@ protected: /// called when the widget receives a key release virtual bool on_keyrelease(const int key, const unsigned int modifier); + + /// called when the widget receives a custom event + virtual bool on_emit(Widget *sender, const Event event, void *data=0); /* -- draw functions --------------------------------------- */ -- cgit v1.2.3