aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/client.cpp73
-rw-r--r--src/client.h28
-rw-r--r--src/game.cpp516
-rw-r--r--src/hud.cpp291
-rw-r--r--src/hud.h116
-rw-r--r--src/player.h18
-rw-r--r--src/scriptapi_object.cpp268
-rw-r--r--src/scriptapi_object.h19
-rw-r--r--src/server.cpp180
-rw-r--r--src/server.h20
11 files changed, 740 insertions, 790 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 62bb42b9e..7ddeeb02e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -327,6 +327,7 @@ set(minetest_SRCS
particles.cpp
clientobject.cpp
chat.cpp
+ hud.cpp
guiMainMenu.cpp
guiKeyChangeMenu.cpp
guiMessageMenu.cpp
diff --git a/src/client.cpp b/src/client.cpp
index 1f8b9caca..03a710599 100644
--- a/src/client.cpp
+++ b/src/client.cpp
@@ -2042,35 +2042,35 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
}
else if(command == TOCLIENT_HUDADD)
{
- std::string datastring((char*)&data[2], datasize-2);
+ std::string datastring((char *)&data[2], datasize - 2);
std::istringstream is(datastring, std::ios_base::binary);
- u32 id = readU32(is);
- u8 type = readU8(is);
- core::vector2df pos = readV2F1000(is);
- std::string name = deSerializeString(is);
- core::vector2df scale = readV2F1000(is);
- std::string text = deSerializeString(is);
- u32 number = readU32(is);
- u32 item = readU32(is);
- u32 dir = readU32(is);
+ u32 id = readU32(is);
+ u8 type = readU8(is);
+ v2f pos = readV2F1000(is);
+ std::string name = deSerializeString(is);
+ v2f scale = readV2F1000(is);
+ std::string text = deSerializeString(is);
+ u32 number = readU32(is);
+ u32 item = readU32(is);
+ u32 dir = readU32(is);
ClientEvent event;
event.type = CE_HUDADD;
- event.hudadd.id = id;
- event.hudadd.type = type;
- event.hudadd.pos = new v2f(pos);
- event.hudadd.name = new std::string(name);
- event.hudadd.scale = new v2f(scale);
- event.hudadd.text = new std::string(text);
+ event.hudadd.id = id;
+ event.hudadd.type = type;
+ event.hudadd.pos = new v2f(pos);
+ event.hudadd.name = new std::string(name);
+ event.hudadd.scale = new v2f(scale);
+ event.hudadd.text = new std::string(text);
event.hudadd.number = number;
- event.hudadd.item = item;
- event.hudadd.dir = dir;
+ event.hudadd.item = item;
+ event.hudadd.dir = dir;
m_client_event_queue.push_back(event);
}
else if(command == TOCLIENT_HUDRM)
{
- std::string datastring((char*)&data[2], datasize-2);
+ std::string datastring((char *)&data[2], datasize - 2);
std::istringstream is(datastring, std::ios_base::binary);
u32 id = readU32(is);
@@ -2081,30 +2081,31 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
m_client_event_queue.push_back(event);
}
else if(command == TOCLIENT_HUDCHANGE)
- {
- std::string datastring((char*)&data[2], datasize-2);
+ {
+ std::string sdata;
+ v2f v2fdata;
+ u32 intdata = 0;
+
+ std::string datastring((char *)&data[2], datasize - 2);
std::istringstream is(datastring, std::ios_base::binary);
- u32 id = readU32(is);
- u8 stat = readU8(is);
- core::vector2df v2fdata;
- std::string sdata;
- u32 data = 0;
- if(stat == 0 || stat == 2) {
+ u32 id = readU32(is);
+ u8 stat = (HudElementStat)readU8(is);
+
+ if (stat == HUD_STAT_POS || stat == HUD_STAT_SCALE)
v2fdata = readV2F1000(is);
- } else if(stat == 1 || stat == 3) {
+ else if (stat == HUD_STAT_NAME || stat == HUD_STAT_TEXT)
sdata = deSerializeString(is);
- } else {
- data = readU32(is);
- }
-
+ else
+ intdata = readU32(is);
+
ClientEvent event;
event.type = CE_HUDCHANGE;
- event.hudchange.id = id;
- event.hudchange.stat = stat;
+ event.hudchange.id = id;
+ event.hudchange.stat = (HudElementStat)stat;
event.hudchange.v2fdata = new v2f(v2fdata);
- event.hudchange.sdata = new std::string(sdata);
- event.hudchange.data = data;
+ event.hudchange.sdata = new std::string(sdata);
+ event.hudchange.data = intdata;
m_client_event_queue.push_back(event);
}
else
diff --git a/src/client.h b/src/client.h
index 696385a9a..f59588680 100644
--- a/src/client.h
+++ b/src/client.h
@@ -186,8 +186,8 @@ struct ClientEvent
f32 camera_point_target_z;
} deathscreen;
struct{
- std::string* formspec;
- std::string* formname;
+ std::string *formspec;
+ std::string *formname;
} show_formspec;
struct{
} textures_updated;
@@ -221,24 +221,24 @@ struct ClientEvent
u32 id;
} delete_particlespawner;
struct{
- u32 id;
- u8 type;
- v2f* pos;
- std::string* name;
- v2f* scale;
- std::string* text;
- u32 number;
- u32 item;
- u32 dir;
+ u32 id;
+ u8 type;
+ v2f *pos;
+ std::string *name;
+ v2f *scale;
+ std::string *text;
+ u32 number;
+ u32 item;
+ u32 dir;
} hudadd;
struct{
u32 id;
} hudrm;
struct{
u32 id;
- u8 stat;
- v2f* v2fdata;
- std::string* sdata;
+ HudElementStat stat;
+ v2f *v2fdata;
+ std::string *sdata;
u32 data;
} hudchange;
};
diff --git a/src/game.cpp b/src/game.cpp
index 046b7bdbf..a2d94ac0a 100644
--- a/src/game.cpp
+++ b/src/game.cpp
@@ -59,6 +59,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "subgame.h"
#include "quicktune_shortcutter.h"
#include "clientmap.h"
+#include "hud.h"
#include "sky.h"
#include "sound.h"
#if USE_SOUND
@@ -230,296 +231,6 @@ public:
};
/*
- Item draw routine
-*/
-void draw_item(video::IVideoDriver *driver, gui::IGUIFont *font, IGameDef *gamedef,
- v2s32 upperleftpos, s32 imgsize, s32 itemcount,
- InventoryList *mainlist, u16 selectitem, unsigned short int direction)
- //NOTE: selectitem = 0 -> no selected; selectitem 1-based
- //NOTE: direction: 0-> left-right, 1-> right-left, 2->top-bottom, 3->bottom-top
-{
- s32 padding = imgsize/12;
- s32 height = imgsize + padding*2;
- s32 width = itemcount*(imgsize+padding*2);
- if(direction == 2 or direction == 3){
- width = imgsize + padding*2;
- height = itemcount*(imgsize+padding*2);
- }
- s32 fullimglen = imgsize + padding*2;
-
- // Position of upper left corner of bar
- v2s32 pos = upperleftpos;
-
- // Draw background color
- /*core::rect<s32> barrect(0,0,width,height);
- barrect += pos;
- video::SColor bgcolor(255,128,128,128);
- driver->draw2DRectangle(bgcolor, barrect, NULL);*/
-
- core::rect<s32> imgrect(0,0,imgsize,imgsize);
-
- for(s32 i=0; i<itemcount; i++)
- {
- const ItemStack &item = mainlist->getItem(i);
-
- v2s32 steppos;
- if(direction == 1){
- steppos = v2s32(-(padding+i*fullimglen), padding);
- } else if(direction == 2) {
- steppos = v2s32(padding, padding+i*fullimglen);
- } else if(direction == 3) {
- steppos = v2s32(padding, -(padding+i*fullimglen));
- } else {
- steppos = v2s32(padding+i*fullimglen, padding);
- }
- core::rect<s32> rect = imgrect + pos
- + steppos;
-
- if(selectitem == (i+1))
- {
- video::SColor c_outside(255,255,0,0);
- //video::SColor c_outside(255,0,0,0);
- //video::SColor c_inside(255,192,192,192);
- s32 x1 = rect.UpperLeftCorner.X;
- s32 y1 = rect.UpperLeftCorner.Y;
- s32 x2 = rect.LowerRightCorner.X;
- s32 y2 = rect.LowerRightCorner.Y;
- // Black base borders
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x1 - padding, y1 - padding),
- v2s32(x2 + padding, y1)
- ), NULL);
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x1 - padding, y2),
- v2s32(x2 + padding, y2 + padding)
- ), NULL);
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x1 - padding, y1),
- v2s32(x1, y2)
- ), NULL);
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x2, y1),
- v2s32(x2 + padding, y2)
- ), NULL);
- /*// Light inside borders
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x1 - padding/2, y1 - padding/2),
- v2s32(x2 + padding/2, y1)
- ), NULL);
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x1 - padding/2, y2),
- v2s32(x2 + padding/2, y2 + padding/2)
- ), NULL);
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x1 - padding/2, y1),
- v2s32(x1, y2)
- ), NULL);
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x2, y1),
- v2s32(x2 + padding/2, y2)
- ), NULL);
- */
- }
-
- video::SColor bgcolor2(128,0,0,0);
- driver->draw2DRectangle(bgcolor2, rect, NULL);
- drawItemStack(driver, font, item, rect, NULL, gamedef);
- }
-}
-
-/*
- Statbar draw routine
-*/
-void draw_statbar(video::IVideoDriver *driver, gui::IGUIFont *font, IGameDef *gamedef,
- v2s32 upperleftpos, std::string texture, s32 count)
- //NOTE: selectitem = 0 -> no selected; selectitem 1-based
- //NOTE: direction: 0-> left-right, 1-> right-left, 2->top-bottom, 3->bottom-top
-{
- video::ITexture *stat_texture =
- gamedef->getTextureSource()->getTextureRaw(texture);
- if(stat_texture)
- {
- v2s32 p = upperleftpos;
- for(s32 i=0; i<count/2; i++)
- {
- core::dimension2di srcd(stat_texture->getOriginalSize());
- const video::SColor color(255,255,255,255);
- const video::SColor colors[] = {color,color,color,color};
- core::rect<s32> rect(0,0,srcd.Width,srcd.Height);
- rect += p;
- driver->draw2DImage(stat_texture, rect,
- core::rect<s32>(core::position2d<s32>(0,0), srcd),
- NULL, colors, true);
- p += v2s32(srcd.Width,0);
- }
- if(count % 2 == 1)
- {
- core::dimension2di srcd(stat_texture->getOriginalSize());
- const video::SColor color(255,255,255,255);
- const video::SColor colors[] = {color,color,color,color};
- core::rect<s32> rect(0,0,srcd.Width/2,srcd.Height);
- rect += p;
- srcd.Width /= 2;
- driver->draw2DImage(stat_texture, rect,
- core::rect<s32>(core::position2d<s32>(0,0), srcd),
- NULL, colors, true);
- p += v2s32(srcd.Width*2,0);
- }
- }
-}
-
-/*
- Hotbar draw routine
-*/
-void draw_hotbar(video::IVideoDriver *driver, gui::IGUIFont *font,
- IGameDef *gamedef,
- v2s32 centerlowerpos, s32 imgsize, s32 itemcount,
- Inventory *inventory, s32 halfheartcount, u16 playeritem)
-{
- InventoryList *mainlist = inventory->getList("main");
- if(mainlist == NULL)
- {
- errorstream<<"draw_hotbar(): mainlist == NULL"<<std::endl;
- return;
- }
-#if 0
- s32 padding = imgsize/12;
- //s32 height = imgsize + padding*2;
- s32 width = itemcount*(imgsize+padding*2);
-
- // Position of upper left corner of bar
- v2s32 pos = centerlowerpos - v2s32(width/2, imgsize+padding*2);
-
- // Draw background color
- /*core::rect<s32> barrect(0,0,width,height);
- barrect += pos;
- video::SColor bgcolor(255,128,128,128);
- driver->draw2DRectangle(bgcolor, barrect, NULL);*/
-
- core::rect<s32> imgrect(0,0,imgsize,imgsize);
-
- for(s32 i=0; i<itemcount; i++)
- {
- const ItemStack &item = mainlist->getItem(i);
-
- core::rect<s32> rect = imgrect + pos
- + v2s32(padding+i*(imgsize+padding*2), padding);
-
- if(playeritem == i)
- {
- video::SColor c_outside(255,255,0,0);
- //video::SColor c_outside(255,0,0,0);
- //video::SColor c_inside(255,192,192,192);
- s32 x1 = rect.UpperLeftCorner.X;
- s32 y1 = rect.UpperLeftCorner.Y;
- s32 x2 = rect.LowerRightCorner.X;
- s32 y2 = rect.LowerRightCorner.Y;
- // Black base borders
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x1 - padding, y1 - padding),
- v2s32(x2 + padding, y1)
- ), NULL);
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x1 - padding, y2),
- v2s32(x2 + padding, y2 + padding)
- ), NULL);
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x1 - padding, y1),
- v2s32(x1, y2)
- ), NULL);
- driver->draw2DRectangle(c_outside,
- core::rect<s32>(
- v2s32(x2, y1),
- v2s32(x2 + padding, y2)
- ), NULL);
- /*// Light inside borders
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x1 - padding/2, y1 - padding/2),
- v2s32(x2 + padding/2, y1)
- ), NULL);
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x1 - padding/2, y2),
- v2s32(x2 + padding/2, y2 + padding/2)
- ), NULL);
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x1 - padding/2, y1),
- v2s32(x1, y2)
- ), NULL);
- driver->draw2DRectangle(c_inside,
- core::rect<s32>(
- v2s32(x2, y1),
- v2s32(x2 + padding/2, y2)
- ), NULL);
- */
- }
-
- video::SColor bgcolor2(128,0,0,0);
- driver->draw2DRectangle(bgcolor2, rect, NULL);
- drawItemStack(driver, font, item, rect, NULL, gamedef);
- }
-#else
- s32 padding = imgsize/12;
- s32 width = itemcount*(imgsize+padding*2);
- v2s32 pos = centerlowerpos - v2s32(width/2, imgsize+padding*2);
- draw_item(driver, font, gamedef, pos, imgsize, itemcount,
- mainlist, playeritem + 1, 0);
-#endif
-#if 0
- /*
- Draw hearts
- */
- video::ITexture *heart_texture =
- gamedef->getTextureSource()->getTextureRaw("heart.png");
- if(heart_texture)
- {
- v2s32 p = pos + v2s32(0, -20);
- for(s32 i=0; i<halfheartcount/2; i++)
- {
- const video::SColor color(255,255,255,255);
- const video::SColor colors[] = {color,color,color,color};
- core::rect<s32> rect(0,0,16,16);
- rect += p;
- driver->draw2DImage(heart_texture, rect,
- core::rect<s32>(core::position2d<s32>(0,0),
- core::dimension2di(heart_texture->getOriginalSize())),
- NULL, colors, true);
- p += v2s32(16,0);
- }
- if(halfheartcount % 2 == 1)
- {
- const video::SColor color(255,255,255,255);
- const video::SColor colors[] = {color,color,color,color};
- core::rect<s32> rect(0,0,16/2,16);
- rect += p;
- core::dimension2di srcd(heart_texture->getOriginalSize());
- srcd.Width /= 2;
- driver->draw2DImage(heart_texture, rect,
- core::rect<s32>(core::position2d<s32>(0,0), srcd),
- NULL, colors, true);
- p += v2s32(16,0);
- }
- }
-#else
- draw_statbar(driver, font, gamedef, pos + v2s32(0, -20),
- "heart.png", halfheartcount);
-#endif
-}
-
-/*
Check if a node is pointable
*/
inline bool isPointableNode(const MapNode& n,
@@ -1103,14 +814,8 @@ void the_game(
// Calculate text height using the font
u32 text_height = font->getDimension(L"Random test string").Height;
- v2u32 screensize(0,0);
v2u32 last_screensize(0,0);
- screensize = driver->getScreenSize();
-
- const s32 hotbar_itemcount = 8;
- //const s32 hotbar_imagesize = 36;
- //const s32 hotbar_imagesize = 64;
- s32 hotbar_imagesize = 48;
+ v2u32 screensize = driver->getScreenSize();
/*
Draw "Loading" screen
@@ -1534,6 +1239,12 @@ void the_game(
LocalPlayer* player = client.getEnv().getLocalPlayer();
player->hurt_tilt_timer = 0;
player->hurt_tilt_strength = 0;
+
+ /*
+ HUD object
+ */
+ Hud hud(driver, guienv, font, text_height,
+ gamedef, player, &local_inventory);
for(;;)
{
@@ -1707,13 +1418,11 @@ void the_game(
v2s32 displaycenter(screensize.X/2,screensize.Y/2);
//bool screensize_changed = screensize != last_screensize;
- // Resize hotbar
- if(screensize.Y <= 800)
- hotbar_imagesize = 32;
- else if(screensize.Y <= 1280)
- hotbar_imagesize = 48;
- else
- hotbar_imagesize = 64;
+
+ // Update HUD values
+ hud.screensize = screensize;
+ hud.displaycenter = displaycenter;
+ hud.resizeHotbar();
// Hilight boxes collected during the loop and displayed
std::vector<aabb3f> hilightboxes;
@@ -2077,7 +1786,7 @@ void the_game(
{
s32 wheel = input->getMouseWheel();
u16 max_item = MYMIN(PLAYER_INVENTORY_SIZE-1,
- hotbar_itemcount-1);
+ hud.hotbar_itemcount-1);
if(wheel < 0)
{
@@ -2101,7 +1810,7 @@ void the_game(
const KeyPress *kp = NumberKey + (i + 1) % 10;
if(input->wasKeyDown(*kp))
{
- if(i < PLAYER_INVENTORY_SIZE && i < hotbar_itemcount)
+ if(i < PLAYER_INVENTORY_SIZE && i < hud.hotbar_itemcount)
{
new_playeritem = i;
@@ -2390,8 +2099,18 @@ void the_game(
}
else if (event.type == CE_HUDADD)
{
- HudElement* e = new HudElement;
- e->type = event.hudadd.type;
+ u32 id = event.hudadd.id;
+ size_t nhudelem = player->hud.size();
+ if (id > nhudelem || (id < nhudelem && player->hud[id])) {
+ delete event.hudadd.pos;
+ delete event.hudadd.name;
+ delete event.hudadd.scale;
+ delete event.hudadd.text;
+ continue;
+ }
+
+ HudElement *e = new HudElement;
+ e->type = (HudElementType)event.hudadd.type;
e->pos = *event.hudadd.pos;
e->name = *event.hudadd.name;
e->scale = *event.hudadd.scale;
@@ -2399,33 +2118,61 @@ void the_game(
e->number = event.hudadd.number;
e->item = event.hudadd.item;
e->dir = event.hudadd.dir;
- player->hud[event.hudadd.id] = e;
- delete(event.hudadd.pos);
- delete(event.hudadd.name);
- delete(event.hudadd.scale);
- delete(event.hudadd.text);
+
+ if (id == nhudelem)
+ player->hud.push_back(e);
+ else
+ player->hud[id] = e;
+
+ delete event.hudadd.pos;
+ delete event.hudadd.name;
+ delete event.hudadd.scale;
+ delete event.hudadd.text;
}
else if (event.type == CE_HUDRM)
{
- player->hud.erase(event.hudrm.id);
+ u32 id = event.hudrm.id;
+ if (id < player->hud.size() && player->hud[id]) {
+ delete player->hud[id];
+ player->hud[id] = NULL;
+ }
}
else if (event.type == CE_HUDCHANGE)
{
- HudElement* e = player->hud[event.hudchange.id];
- if(event.hudchange.stat == 0)
- e->pos = *event.hudchange.v2fdata;
- else if(event.hudchange.stat == 1)
- e->name = *event.hudchange.sdata;
- else if(event.hudchange.stat == 2)
- e->scale = *event.hudchange.v2fdata;
- else if(event.hudchange.stat == 3)
- e->text = *event.hudchange.sdata;
- else if(event.hudchange.stat == 4)
- e->number = event.hudchange.data;
- else if(event.hudchange.stat == 5)
- e->item = event.hudchange.data;
- else if(event.hudchange.stat == 6)
- e->dir = event.hudchange.data;
+ u32 id = event.hudchange.id;
+ if (id >= player->hud.size() || !player->hud[id]) {
+ delete event.hudchange.v2fdata;
+ delete event.hudchange.sdata;
+ continue;
+ }
+
+ HudElement* e = player->hud[id];
+ switch (event.hudchange.stat) {
+ case HUD_STAT_POS:
+ e->pos = *event.hudchange.v2fdata;
+ break;
+ case HUD_STAT_NAME:
+ e->name = *event.hudchange.sdata;
+ break;
+ case HUD_STAT_SCALE:
+ e->scale = *event.hudchange.v2fdata;
+ break;
+ case HUD_STAT_TEXT:
+ e->text = *event.hudchange.sdata;
+ break;
+ case HUD_STAT_NUMBER:
+ e->number = event.hudchange.data;
+ break;
+ case HUD_STAT_ITEM:
+ e->item = event.hudchange.data;
+ break;
+ case HUD_STAT_DIR:
+ e->dir = event.hudchange.data;
+ break;
+ }
+
+ delete event.hudchange.v2fdata;
+ delete event.hudchange.sdata;
}
}
}
@@ -3203,7 +2950,6 @@ void the_game(
*/
TimeTaker tt_draw("mainloop: draw");
-
{
TimeTaker timer("beginScene");
@@ -3307,26 +3053,8 @@ void the_game(
driver->setTransform(video::ETS_WORLD, core::IdentityMatrix);
- if(show_hud)
- {
- v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
- u32 selectionbox_color_r = rangelim(myround(selectionbox_color.X), 0, 255);
- u32 selectionbox_color_g = rangelim(myround(selectionbox_color.Y), 0, 255);
- u32 selectionbox_color_b = rangelim(myround(selectionbox_color.Z), 0, 255);
-
- for(std::vector<aabb3f>::const_iterator
- i = hilightboxes.begin();
- i != hilightboxes.end(); i++)
- {
- /*infostream<<"hilightbox min="
- <<"("<<i->MinEdge.X<<","<<i->MinEdge.Y<<","<<i->MinEdge.Z<<")"
- <<" max="
- <<"("<<i->MaxEdge.X<<","<<i->MaxEdge.Y<<","<<i->MaxEdge.Z<<")"
- <<std::endl;*/
- driver->draw3DBox(*i, video::SColor(255,selectionbox_color_r,selectionbox_color_g,selectionbox_color_b));
- }
- }
-
+ if (show_hud)
+ hud.drawSelectionBoxes(hilightboxes);
/*
Wielded tool
*/
@@ -3354,22 +3082,9 @@ void the_game(
/*
Draw crosshair
*/
- if(show_hud)
- {
- v3f crosshair_color = g_settings->getV3F("crosshair_color");
- u32 crosshair_color_r = rangelim(myround(crosshair_color.X), 0, 255);
- u32 crosshair_color_g = rangelim(myround(crosshair_color.Y), 0, 255);
- u32 crosshair_color_b = rangelim(myround(crosshair_color.Z), 0, 255);
- u32 crosshair_alpha = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
-
- driver->draw2DLine(displaycenter - core::vector2d<s32>(10,0),
- displaycenter + core::vector2d<s32>(10,0),
- video::SColor(crosshair_alpha,crosshair_color_r,crosshair_color_g,crosshair_color_b));
- driver->draw2DLine(displaycenter - core::vector2d<s32>(0,10),
- displaycenter + core::vector2d<s32>(0,10),
- video::SColor(crosshair_alpha,crosshair_color_r,crosshair_color_g,crosshair_color_b));
- }
-
+ if (show_hud)
+ hud.drawCrosshair();
+
} // timer
//timer10.stop();
@@ -3379,11 +3094,9 @@ void the_game(
/*
Draw hotbar
*/
- if(show_hud)
+ if (show_hud)
{
- draw_hotbar(driver, font, gamedef,
- v2s32(displaycenter.X, screensize.Y),
- hotbar_imagesize, hotbar_itemcount, &local_inventory,
+ hud.drawHotbar(v2s32(displaycenter.X, screensize.Y),
client.getHP(), client.getPlayerItem());
}
@@ -3413,54 +3126,8 @@ void the_game(
/*
Draw lua hud items
*/
- std::deque<gui::IGUIStaticText *> luaguitexts;
- if(show_hud)
- {
- for(std::map<u32, HudElement*>::iterator it = player->hud.begin();
- it != player->hud.end(); ++it)
- {
- HudElement* e = it->second;
- v2f posp(e->pos * v2f(screensize.X, screensize.Y));
- core::vector2d<s32> pos(posp.X, posp.Y);
- if(e->type == 'I'){ //Img
- video::ITexture *texture =
- gamedef->getTextureSource()->getTextureRaw(e->text);
- const video::SColor color(255,255,255,255);
- const video::SColor colors[] = {color,color,color,color};
- core::dimension2di imgsize(texture->getOriginalSize());
- core::rect<s32> rect(0, 0, imgsize.Width*e->scale.X,
- imgsize.Height*e->scale.X);
- rect += pos;
- driver->draw2DImage(texture, rect,
- core::rect<s32>(core::position2d<s32>(0,0), imgsize),
- NULL, colors, true);
- } else if(e->type == 'T') { //Text
- std::wstring t;
- t.assign(e->text.begin(), e->text.end());
- gui::IGUIStaticText *luaguitext = guienv->addStaticText(
- t.c_str(),
- core::rect<s32>(0, 0, e->scale.X, text_height*(e->scale.Y))+pos,
- false, false);
- luaguitexts.push_back(luaguitext);
- } else if(e->type == 'S') { //Statbar
- draw_statbar(driver, font, gamedef, pos, e->text, e->number);
- } else if(e->type == 's') { //Non-conflict Statbar
- v2s32 p(displaycenter.X - 143, screensize.Y - 76);
- p.X += e->pos.X*173;
- p.Y += e->pos.X*20;
- p.Y -= e->pos.Y*20;
- draw_statbar(driver, font, gamedef, p, e->text, e->number);
- } else if(e->type == 'i') { //Inv
- InventoryList* inv = local_inventory.getList(e->text);
- draw_item(driver, font, gamedef, pos, hotbar_imagesize,
- e->number, inv, e->item, e->dir);
- } else {
- actionstream<<"luadraw: ignoring drawform "<<it->second<<
- "of key "<<it->first<<" due to incorrect command."<<std::endl;
- continue;
- }
- }
- }
+ if (show_hud)
+ hud.drawLuaElements();
/*
Draw gui
@@ -3469,13 +3136,6 @@ void the_game(
guienv->drawAll();
/*
- Remove lua-texts
- */
- for(std::deque<gui::IGUIStaticText *>::iterator it = luaguitexts.begin();
- it != luaguitexts.end(); ++it)
- (*it)->remove();
-
- /*
End scene
*/
{
@@ -3517,11 +3177,11 @@ void the_game(
/*
Drop stuff
*/
- if(clouds)
+ if (clouds)
clouds->drop();
- if(gui_chat_console)
+ if (gui_chat_console)
gui_chat_console->drop();
- clear_particles ();
+ clear_particles();
/*
Draw a "shutting down" screen, which will be shown while the map
diff --git a/src/hud.cpp b/src/hud.cpp
new file mode 100644
index 000000000..349c55add
--- /dev/null
+++ b/src/hud.cpp
@@ -0,0 +1,291 @@
+/*
+Minetest
+Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
+Copyright (C) 2010-2013 blue42u, Jonathon Anderson <anderjon@umail.iu.edu>
+Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#include <IGUIStaticText.h>
+
+#include "guiFormSpecMenu.h"
+#include "main.h"
+#include "util/numeric.h"
+#include "log.h"
+#include "client.h"
+#include "hud.h"
+
+
+Hud::Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
+ gui::IGUIFont *font, u32 text_height, IGameDef *gamedef,
+ LocalPlayer *player, Inventory *inventory) {
+ this->driver = driver;
+ this->guienv = guienv;
+ this->font = font;
+ this->text_height = text_height;
+ this->gamedef = gamedef;
+ this->player = player;
+ this->inventory = inventory;
+
+ screensize = v2u32(0, 0);
+ displaycenter = v2s32(0, 0);
+ hotbar_imagesize = 48;
+ hotbar_itemcount = 8;
+
+ v3f crosshair_color = g_settings->getV3F("crosshair_color");
+ u32 cross_r = rangelim(myround(crosshair_color.X), 0, 255);
+ u32 cross_g = rangelim(myround(crosshair_color.Y), 0, 255);
+ u32 cross_b = rangelim(myround(crosshair_color.Z), 0, 255);
+ u32 cross_a = rangelim(g_settings->getS32("crosshair_alpha"), 0, 255);
+ crosshair_argb = video::SColor(cross_a, cross_r, cross_g, cross_b);
+
+ v3f selectionbox_color = g_settings->getV3F("selectionbox_color");
+ u32 sbox_r = rangelim(myround(selectionbox_color.X), 0, 255);
+ u32 sbox_g = rangelim(myround(selectionbox_color.Y), 0, 255);
+ u32 sbox_b = rangelim(myround(selectionbox_color.Z), 0, 255);
+ selectionbox_argb = video::SColor(255, sbox_r, sbox_g, sbox_b);
+}
+
+
+//NOTE: selectitem = 0 -> no selected; selectitem 1-based
+void Hud::drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount,
+ InventoryList *mainlist, u16 selectitem, u16 direction)
+{
+ s32 padding = imgsize / 12;
+ s32 height = imgsize + padding * 2;
+ s32 width = itemcount * (imgsize + padding * 2);
+ if (direction == HUD_DIR_TOP_BOTTOM || direction == HUD_DIR_BOTTOM_TOP) {
+ width = imgsize + padding * 2;
+ height = itemcount * (imgsize + padding * 2);
+ }
+ s32 fullimglen = imgsize + padding * 2;
+
+ // Position of upper left corner of bar
+ v2s32 pos = upperleftpos;
+
+ // Draw background color
+ /*core::rect<s32> barrect(0,0,width,height);
+ barrect += pos;
+ video::SColor bgcolor(255,128,128,128);
+ driver->draw2DRectangle(bgcolor, barrect, NULL);*/
+
+ core::rect<s32> imgrect(0, 0, imgsize, imgsize);
+
+ for (s32 i = 0; i < itemcount; i++)
+ {
+ const ItemStack &item = mainlist->getItem(i);
+
+ v2s32 steppos;
+ switch (direction) {
+ case HUD_DIR_RIGHT_LEFT:
+ steppos = v2s32(-(padding + i * fullimglen), padding);
+ break;
+ case HUD_DIR_TOP_BOTTOM:
+ steppos = v2s32(padding, padding + i * fullimglen);
+ break;
+ case HUD_DIR_BOTTOM_TOP:
+ steppos = v2s32(padding, -(padding + i * fullimglen));
+ break;
+ default:
+ steppos = v2s32(padding + i * fullimglen, padding);
+ }
+
+ core::rect<s32> rect = imgrect + pos + steppos;
+
+ if (selectitem == i + 1)
+ {
+ video::SColor c_outside(255,255,0,0);
+ //video::SColor c_outside(255,0,0,0);
+ //video::SColor c_inside(255,192,192,192);
+ s32 x1 = rect.UpperLeftCorner.X;
+ s32 y1 = rect.UpperLeftCorner.Y;
+ s32 x2 = rect.LowerRightCorner.X;
+ s32 y2 = rect.LowerRightCorner.Y;
+ // Black base borders
+ driver->draw2DRectangle(c_outside,
+ core::rect<s32>(
+ v2s32(x1 - padding, y1 - padding),
+ v2s32(x2 + padding, y1)
+ ), NULL);
+ driver->draw2DRectangle(c_outside,
+ core::rect<s32>(
+ v2s32(x1 - padding, y2),
+ v2s32(x2 + padding, y2 + padding)
+ ), NULL);
+ driver->draw2DRectangle(c_outside,
+ core::rect<s32>(
+ v2s32(x1 - padding, y1),
+ v2s32(x1, y2)
+ ), NULL);
+ driver->draw2DRectangle(c_outside,
+ core::rect<s32>(
+ v2s32(x2, y1),
+ v2s32(x2 + padding, y2)
+ ), NULL);
+ /*// Light inside borders
+ driver->draw2DRectangle(c_inside,
+ core::rect<s32>(
+ v2s32(x1 - padding/2, y1 - padding/2),
+ v2s32(x2 + padding/2, y1)
+ ), NULL);
+ driver->draw2DRectangle(c_inside,
+ core::rect<s32>(
+ v2s32(x1 - padding/2, y2),
+ v2s32(x2 + padding/2, y2 + padding/2)
+ ), NULL);
+ driver->draw2DRectangle(c_inside,
+ core::rect<s32>(
+ v2s32(x1 - padding/2, y1),
+ v2s32(x1, y2)
+ ), NULL);
+ driver->draw2DRectangle(c_inside,
+ core::rect<s32>(
+ v2s32(x2, y1),
+ v2s32(x2 + padding/2, y2)
+ ), NULL);
+ */
+ }
+
+ video::SColor bgcolor2(128, 0, 0, 0);
+ driver->draw2DRectangle(bgcolor2, rect, NULL);
+ drawItemStack(driver, font, item, rect, NULL, gamedef);
+ }
+}
+
+
+void Hud::drawLuaElements() {
+ for (size_t i = 0; i != player->hud.size(); i++) {
+ HudElement *e = player->hud[i];
+ if (!e)
+ continue;
+
+ v2s32 pos(e->pos.X * screensize.X, e->pos.Y * screensize.Y);
+ switch (e->type) {
+ case HUD_ELEM_IMAGE: {
+ video::ITexture *texture =
+ gamedef->getTextureSource()->getTextureRaw(e->text);
+ if (!texture)
+ continue;
+
+ const video::SColor color(255, 255, 255, 255);
+ const video::SColor colors[] = {color, color, color, color};
+ core::dimension2di imgsize(texture->getOriginalSize());
+ core::rect<s32> rect(0, 0, imgsize.Width * e->scale.X,
+ imgsize.Height * e->scale.X);
+ rect += pos;
+ driver->draw2DImage(texture, rect,
+ core::rect<s32>(core::position2d<s32>(0,0), imgsize),
+ NULL, colors, true);
+ break; }
+ case HUD_ELEM_TEXT: {
+ video::SColor color(255, (e->number >> 16) & 0xFF,
+ (e->number >> 8) & 0xFF,
+ (e->number >> 0) & 0xFF);
+ core::rect<s32> size(0, 0, e->scale.X, text_height * e->scale.Y);
+ font->draw(narrow_to_wide(e->text).c_str(), size + pos, color);
+ break; }
+ case HUD_ELEM_STATBAR:
+ drawStatbar(pos, e->text, e->number);
+ break;
+ case HUD_ELEM_INVENTORY: {
+ InventoryList *inv = inventory->getList(e->text);
+ drawItem(pos, hotbar_imagesize, e->number, inv, e->item, e->dir);
+ break; }
+ default:
+ infostream << "Hud::drawLuaElements: ignoring drawform " << e->type <<
+ "of hud element ID " << i << " due to unrecognized type" << std::endl;
+ }
+ }
+}
+
+
+void Hud::drawStatbar(v2s32 upperleftpos, std::string texture, s32 count) {
+ video::ITexture *stat_texture =
+ gamedef->getTextureSource()->getTextureRaw(texture);
+ if (!stat_texture)
+ return;
+
+ v2s32 p = upperleftpos;
+ for (s32 i = 0; i < count / 2; i++)
+ {
+ core::dimension2di srcd(stat_texture->getOriginalSize());
+ const video::SColor color(255, 255, 255, 255);
+ const video::SColor colors[] = {color, color, color, color};
+ core::rect<s32> rect(0, 0, srcd.Width, srcd.Height);
+ rect += p;
+ driver->draw2DImage(stat_texture, rect,
+ core::rect<s32>(core::position2d<s32>(0, 0), srcd),
+ NULL, colors, true);
+ p += v2s32(srcd.Width, 0);
+ }
+
+ if (count % 2 == 1)
+ {
+ core::dimension2di srcd(stat_texture->getOriginalSize());
+ const video::SColor color(255, 255, 255, 255);
+ const video::SColor colors[] = {color, color, color, color};
+ core::rect<s32> rect(0, 0, srcd.Width / 2, srcd.Height);
+ rect += p;
+ srcd.Width /= 2;
+ driver->draw2DImage(stat_texture, rect,
+ core::rect<s32>(core::position2d<s32>(0, 0), srcd),
+ NULL, colors, true);
+ p += v2s32(srcd.Width * 2, 0);
+ }
+}
+
+
+void Hud::drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem) {
+ InventoryList *mainlist = inventory->getList("main");
+ if (mainlist == NULL) {
+ errorstream << "draw_hotbar(): mainlist == NULL" << std::endl;
+ return;
+ }
+
+ s32 padding = hotbar_imagesize / 12;
+ s32 width = hotbar_itemcount * (hotbar_imagesize + padding * 2);
+ v2s32 pos = centerlowerpos - v2s32(width / 2, hotbar_imagesize + padding * 2);
+
+ drawItem(pos, hotbar_imagesize, hotbar_itemcount, mainlist, playeritem + 1, 0);
+ drawStatbar(pos + v2s32(0, -20), "heart.png", halfheartcount);
+}
+
+
+void Hud::drawCrosshair() {
+ driver->draw2DLine(displaycenter - v2s32(10,0),
+ displaycenter + v2s32(10, 0), crosshair_argb);
+ driver->draw2DLine(displaycenter - v2s32(0,10),
+ displaycenter + v2s32(0, 10), crosshair_argb);
+}
+
+
+void Hud::drawSelectionBoxes(std::vector<aabb3f> &hilightboxes) {
+ for (std::vector<aabb3f>::const_iterator
+ i = hilightboxes.begin();
+ i != hilightboxes.end(); i++) {
+ driver->draw3DBox(*i, selectionbox_argb);
+ }
+}
+
+
+void Hud::resizeHotbar() {
+ if (screensize.Y <= 800)
+ hotbar_imagesize = 32;
+ else if (screensize.Y <= 1280)
+ hotbar_imagesize = 48;
+ else
+ hotbar_imagesize = 64;
+}
diff --git a/src/hud.h b/src/hud.h
new file mode 100644
index 000000000..7e00a94e3
--- /dev/null
+++ b/src/hud.h
@@ -0,0 +1,116 @@
+/*
+Minetest
+Copyright (C) 2010-2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net>
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation; either version 2.1 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License along
+with this program; if not, write to the Free Software Foundation, Inc.,
+51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+#ifndef HUD_HEADER
+#define HUD_HEADER
+
+#include "irrlichttypes_extrabloated.h"
+
+#define HUD_DIR_LEFT_RIGHT 0
+#define HUD_DIR_RIGHT_LEFT 1
+#define HUD_DIR_TOP_BOTTOM 2
+#define HUD_DIR_BOTTOM_TOP 3
+
+class Player;
+
+enum HudElementType {
+ HUD_ELEM_IMAGE = 0,
+ HUD_ELEM_TEXT = 1,
+ HUD_ELEM_STATBAR = 2,
+ HUD_ELEM_INVENTORY = 3
+};
+
+enum HudElementStat {
+ HUD_STAT_POS,
+ HUD_STAT_NAME,
+ HUD_STAT_SCALE,
+ HUD_STAT_TEXT,
+ HUD_STAT_NUMBER,
+ HUD_STAT_ITEM,
+ HUD_STAT_DIR
+};
+
+struct HudElement {
+ HudElementType type;
+ v2f pos;
+ std::string name;
+ v2f scale;
+ std::string text;
+ u32 number;
+ u32 item;
+ u32 dir;
+};
+
+
+inline u32 hud_get_free_id(Player *player) {
+ size_t size = player->hud.size();
+ for (size_t i = 0; i != size; i++) {
+ if (!player->hud[i])
+ return i;
+ }
+ return size;
+}
+
+#ifndef SERVER
+
+#include <deque>
+
+#include <IGUIFont.h>
+
+#include "gamedef.h"
+#include "inventory.h"
+#include "localplayer.h"
+
+class Hud {
+public:
+ video::IVideoDriver *driver;
+ gui::IGUIEnvironment *guienv;
+ gui::IGUIFont *font;
+ u32 text_height;
+ IGameDef *gamedef;
+ LocalPlayer *player;
+ Inventory *inventory;
+
+ v2u32 screensize;
+ v2s32 displaycenter;
+ s32 hotbar_imagesize;
+ s32 hotbar_itemcount;
+
+ video::SColor crosshair_argb;
+ video::SColor selectionbox_argb;
+
+ Hud(video::IVideoDriver *driver, gui::IGUIEnvironment* guienv,
+ gui::IGUIFont *font, u32 text_height, IGameDef *gamedef,
+ LocalPlayer *player, Inventory *inventory);
+
+ void drawItem(v2s32 upperleftpos, s32 imgsize, s32 itemcount,
+ InventoryList *mainlist, u16 selectitem, u16 direction);
+ void drawLuaElements();
+ void drawStatbar(v2s32 upperleftpos, std::string texture, s32 count);
+
+ void drawHotbar(v2s32 centerlowerpos, s32 halfheartcount, u16 playeritem);
+ void resizeHotbar();
+
+ void drawCrosshair();
+ void drawSelectionBoxes(std::vector<aabb3f> &hilightboxes);
+};
+
+#endif
+
+#endif
diff --git a/src/player.h b/src/player.h
index fc80769c2..d0e50d2c3 100644
--- a/src/player.h
+++ b/src/player.h
@@ -87,7 +87,7 @@ class Map;
class IGameDef;
struct CollisionInfo;
class PlayerSAO;
-struct HudElement;
+class HudElement;
class Player
{
@@ -243,9 +243,8 @@ public:
}
u32 keyPressed;
-
- std::map<u32, HudElement*> hud;
- std::map<u8, u32> hud_bars;
+
+ std::vector<HudElement *> hud;
protected:
IGameDef *m_gamedef;
@@ -257,17 +256,6 @@ protected:
v3f m_position;
};
-struct HudElement {
- u8 type;
- core::vector2df pos;
- std::string name;
-
- core::vector2df scale;
- std::string text;
- u32 number;
- u32 item;
- u32 dir;
-};
/*
Player on the server
diff --git a/src/scriptapi_object.cpp b/src/scriptapi_object.cpp
index 8f92ca439..531bb7a58 100644
--- a/src/scriptapi_object.cpp
+++ b/src/scriptapi_object.cpp
@@ -26,6 +26,30 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "scriptapi_item.h"
#include "scriptapi_entity.h"
#include "scriptapi_common.h"
+#include "hud.h"
+
+
+struct EnumString es_HudElementType[] =
+{
+ {HUD_ELEM_IMAGE, "image"},
+ {HUD_ELEM_TEXT, "text"},
+ {HUD_ELEM_STATBAR, "statbar"},
+ {HUD_ELEM_INVENTORY, "inventory"},
+ {0, NULL},
+};
+
+struct EnumString es_HudElementStat[] =
+{
+ {HUD_STAT_POS, "pos"},
+ {HUD_STAT_NAME, "name"},
+ {HUD_STAT_SCALE, "scale"},
+ {HUD_STAT_TEXT, "text"},
+ {HUD_STAT_NUMBER, "number"},
+ {HUD_STAT_ITEM, "item"},
+ {HUD_STAT_DIR, "direction"},
+ {0, NULL},
+};
+
/*
ObjectRef
@@ -705,205 +729,161 @@ int ObjectRef::l_hud_add(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
Player *player = getplayer(ref);
- if(player == NULL) return 0;
+ if (player == NULL)
+ return 0;
- u32 id = hud_get_next_id(L);
- HudElement* form = new HudElement;
- std::string SS = getstringfield_default(L, 3, "type", "I");
- form->type = SS[0];
- lua_getfield(L, 3, "position");
- if(lua_istable(L, -1))
- form->pos = read_v2f(L, -1);
- else
- form->pos = v2f();
+ HudElement *elem = new HudElement;
+
+ elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type",
+ es_HudElementType, HUD_ELEM_TEXT);
+
+ lua_getfield(L, 2, "position");
+ elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
lua_pop(L, 1);
- form->name = getstringfield_default(L, 3, "name", "");
-
- lua_getfield(L, 3, "scale");
- if(lua_istable(L, -1))
- form->scale = read_v2f(L, -1);
- else
- form->scale = v2f();
+
+ lua_getfield(L, 2, "scale");
+ elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
lua_pop(L, 1);
+
+ elem->name = getstringfield_default(L, 2, "name", "");
+ elem->text = getstringfield_default(L, 2, "text", "");
+ elem->number = getintfield_default(L, 2, "number", 0);
+ elem->item = getintfield_default(L, 2, "item", 0);
+ elem->dir = getintfield_default(L, 2, "dir", 0);
+
+ u32 id = get_server(L)->hudAdd(player, elem);
+ if (id == (u32)-1) {
+ delete elem;
+ return 0;
+ }
- form->text = getstringfield_default(L, 3, "text", "");
- form->number = getintfield_default(L, 3, "number", 0);
- form->item = getintfield_default(L, 3, "item", 0);
- form->dir = getintfield_default(L, 3, "dir", 0);
-
- get_server(L)->hudadd(player->getName(), id, form);
- player->hud[id] = form;
lua_pushnumber(L, id);
return 1;
}
-// hud_rm(self, id)
-int ObjectRef::l_hud_rm(lua_State *L)
+// hud_remove(self, id)
+int ObjectRef::l_hud_remove(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
Player *player = getplayer(ref);
- if(player == NULL) return 0;
+ if (player == NULL)
+ return 0;
u32 id = -1;
- if(!lua_isnil(L, 2))
+ if (!lua_isnil(L, 2))
id = lua_tonumber(L, 2);
- get_server(L)->hudrm(player->getName(), id);
- player->hud.at(id)->type = (u8)NULL;
+
+ if (!get_server(L)->hudRemove(player, id))
+ return 0;
+
lua_pushboolean(L, true);
return 1;
}
-
// hud_change(self, id, stat, data)
int ObjectRef::l_hud_change(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
Player *player = getplayer(ref);
- if(player == NULL) return 0;
+ if (player == NULL)
+ return 0;
u32 id = -1;
- if(!lua_isnil(L, 2))
+ if (!lua_isnil(L, 2))
id = lua_tonumber(L, 2);
- u8 stat = -1;
- if(!lua_isnil(L, 3))
- stat = lua_tonumber(L, 3);
- if(stat == 0 || stat == 2) {
- get_server(L)->hudchange(player->getName(), id, stat, read_v2f(L, 4));
- } else if(stat == 1 || stat == 3) {
- get_server(L)->hudchange(player->getName(), id, stat, lua_tostring(L, 4));
- } else {
- get_server(L)->hudchange(player->getName(), id, stat, lua_tonumber(L, 4));
- }
-
- HudElement* e = player->hud[id];
- switch(stat) {
- case HUD_STAT_POS: e->pos = read_v2f(L, 4);
- case HUD_STAT_NAME: e->name = lua_tostring(L, 4);
- case HUD_STAT_SCALE: e->scale = read_v2f(L, 4);
- case HUD_STAT_TEXT: e->text = lua_tostring(L, 4);
- case HUD_STAT_NUMBER: e->number = lua_tonumber(L, 4);
- case HUD_STAT_ITEM: e->item = lua_tonumber(L, 4);
- case HUD_STAT_DIR: e->dir = lua_tonumber(L, 4);
+
+ HudElementStat stat = (HudElementStat)getenumfield(L, 3, "stat",
+ es_HudElementStat, HUD_STAT_NUMBER);
+
+ if (id >= player->hud.size())
+ return 0;
+
+ void *value = NULL;
+ HudElement *e = player->hud[id];
+ if (!e)
+ return 0;
+
+ switch (stat) {
+ case HUD_STAT_POS:
+ e->pos = read_v2f(L, 4);
+ value = &e->pos;
+ break;
+ case HUD_STAT_NAME:
+ e->name = lua_tostring(L, 4);
+ value = &e->name;
+ break;
+ case HUD_STAT_SCALE:
+ e->scale = read_v2f(L, 4);
+ value = &e->scale;
+ break;
+ case HUD_STAT_TEXT:
+ e->text = lua_tostring(L, 4);
+ value = &e->text;
+ break;
+ case HUD_STAT_NUMBER:
+ e->number = lua_tonumber(L, 4);
+ value = &e->number;
+ break;
+ case HUD_STAT_ITEM:
+ e->item = lua_tonumber(L, 4);
+ value = &e->item;
+ break;
+ case HUD_STAT_DIR:
+ e->dir = lua_tonumber(L, 4);
+ value = &e->dir;
}
+
+ get_server(L)->hudChange(player, id, stat, value);
lua_pushboolean(L, true);
return 1;
}
-u32 ObjectRef::hud_get_next_id(lua_State *L)
-{
- ObjectRef *ref = checkobject(L, 1);
- Player *player = getplayer(ref);
-
- for(std::map<u32, HudElement*>::iterator it=player->hud.begin();
- it!=player->hud.end();it++) {
- if(it->second->type == (u8)NULL) {
- return it->first;
- }
- }
- return player->hud.size();
-}
-
// hud_get(self, id)
int ObjectRef::l_hud_get(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
Player *player = getplayer(ref);
- if(player == NULL) return 0;
+ if (player == NULL)
+ return 0;
- HudElement* e = player->hud.at(lua_tonumber(L, -1));
+ u32 id = lua_tonumber(L, -1);
+ if (id >= player->hud.size())
+ return 0;
+
+ HudElement *e = player->hud[id];
+ if (!e)
+ return 0;
+
lua_newtable(L);
- lua_pushstring(L, std::string(1, e->type).c_str());
+
+ lua_pushstring(L, es_HudElementType[(u8)e->type].str);
lua_setfield(L, -2, "type");
+
push_v2f(L, e->pos);
lua_setfield(L, -2, "position");
+
lua_pushstring(L, e->name.c_str());
lua_setfield(L, -2, "name");
+
push_v2f(L, e->scale);
lua_setfield(L, -2, "scale");
+
lua_pushstring(L, e->text.c_str());
lua_setfield(L, -2, "text");
+
lua_pushnumber(L, e->number);
lua_setfield(L, -2, "number");
+
lua_pushnumber(L, e->item);
lua_setfield(L, -2, "item");
+
lua_pushnumber(L, e->dir);
lua_setfield(L, -2, "dir");
return 1;
}
-// hud_lock_next_bar(self, texture, right)
-// return id on success, false otherwise
-int ObjectRef::l_hud_lock_next_bar(lua_State *L)
-{
- ObjectRef *ref = checkobject(L, 1);
- Player *player = getplayer(ref);
- if(player == NULL) return 0;
-
- bool right = false;
- if(!lua_isnil(L, 2))
- right = lua_toboolean(L, 2);
- v2f pos(0, 0);
- u8 i = 0;
- if(right)
- pos.X = 1;
- i += 3;
- for(u8 it = 0; it < 4; it++) {
- if(player->hud_bars.count(i+it) == 1) {
- if(it == 3) {
- lua_pushboolean(L, false);
- return 1;
- }
- } else {
- i += it;
- pos.Y = it;
- break;
- }
- }
- HudElement* form = new HudElement;
- form->type = 's';
- form->pos = pos;
- form->name = "";
- form->scale = v2f();
- form->text = "";
- form->number = 0;
- form->item = 0;
- form->dir = 0;
-
- u32 id = hud_get_next_id(L);
- get_server(L)->hudadd(player->getName(), id, form);
- player->hud[id] = form;
- player->hud_bars[i] = id;
- lua_pushnumber(L, id);
- return 1;
-}
-
-// hud_unlock_bar(self, id)
-int ObjectRef::l_hud_unlock_bar(lua_State *L)
-{
- ObjectRef *ref = checkobject(L, 1);
- Player *player = getplayer(ref);
- if(player == NULL) return 0;
-
- u32 id = 0;
- if(!lua_isnil(L, 2))
- id = lua_tonumber(L, 2);
-
- for(std::map<u8, u32>::iterator it=player->hud_bars.begin();
- it!=player->hud_bars.end();it++) {
- if(it->second == id) {
- player->hud_bars.erase(it->first);
- get_server(L)->hudrm(player->getName(), id);
- player->hud.at(id)->type = (u8)NULL;
- lua_pushboolean(L, true);
- return 1;
- }
- }
- lua_pushboolean(L, false);
- return 1;
-}
-
ObjectRef::ObjectRef(ServerActiveObject *object):
m_object(object)
{
@@ -1011,11 +991,11 @@ const luaL_reg ObjectRef::methods[] = {
luamethod(ObjectRef, get_player_control),
luamethod(ObjectRef, get_player_control_bits),
luamethod(ObjectRef, hud_add),
- luamethod(ObjectRef, hud_rm),
+ luamethod(ObjectRef, hud_remove),
luamethod(ObjectRef, hud_change),
luamethod(ObjectRef, hud_get),
- luamethod(ObjectRef, hud_lock_next_bar),
- luamethod(ObjectRef, hud_unlock_bar),
+ //luamethod(ObjectRef, hud_lock_next_bar),
+ //luamethod(ObjectRef, hud_unlock_bar),
{0,0}
};
diff --git a/src/scriptapi_object.h b/src/scriptapi_object.h
index 6df4366bb..fd46f2cf6 100644
--- a/src/scriptapi_object.h
+++ b/src/scriptapi_object.h
@@ -29,14 +29,6 @@ extern "C" {
#include "content_sao.h"
#include "player.h"
-#define HUD_STAT_POS 0
-#define HUD_STAT_NAME 1
-#define HUD_STAT_SCALE 2
-#define HUD_STAT_TEXT 3
-#define HUD_STAT_NUMBER 4
-#define HUD_STAT_ITEM 5
-#define HUD_STAT_DIR 6
-
/*
ObjectRef
*/
@@ -202,23 +194,14 @@ private:
static int l_hud_add(lua_State *L);
// hud_rm(self, id)
- static int l_hud_rm(lua_State *L);
+ static int l_hud_remove(lua_State *L);
// hud_change(self, id, stat, data)
static int l_hud_change(lua_State *L);
- // hud_get_next_id(self)
- static u32 hud_get_next_id(lua_State *L);
-
// hud_get(self, id)
static int l_hud_get(lua_State *L);
- // hud_lock_next_bar(self, right)
- static int l_hud_lock_next_bar(lua_State *L);
-
- // hud_unlock_bar(self, id)
- static int l_hud_unlock_bar(lua_State *L);
-
public:
ObjectRef(ServerActiveObject *object);
diff --git a/src/server.cpp b/src/server.cpp
index a9632c93c..241826ba2 100644
--- a/src/server.cpp
+++ b/src/server.cpp
@@ -3449,7 +3449,9 @@ void Server::SendChatMessage(u16 peer_id, const std::wstring &message)
// Send as reliable
m_con.Send(peer_id, 0, data, true);
}
-void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname)
+
+void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec,
+ const std::string formname)
{
DSTACK(__FUNCTION_NAME);
@@ -3470,7 +3472,9 @@ void Server::SendShowFormspecMessage(u16 peer_id, const std::string formspec, co
}
// Spawns a particle on peer with peer_id
-void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, std::string texture)
+void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f acceleration,
+ float expirationtime, float size, bool collisiondetection,
+ std::string texture)
{
DSTACK(__FUNCTION_NAME);
@@ -3492,7 +3496,9 @@ void Server::SendSpawnParticle(u16 peer_id, v3f pos, v3f velocity, v3f accelerat
}
// Spawns a particle on all peers
-void Server::SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration, float expirationtime, float size, bool collisiondetection, std::string texture)
+void Server::SendSpawnParticleAll(v3f pos, v3f velocity, v3f acceleration,
+ float expirationtime, float size, bool collisiondetection,
+ std::string texture)
{
for(std::map<u16, RemoteClient*>::iterator
i = m_clients.begin();
@@ -3595,22 +3601,18 @@ void Server::SendDeleteParticleSpawnerAll(u32 id)
}
}
-void Server::SendHUDAdd(u16 peer_id, const u32 id, HudElement* form)
+void Server::SendHUDAdd(u16 peer_id, u32 id, HudElement *form)
{
- DSTACK(__FUNCTION_NAME);
-
std::ostringstream os(std::ios_base::binary);
- u8 buf[12];
// Write command
- writeU16(buf, TOCLIENT_HUDADD);
- os.write((char*)buf, 2);
+ writeU16(os, TOCLIENT_HUDADD);
writeU32(os, id);
- writeU8(os, form->type);
+ writeU8(os, (u8)form->type);
writeV2F1000(os, form->pos);
- os<<serializeString(form->name);
+ os << serializeString(form->name);
writeV2F1000(os, form->scale);
- os<<serializeString(form->text);
+ os << serializeString(form->text);
writeU32(os, form->number);
writeU32(os, form->item);
writeU32(os, form->dir);
@@ -3622,16 +3624,12 @@ void Server::SendHUDAdd(u16 peer_id, const u32 id, HudElement* form)
m_con.Send(peer_id, 0, data, true);
}
-void Server::SendHUDRm(u16 peer_id, const u32 id)
+void Server::SendHUDRemove(u16 peer_id, u32 id)
{
- DSTACK(__FUNCTION_NAME);
-
std::ostringstream os(std::ios_base::binary);
- u8 buf[12];
// Write command
- writeU16(buf, TOCLIENT_HUDRM);
- os.write((char*)buf, 2);
+ writeU16(os, TOCLIENT_HUDRM);
writeU32(os, id);
// Make data buffer
@@ -3641,67 +3639,36 @@ void Server::SendHUDRm(u16 peer_id, const u32 id)
m_con.Send(peer_id, 0, data, true);
}
-void Server::SendHUDChange(u16 peer_id, const u32 id, const u8 stat, v2f data)
+void Server::SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value)
{
- DSTACK(__FUNCTION_NAME);
-
std::ostringstream os(std::ios_base::binary);
- u8 buf[12];
// Write command
- writeU16(buf, TOCLIENT_HUDCHANGE);
- os.write((char*)buf, 2);
+ writeU16(os, TOCLIENT_HUDCHANGE);
writeU32(os, id);
- writeU8(os, stat);
- writeV2F1000(os, data);
-
- // Make data buffer
- std::string s = os.str();
- SharedBuffer<u8> ddata((u8*)s.c_str(), s.size());
- // Send as reliable
- m_con.Send(peer_id, 0, ddata, true);
-}
-
-void Server::SendHUDChange(u16 peer_id, const u32 id, const u8 stat, std::string data)
-{
- DSTACK(__FUNCTION_NAME);
-
- std::ostringstream os(std::ios_base::binary);
- u8 buf[12];
-
- // Write command
- writeU16(buf, TOCLIENT_HUDCHANGE);
- os.write((char*)buf, 2);
- writeU32(os, id);
- writeU8(os, stat);
- os<<serializeString(data);
-
- // Make data buffer
- std::string s = os.str();
- SharedBuffer<u8> ddata((u8*)s.c_str(), s.size());
- // Send as reliable
- m_con.Send(peer_id, 0, ddata, true);
-}
-
-void Server::SendHUDChange(u16 peer_id, const u32 id, const u8 stat, u32 data)
-{
- DSTACK(__FUNCTION_NAME);
-
- std::ostringstream os(std::ios_base::binary);
- u8 buf[12];
-
- // Write command
- writeU16(buf, TOCLIENT_HUDCHANGE);
- os.write((char*)buf, 2);
- writeU32(os, id);
- writeU8(os, stat);
- writeU32(os, data);
+ writeU8(os, (u8)stat);
+ switch (stat) {
+ case HUD_STAT_POS:
+ case HUD_STAT_SCALE:
+ writeV2F1000(os, *(v2f *)value);
+ break;
+ case HUD_STAT_NAME:
+ case HUD_STAT_TEXT:
+ os << serializeString(*(std::string *)value);
+ break;
+ case HUD_STAT_NUMBER:
+ case HUD_STAT_ITEM:
+ case HUD_STAT_DIR:
+ default:
+ writeU32(os, *(u32 *)value);
+ break;
+ }
// Make data buffer
std::string s = os.str();
- SharedBuffer<u8> ddata((u8*)s.c_str(), s.size());
+ SharedBuffer<u8> data((u8 *)s.c_str(), s.size());
// Send as reliable
- m_con.Send(peer_id, 0, ddata, true);
+ m_con.Send(peer_id, 0, data, true);
}
void Server::BroadcastChatMessage(const std::wstring &message)
@@ -4657,71 +4624,34 @@ bool Server::showFormspec(const char *playername, const std::string &formspec, c
return true;
}
-bool Server::hudadd(const char *playername, const u32 &id, HudElement* form)
-{
- Player *player = m_env->getPlayer(playername);
-
- if(!player)
- {
- infostream<<"hudadd: couldn't find player:"<<playername<<std::endl;
- return false;
- }
+u32 Server::hudAdd(Player *player, HudElement *form) {
+ if (!player)
+ return -1;
+ u32 id = hud_get_free_id(player);
+ if (id < player->hud.size())
+ player->hud[id] = form;
+ else
+ player->hud.push_back(form);
+
SendHUDAdd(player->peer_id, id, form);
- return true;
-}
-
-bool Server::hudrm(const char *playername, const u32 &id)
-{
- Player *player = m_env->getPlayer(playername);
-
- if(!player)
- {
- infostream<<"hudrm: couldn't find player:"<<playername<<std::endl;
- return false;
- }
-
- SendHUDRm(player->peer_id, id);
- return true;
-}
-
-bool Server::hudchange(const char *playername, const u32 &id, const u8 &stat, v2f data)
-{
- Player *player = m_env->getPlayer(playername);
-
- if(!player)
- {
- infostream<<"hudchange: couldn't find player:"<<playername<<std::endl;
- return false;
- }
-
- SendHUDChange(player->peer_id, id, stat, data);
- return true;
+ return id;
}
-bool Server::hudchange(const char *playername, const u32 &id, const u8 &stat, std::string data)
-{
- Player *player = m_env->getPlayer(playername);
-
- if(!player)
- {
- infostream<<"hudchange: couldn't find player:"<<playername<<std::endl;
+bool Server::hudRemove(Player *player, u32 id) {
+ if (!player || id >= player->hud.size() || !player->hud[id])
return false;
- }
- SendHUDChange(player->peer_id, id, stat, data);
+ delete player->hud[id];
+ player->hud[id] = NULL;
+
+ SendHUDRemove(player->peer_id, id);
return true;
}
-bool Server::hudchange(const char *playername, const u32 &id, const u8 &stat, u32 data)
-{
- Player *player = m_env->getPlayer(playername);
-
- if(!player)
- {
- infostream<<"hudchange: couldn't find player:"<<playername<<std::endl;
+bool Server::hudChange(Player *player, u32 id, HudElementStat stat, void *data) {
+ if (!player)
return false;
- }
SendHUDChange(player->peer_id, id, stat, data);
return true;
diff --git a/src/server.h b/src/server.h
index ef0c45a6a..52606b0cb 100644
--- a/src/server.h
+++ b/src/server.h
@@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "map.h"
#include "inventory.h"
#include "ban.h"
+#include "hud.h"
#include "gamedef.h"
#include "serialization.h" // For SER_FMT_VER_INVALID
#include "mods.h"
@@ -51,6 +52,7 @@ class EventManager;
class PlayerSAO;
class IRollbackManager;
class EmergeManager;
+//struct HudElement;
class ServerError : public std::exception
{
@@ -534,11 +536,11 @@ public:
}
bool showFormspec(const char *name, const std::string &formspec, const std::string &formname);
- bool hudadd(const char *pname, const u32 &id, HudElement *element);
- bool hudrm(const char *pname, const u32 &id);
- bool hudchange(const char *pname, const u32 &id, const u8 &stat, v2f data);
- bool hudchange(const char *pname, const u32 &id, const u8 &stat, std::string data);
- bool hudchange(const char *pname, const u32 &id, const u8 &stat, u32 data);
+
+ u32 hudAdd(Player *player, HudElement *element);
+ bool hudRemove(Player *player, u32 id);
+ bool hudChange(Player *player, u32 id, HudElementStat stat, void *value);
+
private:
// con::PeerHandler implementation.
@@ -578,11 +580,9 @@ private:
void SendPlayerPrivileges(u16 peer_id);
void SendPlayerInventoryFormspec(u16 peer_id);
void SendShowFormspecMessage(u16 peer_id, const std::string formspec, const std::string formname);
- void SendHUDAdd(u16 peer_id, const u32 id, HudElement* form);
- void SendHUDRm(u16 peer_id, const u32 id);
- void SendHUDChange(u16 peer_id, const u32 id, const u8 stat, v2f data);
- void SendHUDChange(u16 peer_id, const u32 id, const u8 stat, std::string data);
- void SendHUDChange(u16 peer_id, const u32 id, const u8 stat, u32 data);
+ void SendHUDAdd(u16 peer_id, u32 id, HudElement *form);
+ void SendHUDRemove(u16 peer_id, u32 id);
+ void SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value);
/*
Send a node removal/addition event to all clients except ignore_id.
Additionally, if far_players!=NULL, players further away than