5 -- number of registered HUD bars
8 -- table which records which HUD bar slots have been “registered” so far; used for automatic positioning
9 hb
.registered_slots
= {}
13 function hb
.load_setting(sname
, stype
, defaultval
, valid_values
)
15 if stype
== "string" then
16 sval
= minetest
.setting_get(sname
)
17 elseif stype
== "bool" then
18 sval
= minetest
.setting_getbool(sname
)
19 elseif stype
== "number" then
20 sval
= tonumber(minetest
.setting_get(sname
))
23 if valid_values
~= nil then
25 for i
=1,#valid_values
do
26 if sval
== valid_values
[i
] then
31 minetest
.log("error", "[hudbars] Invalid value for "..sname
.."! Using default value ("..tostring(defaultval
)..").")
44 -- (hardcoded) default settings
45 hb
.settings
.max_bar_length
= 160
46 hb
.settings
.statbar_length
= 20
49 hb
.settings
.pos_left
= {}
50 hb
.settings
.pos_right
= {}
51 hb
.settings
.start_offset_left
= {}
52 hb
.settings
.start_offset_right
= {}
53 hb
.settings
.pos_left
.x
= hb
.load_setting("hudbars_pos_left_x", "number", 0.5)
54 hb
.settings
.pos_left
.y
= hb
.load_setting("hudbars_pos_left_y", "number", 1)
55 hb
.settings
.pos_right
.x
= hb
.load_setting("hudbars_pos_right_x", "number", 0.5)
56 hb
.settings
.pos_right
.y
= hb
.load_setting("hudbars_pos_right_y", "number", 1)
57 hb
.settings
.start_offset_left
.x
= hb
.load_setting("hudbars_start_offset_left_x", "number", -175)
58 hb
.settings
.start_offset_left
.y
= hb
.load_setting("hudbars_start_offset_left_y", "number", -86)
59 hb
.settings
.start_offset_right
.x
= hb
.load_setting("hudbars_start_offset_right_x", "number", 15)
60 hb
.settings
.start_offset_right
.y
= hb
.load_setting("hudbars_start_offset_right_y", "number", -86)
62 hb
.settings
.vmargin
= hb
.load_setting("hudbars_tick", "number", 24)
63 hb
.settings
.tick
= hb
.load_setting("hudbars_tick", "number", 0.1)
66 - hudbars_alignment_pattern: This setting changes the way the HUD bars are ordered on the display. You can choose
67 between a zig-zag pattern or a vertically stacked pattern.
68 The following values are allowed:
69 zigzag: Starting from the left bottom, the next is right from the first,
70 the next is above the first, the next is right of the third, etc.
72 stack_up: The HUD bars are stacked vertically, going upwards.
73 stack_down: The HUD bars are stacked vertically, going downwards.
77 hb
.settings
.alignment_pattern
= hb
.load_setting("hudbars_alignment_pattern", "string", "zigzag", {"zigzag", "stack_up", "stack_down"})
78 hb
.settings
.bar_type
= hb
.load_setting("hudbars_bar_type", "string", "progress_bar", {"progress_bar", "statbar_classic", "statbar_modern"})
79 hb
.settings
.autohide_breath
= hb
.load_setting("hudbars_autohide_breath", "bool", true)
81 local sorting
= minetest
.setting_get("hudbars_sorting")
82 if sorting
~= nil then
83 hb
.settings
.sorting
= {}
84 hb
.settings
.sorting_reverse
= {}
85 for k
,v
in string.gmatch(sorting
, "(%w+)=(%w+)") do
86 hb
.settings
.sorting
[k
] = tonumber(v
)
87 hb
.settings
.sorting_reverse
[tonumber(v
)] = k
90 hb
.settings
.sorting
= { ["health"] = 0, ["breath"] = 1 }
91 hb
.settings
.sorting_reverse
= { [0] = "health", [1] = "breath" }
94 -- Table which contains all players with active default HUD bars (only for internal use)
97 function hb
.value_to_barlength(value
, max)
101 if hb
.settings
.bar_type
== "progress_bar" then
103 if value
< 0 then x
=-0.5 else x
= 0.5 end
104 local ret
= math
.modf((value
/max) * hb
.settings
.max_bar_length
+ x
)
108 if value
< 0 then x
=-0.5 else x
= 0.5 end
109 local ret
= math
.modf((value
/max) * hb
.settings
.statbar_length
+ x
)
115 function hb
.get_hudtable(identifier
)
116 return hb
.hudtables
[identifier
]
119 function hb
.get_hudbar_position_index(identifier
)
120 if hb
.settings
.sorting
[identifier
] ~= nil then
121 return hb
.settings
.sorting
[identifier
]
125 if hb
.registered_slots
[i
] ~= true and hb
.settings
.sorting_reverse
[i
] == nil then
133 function hb
.register_hudbar(identifier
, text_color
, label
, textures
, default_start_value
, default_start_max
, default_start_hidden
, format_string
)
136 local index
= math
.floor(hb
.get_hudbar_position_index(identifier
))
137 hb
.registered_slots
[index
] = true
138 if hb
.settings
.alignment_pattern
== "stack_up" then
139 pos
= hb
.settings
.pos_left
141 x
= hb
.settings
.start_offset_left
.x
,
142 y
= hb
.settings
.start_offset_left
.y
- hb
.settings
.vmargin
* index
144 elseif hb
.settings
.alignment_pattern
== "stack_down" then
145 pos
= hb
.settings
.pos_left
147 x
= hb
.settings
.start_offset_left
.x
,
148 y
= hb
.settings
.start_offset_left
.y
+ hb
.settings
.vmargin
* index
151 if index
% 2 == 0 then
152 pos
= hb
.settings
.pos_left
154 x
= hb
.settings
.start_offset_left
.x
,
155 y
= hb
.settings
.start_offset_left
.y
- hb
.settings
.vmargin
* (index
/2)
158 pos
= hb
.settings
.pos_right
160 x
= hb
.settings
.start_offset_right
.x
,
161 y
= hb
.settings
.start_offset_right
.y
- hb
.settings
.vmargin
* ((index
-1)/2)
165 if format_string
== nil then
166 format_string
= "%s: %d/%d"
169 hudtable
.add_all
= function(player
, hudtable
, start_value
, start_max
, start_hidden
)
170 if start_value
== nil then start_value
= hudtable
.default_start_value
end
171 if start_max
== nil then start_max
= hudtable
.default_start_max
end
172 if start_hidden
== nil then start_hidden
= hudtable
.default_start_hidden
end
175 local name
= player
:get_player_name()
176 local bgscale
, iconscale
, text
, barnumber
177 if start_max
== 0 or start_hidden
then
178 bgscale
= { x
=0, y
=0 }
180 bgscale
= { x
=1, y
=1 }
183 iconscale
= { x
=0, y
=0 }
187 iconscale
= { x
=1, y
=1 }
188 barnumber
= hb
.value_to_barlength(start_value
, start_max
)
189 text
= string.format(format_string
, label
, start_value
, start_max
)
191 if hb
.settings
.bar_type
== "progress_bar" then
192 ids
.bg
= player
:hud_add({
193 hud_elem_type
= "image",
196 text
= "hudbars_bar_background.png",
197 alignment
= {x
=1,y
=1},
198 offset
= { x
= offset
.x
- 1, y
= offset
.y
- 1 },
200 if textures
.icon
~= nil then
201 ids
.icon
= player
:hud_add({
202 hud_elem_type
= "image",
205 text
= textures
.icon
,
206 alignment
= {x
=-1,y
=1},
207 offset
= { x
= offset
.x
- 3, y
= offset
.y
},
210 elseif hb
.settings
.bar_type
== "statbar_modern" then
211 if textures
.bgicon
~= nil then
212 ids
.bg
= player
:hud_add({
213 hud_elem_type
= "statbar",
216 text
= textures
.bgicon
,
217 number = hb
.settings
.statbar_length
,
218 alignment
= {x
=-1,y
=-1},
219 offset
= { x
= offset
.x
, y
= offset
.y
},
224 if hb
.settings
.bar_type
== "progress_bar" then
225 bar_image
= textures
.bar
226 elseif hb
.settings
.bar_type
== "statbar_classic" or hb
.settings
.bar_type
== "statbar_modern" then
227 bar_image
= textures
.icon
229 ids
.bar
= player
:hud_add({
230 hud_elem_type
= "statbar",
234 alignment
= {x
=-1,y
=-1},
237 if hb
.settings
.bar_type
== "progress_bar" then
238 ids
.text
= player
:hud_add({
239 hud_elem_type
= "text",
242 alignment
= {x
=1,y
=1},
245 offset
= { x
= offset
.x
+ 2, y
= offset
.y
},
248 -- Do not forget to update hb.get_hudbar_state if you add new fields to the state table
249 state
.hidden
= start_hidden
250 state
.value
= start_value
251 state
.max = start_max
253 state
.barlength
= hb
.value_to_barlength(start_value
, start_max
)
255 local main_error_text
=
256 "[hudbars] Bad initial values of HUD bar identifier “"..tostring(identifier
).."” for player "..name
..". "
258 if start_max
< start_value
then
259 minetest
.log("error", main_error_text
.."start_max ("..start_max
..") is smaller than start_value ("..start_value
..")!")
261 if start_max
< 0 then
262 minetest
.log("error", main_error_text
.."start_max ("..start_max
..") is smaller than 0!")
264 if start_value
< 0 then
265 minetest
.log("error", main_error_text
.."start_value ("..start_value
..") is smaller than 0!")
268 hb
.hudtables
[identifier
].hudids
[name
] = ids
269 hb
.hudtables
[identifier
].hudstate
[name
] = state
272 hudtable
.identifier
= identifier
273 hudtable
.format_string
= format_string
274 hudtable
.label
= label
276 hudtable
.hudstate
= {}
277 hudtable
.default_start_hidden
= default_start_hidden
278 hudtable
.default_start_value
= default_start_value
279 hudtable
.default_start_max
= default_start_max
281 hb
.hudbars_count
= hb
.hudbars_count
+ 1
283 hb
.hudtables
[identifier
] = hudtable
286 function hb
.init_hudbar(player
, identifier
, start_value
, start_max
, start_hidden
)
287 local hudtable
= hb
.get_hudtable(identifier
)
288 hb
.hudtables
[identifier
].add_all(player
, hudtable
, start_value
, start_max
, start_hidden
)
291 function hb
.change_hudbar(player
, identifier
, new_value
, new_max_value
)
292 if new_value
== nil and new_max_value
== nil then
296 local name
= player
:get_player_name()
297 local hudtable
= hb
.get_hudtable(identifier
)
298 local value_changed
, max_changed
= false, false
300 if new_value
~= nil then
301 if new_value
~= hudtable
.hudstate
[name
].value
then
302 hudtable
.hudstate
[name
].value
= new_value
306 new_value
= hudtable
.hudstate
[name
].value
308 if new_max_value
~= nil then
309 if new_max_value
~= hudtable
.hudstate
[name
].max then
310 hudtable
.hudstate
[name
].max = new_max_value
314 new_max_value
= hudtable
.hudstate
[name
].max
317 local main_error_text
=
318 "[hudbars] Bad call to hb.change_hudbar, identifier: “"..tostring(identifier
).."”, player name: “"..name
.."”. "
319 if new_max_value
< new_value
then
320 minetest
.log("error", main_error_text
.."new_max_value ("..new_max_value
..") is smaller than new_value ("..new_value
..")!")
322 if new_max_value
< 0 then
323 minetest
.log("error", main_error_text
.."new_max_value ("..new_max_value
..") is smaller than 0!")
325 if new_value
< 0 then
326 minetest
.log("error", main_error_text
.."new_value ("..new_value
..") is smaller than 0!")
329 if hudtable
.hudstate
[name
].hidden
== false then
330 if max_changed
and hb
.settings
.bar_type
== "progress_bar" then
331 if hudtable
.hudstate
[name
].max == 0 then
332 player
:hud_change(hudtable
.hudids
[name
].bg
, "scale", {x
=0,y
=0})
334 player
:hud_change(hudtable
.hudids
[name
].bg
, "scale", {x
=1,y
=1})
338 if value_changed
or max_changed
then
339 local new_barlength
= hb
.value_to_barlength(new_value
, new_max_value
)
340 if new_barlength
~= hudtable
.hudstate
[name
].barlength
then
341 player
:hud_change(hudtable
.hudids
[name
].bar
, "number", hb
.value_to_barlength(new_value
, new_max_value
))
342 hudtable
.hudstate
[name
].barlength
= new_barlength
345 if hb
.settings
.bar_type
== "progress_bar" then
346 local new_text
= string.format(hudtable
.format_string
, hudtable
.label
, new_value
, new_max_value
)
347 if new_text
~= hudtable
.hudstate
[name
].text
then
348 player
:hud_change(hudtable
.hudids
[name
].text
, "text", new_text
)
349 hudtable
.hudstate
[name
].text
= new_text
356 function hb
.hide_hudbar(player
, identifier
)
357 local name
= player
:get_player_name()
358 local hudtable
= hb
.get_hudtable(identifier
)
359 if(hudtable
.hudstate
[name
].hidden
== false) then
360 if hb
.settings
.bar_type
== "progress_bar" then
361 if hudtable
.hudids
[name
].icon
~= nil then
362 player
:hud_change(hudtable
.hudids
[name
].icon
, "scale", {x
=0,y
=0})
364 player
:hud_change(hudtable
.hudids
[name
].bg
, "scale", {x
=0,y
=0})
365 player
:hud_change(hudtable
.hudids
[name
].text
, "text", "")
367 player
:hud_change(hudtable
.hudids
[name
].bar
, "number", 0)
368 hudtable
.hudstate
[name
].hidden
= true
372 function hb
.unhide_hudbar(player
, identifier
)
373 local name
= player
:get_player_name()
374 local hudtable
= hb
.get_hudtable(identifier
)
375 if(hudtable
.hudstate
[name
].hidden
) then
376 local name
= player
:get_player_name()
377 local value
= hudtable
.hudstate
[name
].value
378 local max = hudtable
.hudstate
[name
].max
379 if hb
.settings
.bar_type
== "progress_bar" then
380 if hudtable
.hudids
[name
].icon
~= nil then
381 player
:hud_change(hudtable
.hudids
[name
].icon
, "scale", {x
=1,y
=1})
383 if hudtable
.hudstate
[name
].max ~= 0 then
384 player
:hud_change(hudtable
.hudids
[name
].bg
, "scale", {x
=1,y
=1})
386 player
:hud_change(hudtable
.hudids
[name
].text
, "text", tostring(string.format(hudtable
.format_string
, hudtable
.label
, value
, max)))
388 player
:hud_change(hudtable
.hudids
[name
].bar
, "number", hb
.value_to_barlength(value
, max))
389 hudtable
.hudstate
[name
].hidden
= false
393 function hb
.get_hudbar_state(player
, identifier
)
394 local ref
= hb
.get_hudtable(identifier
).hudstate
[player
:get_player_name()]
395 -- Do not forget to update this chunk of code in case the state changes
401 barlength
= ref
.barlength
,
406 --register built-in HUD bars
407 if minetest
.setting_getbool("enable_damage") then
408 hb
.register_hudbar("health", 0xFFFFFF, "Health", { bar
= "hudbars_bar_health.png", icon
= "hudbars_icon_health.png", bgicon
= "hudbars_bgicon_health.png" }, 20, 20, false)
409 hb
.register_hudbar("breath", 0xFFFFFF, "Breath", { bar
= "hudbars_bar_breath.png", icon
= "hudbars_icon_breath.png" }, 10, 10, true)
412 local function hide_builtin(player
)
413 local flags
= player
:hud_get_flags()
414 flags
.healthbar
= false
415 flags
.breathbar
= false
416 player
:hud_set_flags(flags
)
420 local function custom_hud(player
)
421 if minetest
.setting_getbool("enable_damage") then
422 hb
.init_hudbar(player
, "health", player
:get_hp())
423 local breath
= player
:get_breath()
425 if breath
== 11 and hb
.settings
.autohide_breath
== true then hide_breath
= true else hide_breath
= false end
426 hb
.init_hudbar(player
, "breath", math
.min(breath
, 10), nil, hide_breath
)
431 -- update built-in HUD bars
432 local function update_hud(player
)
433 if minetest
.setting_getbool("enable_damage") then
435 local breath
= player
:get_breath()
437 if breath
== 11 and hb
.settings
.autohide_breath
== true then
438 hb
.hide_hudbar(player
, "breath")
440 hb
.unhide_hudbar(player
, "breath")
441 hb
.change_hudbar(player
, "breath", math
.min(breath
, 10))
445 hb
.change_hudbar(player
, "health", player
:get_hp())
449 minetest
.register_on_joinplayer(function(player
)
452 hb
.players
[player
:get_player_name()] = player
455 minetest
.register_on_leaveplayer(function(player
)
456 hb
.players
[player
:get_player_name()] = nil
461 minetest
.register_globalstep(function(dtime
)
462 main_timer
= main_timer
+ dtime
463 timer
= timer
+ dtime
464 if main_timer
> hb
.settings
.tick
or timer
> 4 then
465 if main_timer
> hb
.settings
.tick
then main_timer
= 0 end
466 for playername
, player
in pairs(hb
.players
) do
467 -- only proceed if damage is enabled
468 if minetest
.setting_getbool("enable_damage") then
469 -- update all hud elements
474 if timer
> 4 then timer
= 0 end