Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/client/Makefile.am8
-rw-r--r--src/client/buymenu.cc91
-rw-r--r--src/client/buymenu.h9
-rw-r--r--src/client/chat.cc30
-rw-r--r--src/client/chat.h4
-rw-r--r--src/client/client.h6
-rw-r--r--src/client/hud.cc2
-rw-r--r--src/client/infowidget.cc2
-rw-r--r--src/client/input.cc2
-rw-r--r--src/client/map.cc76
-rw-r--r--src/client/map.h20
-rw-r--r--src/client/playerview.cc4
-rw-r--r--src/client/targets.cc26
-rw-r--r--src/client/targets.h10
-rw-r--r--src/client/trademenu.cc8
-rw-r--r--src/client/trademenu.h9
-rw-r--r--src/core/commandbuffer.cc4
-rw-r--r--src/core/entity.h43
-rw-r--r--src/core/gameconnection.cc16
-rw-r--r--src/core/info.h14
-rw-r--r--src/core/inventory.h6
-rw-r--r--src/core/item.h11
-rw-r--r--src/math/functions.cc6
-rw-r--r--src/math/functions.h9
-rw-r--r--src/render/draw.cc2
-rw-r--r--src/render/draw.h2
-rw-r--r--src/render/tgafile.cc15
-rw-r--r--src/ui/container.cc6
-rw-r--r--src/ui/widget.cc19
-rw-r--r--src/ui/widget.h51
30 files changed, 332 insertions, 179 deletions
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<std::string> 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<ClientExt *>(entity->extension(core::Extension::Client));
}
-inline SoundExt *ext_sound(core::Entity *entity)
+inline SoundExt *ext_sound(const core::Entity *entity)
{
return static_cast<SoundExt *>(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<render::RenderExt *>(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<std::string> 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 --------------------------------------- */