aboutsummaryrefslogtreecommitdiff
path: root/src/client
diff options
context:
space:
mode:
Diffstat (limited to 'src/client')
-rw-r--r--src/client/clientevent.h1
-rw-r--r--src/client/game.cpp7
-rw-r--r--src/client/hud.cpp96
-rw-r--r--src/client/hud.h5
4 files changed, 91 insertions, 18 deletions
diff --git a/src/client/clientevent.h b/src/client/clientevent.h
index f5689c25b..7f3984b03 100644
--- a/src/client/clientevent.h
+++ b/src/client/clientevent.h
@@ -136,6 +136,7 @@ struct ClientEvent
v3f *world_pos;
v2s32 *size;
s16 z_index;
+ std::string *text2;
} hudadd;
struct
{
diff --git a/src/client/game.cpp b/src/client/game.cpp
index 4d7a85526..422e17d4f 100644
--- a/src/client/game.cpp
+++ b/src/client/game.cpp
@@ -2672,6 +2672,7 @@ void Game::handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam)
delete event->hudadd.offset;
delete event->hudadd.world_pos;
delete event->hudadd.size;
+ delete event->hudadd.text2;
return;
}
@@ -2689,6 +2690,7 @@ void Game::handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam)
e->world_pos = *event->hudadd.world_pos;
e->size = *event->hudadd.size;
e->z_index = event->hudadd.z_index;
+ e->text2 = *event->hudadd.text2;
hud_server_to_client[server_id] = player->addHud(e);
delete event->hudadd.pos;
@@ -2699,6 +2701,7 @@ void Game::handleClientEvent_HudAdd(ClientEvent *event, CameraOrientation *cam)
delete event->hudadd.offset;
delete event->hudadd.world_pos;
delete event->hudadd.size;
+ delete event->hudadd.text2;
}
void Game::handleClientEvent_HudRemove(ClientEvent *event, CameraOrientation *cam)
@@ -2771,6 +2774,10 @@ void Game::handleClientEvent_HudChange(ClientEvent *event, CameraOrientation *ca
case HUD_STAT_Z_INDEX:
e->z_index = event->hudchange.data;
break;
+
+ case HUD_STAT_TEXT2:
+ e->text2 = *event->hudchange.sdata;
+ break;
}
delete event->hudchange.v3fdata;
diff --git a/src/client/hud.cpp b/src/client/hud.cpp
index 56763e7e4..f8f712762 100644
--- a/src/client/hud.cpp
+++ b/src/client/hud.cpp
@@ -332,7 +332,8 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
break; }
case HUD_ELEM_STATBAR: {
v2s32 offs(e->offset.X, e->offset.Y);
- drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number, offs, e->size);
+ drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->text2,
+ e->number, e->item, offs, e->size);
break; }
case HUD_ELEM_INVENTORY: {
InventoryList *inv = inventory->getList(e->text);
@@ -401,8 +402,9 @@ void Hud::drawLuaElements(const v3s16 &camera_offset)
}
-void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, const std::string &texture,
- s32 count, v2s32 offset, v2s32 size)
+void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir,
+ const std::string &texture, const std::string &bgtexture,
+ s32 count, s32 maxcount, v2s32 offset, v2s32 size)
{
const video::SColor color(255, 255, 255, 255);
const video::SColor colors[] = {color, color, color, color};
@@ -411,6 +413,11 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, const std::string &tex
if (!stat_texture)
return;
+ video::ITexture *stat_texture_bg = nullptr;
+ if (!bgtexture.empty()) {
+ stat_texture_bg = tsrc->getTexture(bgtexture);
+ }
+
core::dimension2di srcd(stat_texture->getOriginalSize());
core::dimension2di dstd;
if (size == v2s32()) {
@@ -430,43 +437,100 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, const std::string &tex
p += offset;
v2s32 steppos;
- core::rect<s32> srchalfrect, dsthalfrect;
switch (drawdir) {
case HUD_DIR_RIGHT_LEFT:
steppos = v2s32(-1, 0);
- srchalfrect = core::rect<s32>(srcd.Width / 2, 0, srcd.Width, srcd.Height);
- dsthalfrect = core::rect<s32>(dstd.Width / 2, 0, dstd.Width, dstd.Height);
break;
case HUD_DIR_TOP_BOTTOM:
steppos = v2s32(0, 1);
- srchalfrect = core::rect<s32>(0, 0, srcd.Width, srcd.Height / 2);
- dsthalfrect = core::rect<s32>(0, 0, dstd.Width, dstd.Height / 2);
break;
case HUD_DIR_BOTTOM_TOP:
steppos = v2s32(0, -1);
- srchalfrect = core::rect<s32>(0, srcd.Height / 2, srcd.Width, srcd.Height);
- dsthalfrect = core::rect<s32>(0, dstd.Height / 2, dstd.Width, dstd.Height);
break;
default:
+ // From left to right
steppos = v2s32(1, 0);
- srchalfrect = core::rect<s32>(0, 0, srcd.Width / 2, srcd.Height);
- dsthalfrect = core::rect<s32>(0, 0, dstd.Width / 2, dstd.Height);
+ break;
+ }
+
+ auto calculate_clipping_rect = [] (core::dimension2di src,
+ v2s32 steppos) -> core::rect<s32> {
+
+ // Create basic rectangle
+ core::rect<s32> rect(0, 0,
+ src.Width - std::abs(steppos.X) * src.Width / 2,
+ src.Height - std::abs(steppos.Y) * src.Height / 2
+ );
+ // Move rectangle left or down
+ if (steppos.X == -1)
+ rect += v2s32(src.Width / 2, 0);
+ if (steppos.Y == -1)
+ rect += v2s32(0, src.Height / 2);
+ return rect;
+ };
+ // Rectangles for 1/2 the actual value to display
+ core::rect<s32> srchalfrect, dsthalfrect;
+ // Rectangles for 1/2 the "off state" texture
+ core::rect<s32> srchalfrect2, dsthalfrect2;
+
+ if (count % 2 == 1) {
+ // Need to draw halves: Calculate rectangles
+ srchalfrect = calculate_clipping_rect(srcd, steppos);
+ dsthalfrect = calculate_clipping_rect(dstd, steppos);
+ srchalfrect2 = calculate_clipping_rect(srcd, steppos * -1);
+ dsthalfrect2 = calculate_clipping_rect(dstd, steppos * -1);
}
+
steppos.X *= dstd.Width;
steppos.Y *= dstd.Height;
+ // Draw full textures
for (s32 i = 0; i < count / 2; i++) {
core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height);
- core::rect<s32> dstrect(0,0, dstd.Width, dstd.Height);
+ core::rect<s32> dstrect(0, 0, dstd.Width, dstd.Height);
dstrect += p;
- draw2DImageFilterScaled(driver, stat_texture, dstrect, srcrect, NULL, colors, true);
+ draw2DImageFilterScaled(driver, stat_texture,
+ dstrect, srcrect, NULL, colors, true);
p += steppos;
}
if (count % 2 == 1) {
- dsthalfrect += p;
- draw2DImageFilterScaled(driver, stat_texture, dsthalfrect, srchalfrect, NULL, colors, true);
+ // Draw half a texture
+ draw2DImageFilterScaled(driver, stat_texture,
+ dsthalfrect + p, srchalfrect, NULL, colors, true);
+
+ if (stat_texture_bg && maxcount > count) {
+ draw2DImageFilterScaled(driver, stat_texture_bg,
+ dsthalfrect2 + p, srchalfrect2,
+ NULL, colors, true);
+ p += steppos;
+ }
+ }
+
+ if (stat_texture_bg && maxcount > count / 2) {
+ // Draw "off state" textures
+ s32 start_offset;
+ if (count % 2 == 1)
+ start_offset = count / 2 + 1;
+ else
+ start_offset = count / 2;
+ for (s32 i = start_offset; i < maxcount / 2; i++) {
+ core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height);
+ core::rect<s32> dstrect(0, 0, dstd.Width, dstd.Height);
+
+ dstrect += p;
+ draw2DImageFilterScaled(driver, stat_texture_bg,
+ dstrect, srcrect,
+ NULL, colors, true);
+ p += steppos;
+ }
+
+ if (maxcount % 2 == 1) {
+ draw2DImageFilterScaled(driver, stat_texture_bg,
+ dsthalfrect + p, srchalfrect,
+ NULL, colors, true);
+ }
}
}
diff --git a/src/client/hud.h b/src/client/hud.h
index cab115990..6274b1a83 100644
--- a/src/client/hud.h
+++ b/src/client/hud.h
@@ -82,8 +82,9 @@ public:
private:
bool calculateScreenPos(const v3s16 &camera_offset, HudElement *e, v2s32 *pos);
- void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, const std::string &texture,
- s32 count, v2s32 offset, v2s32 size = v2s32());
+ void drawStatbar(v2s32 pos, u16 corner, u16 drawdir,
+ const std::string &texture, const std::string& bgtexture,
+ s32 count, s32 maxcount, v2s32 offset, v2s32 size = v2s32());
void drawItems(v2s32 upperleftpos, v2s32 screen_offset, s32 itemcount,
s32 inv_offset, InventoryList *mainlist, u16 selectitem,