Fix heart + bubble bar size on different texture packs

Add DPI support for statbar
Move heart+bubble bar to Lua HUD
Add statbar size (based upon an idea by blue42u)
Add support for customizing breath and statbar
This commit is contained in:
sapier 2014-04-28 23:41:27 +02:00
parent c80d67f48e
commit d3ee617f37
15 changed files with 325 additions and 51 deletions

@ -29,3 +29,4 @@ dofile(modpath.."/features.lua")
dofile(modpath.."/voxelarea.lua") dofile(modpath.."/voxelarea.lua")
dofile(modpath.."/vector.lua") dofile(modpath.."/vector.lua")
dofile(modpath.."/forceloading.lua") dofile(modpath.."/forceloading.lua")
dofile(modpath.."/statbars.lua")

@ -389,6 +389,7 @@ end
minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration() minetest.registered_on_chat_messages, minetest.register_on_chat_message = make_registration()
minetest.registered_globalsteps, minetest.register_globalstep = make_registration() minetest.registered_globalsteps, minetest.register_globalstep = make_registration()
minetest.registered_playerevents, minetest.register_playerevent = make_registration()
minetest.registered_on_mapgen_inits, minetest.register_on_mapgen_init = make_registration() minetest.registered_on_mapgen_inits, minetest.register_on_mapgen_init = make_registration()
minetest.registered_on_shutdown, minetest.register_on_shutdown = make_registration() minetest.registered_on_shutdown, minetest.register_on_shutdown = make_registration()
minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration() minetest.registered_on_punchnodes, minetest.register_on_punchnode = make_registration()

160
builtin/statbars.lua Normal file

@ -0,0 +1,160 @@
local health_bar_definition =
{
hud_elem_type = "statbar",
position = { x=0.5, y=1 },
text = "heart.png",
number = 20,
direction = 0,
size = { x=24, y=24 },
offset = { x=(-10*24)-25, y=-(48+24+10)},
}
local breath_bar_definition =
{
hud_elem_type = "statbar",
position = { x=0.5, y=1 },
text = "bubble.png",
number = 20,
direction = 0,
size = { x=24, y=24 },
offset = {x=25,y=-(48+24+10)},
}
local hud_ids = {}
local function initialize_builtin_statbars(player)
if not player:is_player() then
return
end
local name = player:get_player_name()
if name == "" then
return
end
if (hud_ids[name] == nil) then
hud_ids[name] = {}
end
if player:hud_get_flags().healthbar then
if hud_ids[name].id_healthbar == nil then
health_bar_definition.number = player:get_hp()
hud_ids[name].id_healthbar = player:hud_add(health_bar_definition)
end
else
if hud_ids[name].id_healthbar ~= nil then
player:hud_remove(hud_ids[name].id_healthbar)
hud_ids[name].id_healthbar = nil
end
end
if (player:get_breath() < 11) then
if player:hud_get_flags().breathbar then
if hud_ids[name].id_breathbar == nil then
hud_ids[name].id_breathbar = player:hud_add(breath_bar_definition)
end
else
if hud_ids[name].id_breathbar ~= nil then
player:hud_remove(hud_ids[name].id_breathbar)
hud_ids[name].id_breathbar = nil
end
end
elseif hud_ids[name].id_breathbar ~= nil then
player:hud_remove(hud_ids[name].id_breathbar)
hud_ids[name].id_breathbar = nil
end
end
local function cleanup_builtin_statbars(player)
if not player:is_player() then
return
end
local name = player:get_player_name()
if name == "" then
return
end
hud_ids[name] = nil
end
local function player_event_handler(player,eventname)
assert(player:is_player())
local name = player:get_player_name()
if name == "" then
return
end
if eventname == "health_changed" then
initialize_builtin_statbars(player)
if hud_ids[name].id_healthbar ~= nil then
player:hud_change(hud_ids[name].id_healthbar,"number",player:get_hp())
return true
end
end
if eventname == "breath_changed" then
initialize_builtin_statbars(player)
if hud_ids[name].id_breathbar ~= nil then
player:hud_change(hud_ids[name].id_breathbar,"number",player:get_breath()*2)
return true
end
end
if eventname == "hud_changed" then
initialize_builtin_statbars(player)
return true
end
return false
end
function minetest.hud_replace_builtin(name, definition)
if definition == nil or
type(definition) ~= "table" or
definition.hud_elem_type ~= "statbar" then
return false
end
if name == "health" then
health_bar_definition = definition
for name,ids in pairs(hud_ids) do
local player = minetest.get_player_by_name(name)
if player and hud_ids[name].id_healthbar then
player:hud_remove(hud_ids[name].id_healthbar)
initialize_builtin_statbars(player)
end
end
return true
end
if name == "breath" then
breath_bar_definition = definition
for name,ids in pairs(hud_ids) do
local player = minetest.get_player_by_name(name)
if player and hud_ids[name].id_breathbar then
player:hud_remove(hud_ids[name].id_breathbar)
initialize_builtin_statbars(player)
end
end
return true
end
return false
end
minetest.register_on_joinplayer(initialize_builtin_statbars)
minetest.register_on_leaveplayer(cleanup_builtin_statbars)
minetest.register_playerevent(player_event_handler)

@ -475,6 +475,7 @@ values can be used.
The offset field specifies a pixel offset from the position. Contrary to position, The offset field specifies a pixel offset from the position. Contrary to position,
the offset is not scaled to screen size. This allows for some precisely-positioned the offset is not scaled to screen size. This allows for some precisely-positioned
items in the HUD. items in the HUD.
Note offset WILL adapt to screen dpi as well as user defined scaling factor!
Below are the specific uses for fields in each type; fields not listed for that type are ignored. Below are the specific uses for fields in each type; fields not listed for that type are ignored.
Note: Future revisions to the HUD API may be incompatible; the HUD API is still in the experimental stages. Note: Future revisions to the HUD API may be incompatible; the HUD API is still in the experimental stages.
@ -504,6 +505,7 @@ Note: Future revisions to the HUD API may be incompatible; the HUD API is still
If odd, will end with a vertically center-split texture. If odd, will end with a vertically center-split texture.
- direction - direction
- offset: offset in pixels from position. - offset: offset in pixels from position.
- size: If used will force full-image size to this value (override texture pack image size)
- inventory - inventory
- text: The name of the inventory list to be displayed. - text: The name of the inventory list to be displayed.
- number: Number of items in the inventory to be displayed. - number: Number of items in the inventory to be displayed.
@ -1853,12 +1855,18 @@ Player-only: (no-op for other objects)
^ flags: (is visible) hotbar, healthbar, crosshair, wielditem ^ flags: (is visible) hotbar, healthbar, crosshair, wielditem
^ pass a table containing a true/false value of each flag to be set or unset ^ pass a table containing a true/false value of each flag to be set or unset
^ if a flag is nil, the flag is not modified ^ if a flag is nil, the flag is not modified
- hud_get_flags(): returns a table containing status of hud flags
^ returns { hotbar=true, healthbar=true, crosshair=true, wielditem=true, breathbar=true }
- hud_set_hotbar_itemcount(count): sets number of items in builtin hotbar - hud_set_hotbar_itemcount(count): sets number of items in builtin hotbar
^ count: number of items, must be between 1 and 23 ^ count: number of items, must be between 1 and 23
- hud_set_hotbar_image(texturename) - hud_set_hotbar_image(texturename)
^ sets background image for hotbar ^ sets background image for hotbar
- hud_set_hotbar_selected_image(texturename) - hud_set_hotbar_selected_image(texturename)
^ sets image for selected item of hotbar ^ sets image for selected item of hotbar
- hud_replace_builtin(name, hud definition)
^ replace definition of a builtin hud element
^ name: "breath" or "health"
^ hud definition: definition to replace builtin definition
- set_sky(bgcolor, type, {texture names}) - set_sky(bgcolor, type, {texture names})
^ bgcolor: {r=0...255, g=0...255, b=0...255} or nil, defaults to white ^ bgcolor: {r=0...255, g=0...255, b=0...255} or nil, defaults to white
^ Available types: ^ Available types:
@ -2579,6 +2587,8 @@ HUD Definition (hud_add, hud_get)
^ See "HUD Element Types" ^ See "HUD Element Types"
offset = {x=0, y=0}, offset = {x=0, y=0},
^ See "HUD Element Types" ^ See "HUD Element Types"
size = { x=100, y=100 },
^ Size of element in pixels
} }
Particle definition (add_particle) Particle definition (add_particle)

@ -1787,9 +1787,13 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
v2f align = readV2F1000(is); v2f align = readV2F1000(is);
v2f offset = readV2F1000(is); v2f offset = readV2F1000(is);
v3f world_pos; v3f world_pos;
v2s32 size;
try{ try{
world_pos = readV3F1000(is); world_pos = readV3F1000(is);
}catch(SerializationError &e) {}; }catch(SerializationError &e) {};
try{
size = readV2S32(is);
} catch(SerializationError &e) {};
ClientEvent event; ClientEvent event;
event.type = CE_HUDADD; event.type = CE_HUDADD;
@ -1805,6 +1809,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
event.hudadd.align = new v2f(align); event.hudadd.align = new v2f(align);
event.hudadd.offset = new v2f(offset); event.hudadd.offset = new v2f(offset);
event.hudadd.world_pos = new v3f(world_pos); event.hudadd.world_pos = new v3f(world_pos);
event.hudadd.size = new v2s32(size);
m_client_event_queue.push_back(event); m_client_event_queue.push_back(event);
} }
else if(command == TOCLIENT_HUDRM) else if(command == TOCLIENT_HUDRM)
@ -1825,6 +1830,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
v2f v2fdata; v2f v2fdata;
v3f v3fdata; v3f v3fdata;
u32 intdata = 0; u32 intdata = 0;
v2s32 v2s32data;
std::string datastring((char *)&data[2], datasize - 2); std::string datastring((char *)&data[2], datasize - 2);
std::istringstream is(datastring, std::ios_base::binary); std::istringstream is(datastring, std::ios_base::binary);
@ -1839,6 +1845,8 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
sdata = deSerializeString(is); sdata = deSerializeString(is);
else if (stat == HUD_STAT_WORLD_POS) else if (stat == HUD_STAT_WORLD_POS)
v3fdata = readV3F1000(is); v3fdata = readV3F1000(is);
else if (stat == HUD_STAT_SIZE )
v2s32data = readV2S32(is);
else else
intdata = readU32(is); intdata = readU32(is);
@ -1850,6 +1858,7 @@ void Client::ProcessData(u8 *data, u32 datasize, u16 sender_peer_id)
event.hudchange.v3fdata = new v3f(v3fdata); event.hudchange.v3fdata = new v3f(v3fdata);
event.hudchange.sdata = new std::string(sdata); event.hudchange.sdata = new std::string(sdata);
event.hudchange.data = intdata; event.hudchange.data = intdata;
event.hudchange.v2s32data = new v2s32(v2s32data);
m_client_event_queue.push_back(event); m_client_event_queue.push_back(event);
} }
else if(command == TOCLIENT_HUD_SET_FLAGS) else if(command == TOCLIENT_HUD_SET_FLAGS)

@ -215,6 +215,7 @@ struct ClientEvent
v2f *align; v2f *align;
v2f *offset; v2f *offset;
v3f *world_pos; v3f *world_pos;
v2s32 * size;
} hudadd; } hudadd;
struct{ struct{
u32 id; u32 id;
@ -226,6 +227,7 @@ struct ClientEvent
std::string *sdata; std::string *sdata;
u32 data; u32 data;
v3f *v3fdata; v3f *v3fdata;
v2s32 * v2s32data;
} hudchange; } hudchange;
struct{ struct{
video::SColor *bgcolor; video::SColor *bgcolor;

@ -472,6 +472,8 @@ enum ToClientCommand
u32 dir u32 dir
v2f1000 align v2f1000 align
v2f1000 offset v2f1000 offset
v3f1000 world_pos
v2s32 size
*/ */
TOCLIENT_HUDRM = 0x4a, TOCLIENT_HUDRM = 0x4a,

@ -2492,6 +2492,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
delete event.hudadd.align; delete event.hudadd.align;
delete event.hudadd.offset; delete event.hudadd.offset;
delete event.hudadd.world_pos; delete event.hudadd.world_pos;
delete event.hudadd.size;
continue; continue;
} }
@ -2507,6 +2508,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
e->align = *event.hudadd.align; e->align = *event.hudadd.align;
e->offset = *event.hudadd.offset; e->offset = *event.hudadd.offset;
e->world_pos = *event.hudadd.world_pos; e->world_pos = *event.hudadd.world_pos;
e->size = *event.hudadd.size;
if (id == nhudelem) if (id == nhudelem)
player->hud.push_back(e); player->hud.push_back(e);
@ -2520,6 +2522,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
delete event.hudadd.align; delete event.hudadd.align;
delete event.hudadd.offset; delete event.hudadd.offset;
delete event.hudadd.world_pos; delete event.hudadd.world_pos;
delete event.hudadd.size;
} }
else if (event.type == CE_HUDRM) else if (event.type == CE_HUDRM)
{ {
@ -2536,6 +2539,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
delete event.hudchange.v3fdata; delete event.hudchange.v3fdata;
delete event.hudchange.v2fdata; delete event.hudchange.v2fdata;
delete event.hudchange.sdata; delete event.hudchange.sdata;
delete event.hudchange.v2s32data;
continue; continue;
} }
@ -2571,11 +2575,15 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
case HUD_STAT_WORLD_POS: case HUD_STAT_WORLD_POS:
e->world_pos = *event.hudchange.v3fdata; e->world_pos = *event.hudchange.v3fdata;
break; break;
case HUD_STAT_SIZE:
e->size = *event.hudchange.v2s32data;
break;
} }
delete event.hudchange.v3fdata; delete event.hudchange.v3fdata;
delete event.hudchange.v2fdata; delete event.hudchange.v2fdata;
delete event.hudchange.sdata; delete event.hudchange.sdata;
delete event.hudchange.v2s32data;
} }
else if (event.type == CE_SET_SKY) else if (event.type == CE_SET_SKY)
{ {
@ -3563,8 +3571,7 @@ void the_game(bool &kill, bool random_input, InputHandler *input,
*/ */
if (show_hud) if (show_hud)
{ {
hud.drawHotbar(client.getHP(), client.getPlayerItem(), hud.drawHotbar(client.getPlayerItem());
client.getBreath());
} }
/* /*

@ -228,7 +228,8 @@ void Hud::drawLuaElements(v3s16 camera_offset) {
if (!e) if (!e)
continue; continue;
v2s32 pos(e->pos.X * m_screensize.X, e->pos.Y * m_screensize.Y); v2s32 pos(floor(e->pos.X * (float) m_screensize.X + 0.5),
floor(e->pos.Y * (float) m_screensize.Y + 0.5));
switch (e->type) { switch (e->type) {
case HUD_ELEM_IMAGE: { case HUD_ELEM_IMAGE: {
video::ITexture *texture = tsrc->getTexture(e->text); video::ITexture *texture = tsrc->getTexture(e->text);
@ -266,7 +267,7 @@ void Hud::drawLuaElements(v3s16 camera_offset) {
break; } break; }
case HUD_ELEM_STATBAR: { case HUD_ELEM_STATBAR: {
v2s32 offs(e->offset.X, e->offset.Y); v2s32 offs(e->offset.X, e->offset.Y);
drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number, offs); drawStatbar(pos, HUD_CORNER_UPPER, e->dir, e->text, e->number, offs, e->size);
break; } break; }
case HUD_ELEM_INVENTORY: { case HUD_ELEM_INVENTORY: {
InventoryList *inv = inventory->getList(e->text); InventoryList *inv = inventory->getList(e->text);
@ -308,7 +309,9 @@ void Hud::drawLuaElements(v3s16 camera_offset) {
} }
void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s32 count, v2s32 offset) { void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
s32 count, v2s32 offset, v2s32 size)
{
const video::SColor color(255, 255, 255, 255); const video::SColor color(255, 255, 255, 255);
const video::SColor colors[] = {color, color, color, color}; const video::SColor colors[] = {color, color, color, color};
@ -317,10 +320,25 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s
return; return;
core::dimension2di srcd(stat_texture->getOriginalSize()); core::dimension2di srcd(stat_texture->getOriginalSize());
core::dimension2di dstd;
if (size == v2s32()) {
dstd = srcd;
} else {
dstd.Height = size.Y * g_settings->getFloat("gui_scaling") *
porting::getDisplayDensity();
dstd.Width = size.X * g_settings->getFloat("gui_scaling") *
porting::getDisplayDensity();
offset.X *= g_settings->getFloat("gui_scaling") *
porting::getDisplayDensity();
offset.Y *= g_settings->getFloat("gui_scaling") *
porting::getDisplayDensity();
}
v2s32 p = pos; v2s32 p = pos;
if (corner & HUD_CORNER_LOWER) if (corner & HUD_CORNER_LOWER)
p -= srcd.Height; p -= dstd.Height;
p += offset; p += offset;
@ -338,13 +356,13 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s
default: default:
steppos = v2s32(1, 0); steppos = v2s32(1, 0);
} }
steppos.X *= srcd.Width; steppos.X *= dstd.Width;
steppos.Y *= srcd.Height; steppos.Y *= dstd.Height;
for (s32 i = 0; i < count / 2; i++) for (s32 i = 0; i < count / 2; i++)
{ {
core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height); core::rect<s32> srcrect(0, 0, srcd.Width, srcd.Height);
core::rect<s32> dstrect(srcrect); core::rect<s32> dstrect(0,0, dstd.Width, dstd.Height);
dstrect += p; dstrect += p;
driver->draw2DImage(stat_texture, dstrect, srcrect, NULL, colors, true); driver->draw2DImage(stat_texture, dstrect, srcrect, NULL, colors, true);
@ -354,7 +372,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s
if (count % 2 == 1) if (count % 2 == 1)
{ {
core::rect<s32> srcrect(0, 0, srcd.Width / 2, srcd.Height); core::rect<s32> srcrect(0, 0, srcd.Width / 2, srcd.Height);
core::rect<s32> dstrect(srcrect); core::rect<s32> dstrect(0,0, dstd.Width / 2, dstd.Height);
dstrect += p; dstrect += p;
driver->draw2DImage(stat_texture, dstrect, srcrect, NULL, colors, true); driver->draw2DImage(stat_texture, dstrect, srcrect, NULL, colors, true);
@ -362,7 +380,7 @@ void Hud::drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture, s
} }
void Hud::drawHotbar(s32 halfheartcount, u16 playeritem, s32 breath) { void Hud::drawHotbar(u16 playeritem) {
v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y); v2s32 centerlowerpos(m_displaycenter.X, m_screensize.Y);
@ -393,13 +411,6 @@ void Hud::drawHotbar(s32 halfheartcount, u16 playeritem, s32 breath) {
drawItems(secondpos, hotbar_itemcount, hotbar_itemcount/2, mainlist, playeritem + 1, 0); drawItems(secondpos, hotbar_itemcount, hotbar_itemcount/2, mainlist, playeritem + 1, 0);
} }
} }
if (player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE)
drawStatbar(pos - v2s32(0, 4), HUD_CORNER_LOWER, HUD_DIR_LEFT_RIGHT,
"heart.png", halfheartcount, v2s32(0, 0));
if (player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE && breath <= 10)
drawStatbar(pos - v2s32(-180, 4), HUD_CORNER_LOWER, HUD_DIR_LEFT_RIGHT,
"bubble.png", breath*2, v2s32(0, 0));
} }

@ -66,7 +66,8 @@ enum HudElementStat {
HUD_STAT_DIR, HUD_STAT_DIR,
HUD_STAT_ALIGN, HUD_STAT_ALIGN,
HUD_STAT_OFFSET, HUD_STAT_OFFSET,
HUD_STAT_WORLD_POS HUD_STAT_WORLD_POS,
HUD_STAT_SIZE
}; };
struct HudElement { struct HudElement {
@ -81,6 +82,7 @@ struct HudElement {
v2f align; v2f align;
v2f offset; v2f offset;
v3f world_pos; v3f world_pos;
v2s32 size;
}; };
#ifndef SERVER #ifndef SERVER
@ -122,14 +124,14 @@ public:
u32 text_height, IGameDef *gamedef, u32 text_height, IGameDef *gamedef,
LocalPlayer *player, Inventory *inventory); LocalPlayer *player, Inventory *inventory);
void drawHotbar(s32 halfheartcount, u16 playeritem, s32 breath); void drawHotbar(u16 playeritem);
void resizeHotbar(); void resizeHotbar();
void drawCrosshair(); void drawCrosshair();
void drawSelectionBoxes(std::vector<aabb3f> &hilightboxes); void drawSelectionBoxes(std::vector<aabb3f> &hilightboxes);
void drawLuaElements(v3s16 camera_offset); void drawLuaElements(v3s16 camera_offset);
private: private:
void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, void drawStatbar(v2s32 pos, u16 corner, u16 drawdir, std::string texture,
std::string texture, s32 count, v2s32 offset); s32 count, v2s32 offset, v2s32 size=v2s32());
void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset, void drawItems(v2s32 upperleftpos, s32 itemcount, s32 offset,
InventoryList *mainlist, u16 selectitem, u16 direction); InventoryList *mainlist, u16 selectitem, u16 direction);

@ -58,6 +58,24 @@ void ScriptApiEnv::environment_Step(float dtime)
} }
} }
void ScriptApiEnv::player_event(ServerActiveObject* player, std::string type)
{
SCRIPTAPI_PRECHECKHEADER
// Get minetest.registered_playerevents
lua_getglobal(L, "minetest");
lua_getfield(L, -1, "registered_playerevents");
// Call callbacks
objectrefGetOrCreate(player); // player
lua_pushstring(L,type.c_str()); // event type
try {
script_run_callbacks(L, 2, RUN_CALLBACKS_MODE_FIRST);
} catch (LuaError &e) {
getServer()->setAsyncFatalError(e.what());
}
}
void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams) void ScriptApiEnv::environment_OnMapgenInit(MapgenParams *mgparams)
{ {
SCRIPTAPI_PRECHECKHEADER SCRIPTAPI_PRECHECKHEADER

@ -37,6 +37,9 @@ public:
// After initializing mapgens // After initializing mapgens
void environment_OnMapgenInit(MapgenParams *mgparams); void environment_OnMapgenInit(MapgenParams *mgparams);
//called on player event
void player_event(ServerActiveObject* player, std::string type);
void initializeEnvironment(ServerEnvironment *env); void initializeEnvironment(ServerEnvironment *env);
}; };

@ -906,6 +906,10 @@ int ObjectRef::l_hud_add(lua_State *L)
elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f(); elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
lua_pop(L, 1); lua_pop(L, 1);
lua_getfield(L, 2, "size");
elem->size = lua_istable(L, -1) ? read_v2s32(L, -1) : v2s32();
lua_pop(L, 1);
elem->name = getstringfield_default(L, 2, "name", ""); elem->name = getstringfield_default(L, 2, "name", "");
elem->text = getstringfield_default(L, 2, "text", ""); elem->text = getstringfield_default(L, 2, "text", "");
elem->number = getintfield_default(L, 2, "number", 0); elem->number = getintfield_default(L, 2, "number", 0);
@ -924,6 +928,11 @@ int ObjectRef::l_hud_add(lua_State *L)
elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f(); elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
lua_pop(L, 1); lua_pop(L, 1);
/* check for known deprecated element usage */
if ((elem->type == HUD_ELEM_STATBAR) && (elem->size == v2s32())) {
log_deprecated(L,"Deprecated usage of statbar without size!");
}
u32 id = getServer(L)->hudAdd(player, elem); u32 id = getServer(L)->hudAdd(player, elem);
if (id == (u32)-1) { if (id == (u32)-1) {
delete elem; delete elem;
@ -1019,6 +1028,10 @@ int ObjectRef::l_hud_change(lua_State *L)
e->world_pos = read_v3f(L, 4); e->world_pos = read_v3f(L, 4);
value = &e->world_pos; value = &e->world_pos;
break; break;
case HUD_STAT_SIZE:
e->size = read_v2s32(L, 4);
value = &e->size;
break;
} }
getServer(L)->hudChange(player, id, stat, value); getServer(L)->hudChange(player, id, stat, value);
@ -1101,6 +1114,28 @@ int ObjectRef::l_hud_set_flags(lua_State *L)
return 1; return 1;
} }
int ObjectRef::l_hud_get_flags(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
Player *player = getplayer(ref);
if (player == NULL)
return 0;
lua_newtable(L);
lua_pushboolean(L, player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE);
lua_setfield(L, -2, "hotbar");
lua_pushboolean(L, player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE);
lua_setfield(L, -2, "healthbar");
lua_pushboolean(L, player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE);
lua_setfield(L, -2, "crosshair");
lua_pushboolean(L, player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE);
lua_setfield(L, -2, "wielditem");
lua_pushboolean(L, player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE);
lua_setfield(L, -2, "breathbar");
return 1;
}
// hud_set_hotbar_itemcount(self, hotbar_itemcount) // hud_set_hotbar_itemcount(self, hotbar_itemcount)
int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L) int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
{ {
@ -1321,6 +1356,7 @@ const luaL_reg ObjectRef::methods[] = {
luamethod(ObjectRef, hud_change), luamethod(ObjectRef, hud_change),
luamethod(ObjectRef, hud_get), luamethod(ObjectRef, hud_get),
luamethod(ObjectRef, hud_set_flags), luamethod(ObjectRef, hud_set_flags),
luamethod(ObjectRef, hud_get_flags),
luamethod(ObjectRef, hud_set_hotbar_itemcount), luamethod(ObjectRef, hud_set_hotbar_itemcount),
luamethod(ObjectRef, hud_set_hotbar_image), luamethod(ObjectRef, hud_set_hotbar_image),
luamethod(ObjectRef, hud_set_hotbar_selected_image), luamethod(ObjectRef, hud_set_hotbar_selected_image),

@ -216,6 +216,9 @@ private:
// hud_set_flags(self, flags) // hud_set_flags(self, flags)
static int l_hud_set_flags(lua_State *L); static int l_hud_set_flags(lua_State *L);
// hud_get_flags()
static int l_hud_get_flags(lua_State *L);
// hud_set_hotbar_itemcount(self, hotbar_itemcount) // hud_set_hotbar_itemcount(self, hotbar_itemcount)
static int l_hud_set_hotbar_itemcount(lua_State *L); static int l_hud_set_hotbar_itemcount(lua_State *L);

@ -646,7 +646,7 @@ void Server::AsyncRunStep(bool initial_step)
/* /*
Send player breath if changed Send player breath if changed
*/ */
if(playersao->m_breath_not_sent){ if(playersao->m_breath_not_sent) {
SendPlayerBreath(*i); SendPlayerBreath(*i);
} }
@ -2202,6 +2202,7 @@ void Server::ProcessData(u8 *data, u32 datasize, u16 peer_id)
std::istringstream is(datastring, std::ios_base::binary); std::istringstream is(datastring, std::ios_base::binary);
u16 breath = readU16(is); u16 breath = readU16(is);
playersao->setBreath(breath); playersao->setBreath(breath);
m_script->player_event(playersao,"breath_changed");
} }
else if(command == TOSERVER_PASSWORD) else if(command == TOSERVER_PASSWORD)
{ {
@ -3289,6 +3290,7 @@ void Server::SendHUDAdd(u16 peer_id, u32 id, HudElement *form)
writeV2F1000(os, form->align); writeV2F1000(os, form->align);
writeV2F1000(os, form->offset); writeV2F1000(os, form->offset);
writeV3F1000(os, form->world_pos); writeV3F1000(os, form->world_pos);
writeV2S32(os,form->size);
// Make data buffer // Make data buffer
std::string s = os.str(); std::string s = os.str();
@ -3335,6 +3337,9 @@ void Server::SendHUDChange(u16 peer_id, u32 id, HudElementStat stat, void *value
case HUD_STAT_WORLD_POS: case HUD_STAT_WORLD_POS:
writeV3F1000(os, *(v3f *)value); writeV3F1000(os, *(v3f *)value);
break; break;
case HUD_STAT_SIZE:
writeV2S32(os,*(v2s32 *)value);
break;
case HUD_STAT_NUMBER: case HUD_STAT_NUMBER:
case HUD_STAT_ITEM: case HUD_STAT_ITEM:
case HUD_STAT_DIR: case HUD_STAT_DIR:
@ -3445,6 +3450,7 @@ void Server::SendPlayerHP(u16 peer_id)
assert(playersao); assert(playersao);
playersao->m_hp_not_sent = false; playersao->m_hp_not_sent = false;
SendHP(peer_id, playersao->getHP()); SendHP(peer_id, playersao->getHP());
m_script->player_event(playersao,"health_changed");
// Send to other clients // Send to other clients
std::string str = gob_cmd_punched(playersao->readDamage(), playersao->getHP()); std::string str = gob_cmd_punched(playersao->readDamage(), playersao->getHP());
@ -3458,6 +3464,7 @@ void Server::SendPlayerBreath(u16 peer_id)
PlayerSAO *playersao = getPlayerSAO(peer_id); PlayerSAO *playersao = getPlayerSAO(peer_id);
assert(playersao); assert(playersao);
playersao->m_breath_not_sent = false; playersao->m_breath_not_sent = false;
m_script->player_event(playersao,"breath_changed");
SendBreath(peer_id, playersao->getBreath()); SendBreath(peer_id, playersao->getBreath());
} }
@ -4588,6 +4595,8 @@ bool Server::hudSetFlags(Player *player, u32 flags, u32 mask) {
return false; return false;
SendHUDSetFlags(player->peer_id, flags, mask); SendHUDSetFlags(player->peer_id, flags, mask);
m_script->player_event(player->getPlayerSAO(),"hud_changed");
return true; return true;
} }