Update hudbars mod to 1.10.0
[MineClone/MineClone2/killajk2201.git] / mods / HUD / hudbars / init.lua
blobfc43f85b9ecdf6fa222e2b74cd330b6d8526368a
1 local S
2 if minetest.global_exists("intllib") then
3 if intllib.make_gettext_pair then
4 S = intllib.make_gettext_pair()
5 else
6 S = intllib.Getter()
7 end
8 else
9 S = function ( s ) return s end
10 end
12 hb = {}
14 hb.hudtables = {}
16 -- number of registered HUD bars
17 hb.hudbars_count = 0
19 -- table which records which HUD bar slots have been “registered” so far; used for automatic positioning
20 hb.registered_slots = {}
22 hb.settings = {}
24 function hb.load_setting(sname, stype, defaultval, valid_values)
25 local sval
26 if stype == "string" then
27 sval = minetest.settings:get(sname)
28 elseif stype == "bool" then
29 sval = minetest.settings:get_bool(sname)
30 elseif stype == "number" then
31 sval = tonumber(minetest.settings:get(sname))
32 end
33 if sval ~= nil then
34 if valid_values ~= nil then
35 local valid = false
36 for i=1,#valid_values do
37 if sval == valid_values[i] then
38 valid = true
39 end
40 end
41 if not valid then
42 minetest.log("error", "[hudbars] Invalid value for "..sname.."! Using default value ("..tostring(defaultval)..").")
43 return defaultval
44 else
45 return sval
46 end
47 else
48 return sval
49 end
50 else
51 return defaultval
52 end
53 end
55 -- Load default settings
56 dofile(minetest.get_modpath("hudbars").."/default_settings.lua")
58 local function player_exists(player)
59 return player ~= nil and player:is_player()
60 end
62 -- Table which contains all players with active default HUD bars (only for internal use)
63 hb.players = {}
65 function hb.value_to_barlength(value, max)
66 if max == 0 then
67 return 0
68 else
69 if hb.settings.bar_type == "progress_bar" then
70 local x
71 if value < 0 then x=-0.5 else x = 0.5 end
72 local ret = math.modf((value/max) * hb.settings.max_bar_length + x)
73 return ret
74 else
75 local x
76 if value < 0 then x=-0.5 else x = 0.5 end
77 local ret = math.modf((value/max) * hb.settings.statbar_length + x)
78 return ret
79 end
80 end
81 end
83 function hb.get_hudtable(identifier)
84 return hb.hudtables[identifier]
85 end
87 function hb.get_hudbar_position_index(identifier)
88 if hb.settings.sorting[identifier] ~= nil then
89 return hb.settings.sorting[identifier]
90 else
91 local i = 0
92 while true do
93 if hb.registered_slots[i] ~= true and hb.settings.sorting_reverse[i] == nil then
94 return i
95 end
96 i = i + 1
97 end
98 end
99 end
101 function hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string)
102 minetest.log("action", "hb.register_hudbar: "..tostring(identifier))
103 local hudtable = {}
104 local pos, offset
105 local index = math.floor(hb.get_hudbar_position_index(identifier))
106 hb.registered_slots[index] = true
107 if hb.settings.alignment_pattern == "stack_up" then
108 pos = hb.settings.pos_left
109 offset = {
110 x = hb.settings.start_offset_left.x,
111 y = hb.settings.start_offset_left.y - hb.settings.vmargin * index
113 elseif hb.settings.alignment_pattern == "stack_down" then
114 pos = hb.settings.pos_left
115 offset = {
116 x = hb.settings.start_offset_left.x,
117 y = hb.settings.start_offset_left.y + hb.settings.vmargin * index
119 else
120 if index % 2 == 0 then
121 pos = hb.settings.pos_left
122 offset = {
123 x = hb.settings.start_offset_left.x,
124 y = hb.settings.start_offset_left.y - hb.settings.vmargin * (index/2)
126 else
127 pos = hb.settings.pos_right
128 offset = {
129 x = hb.settings.start_offset_right.x,
130 y = hb.settings.start_offset_right.y - hb.settings.vmargin * ((index-1)/2)
134 if format_string == nil then
135 format_string = S("%s: %d/%d")
138 hudtable.add_all = function(player, hudtable, start_value, start_max, start_hidden)
139 if start_value == nil then start_value = hudtable.default_start_value end
140 if start_max == nil then start_max = hudtable.default_start_max end
141 if start_hidden == nil then start_hidden = hudtable.default_start_hidden end
142 local ids = {}
143 local state = {}
144 local name = player:get_player_name()
145 local bgscale, iconscale, text, barnumber, bgiconnumber
146 if start_max == 0 or start_hidden then
147 bgscale = { x=0, y=0 }
148 else
149 bgscale = { x=1, y=1 }
151 if start_hidden then
152 iconscale = { x=0, y=0 }
153 barnumber = 0
154 bgiconnumber = 0
155 text = ""
156 else
157 iconscale = { x=1, y=1 }
158 barnumber = hb.value_to_barlength(start_value, start_max)
159 bgiconnumber = hb.settings.statbar_length
160 text = string.format(format_string, label, start_value, start_max)
162 if hb.settings.bar_type == "progress_bar" then
163 ids.bg = player:hud_add({
164 hud_elem_type = "image",
165 position = pos,
166 scale = bgscale,
167 text = "hudbars_bar_background.png",
168 alignment = {x=1,y=1},
169 offset = { x = offset.x - 1, y = offset.y - 1 },
171 if textures.icon ~= nil then
172 ids.icon = player:hud_add({
173 hud_elem_type = "image",
174 position = pos,
175 scale = iconscale,
176 text = textures.icon,
177 alignment = {x=-1,y=1},
178 offset = { x = offset.x - 3, y = offset.y },
181 elseif hb.settings.bar_type == "statbar_modern" then
182 if textures.bgicon ~= nil then
183 ids.bg = player:hud_add({
184 hud_elem_type = "statbar",
185 position = pos,
186 text = textures.bgicon,
187 number = bgiconnumber,
188 alignment = {x=-1,y=-1},
189 offset = { x = offset.x, y = offset.y },
190 direction = 0,
191 size = {x=24, y=24},
195 local bar_image, bar_size
196 if hb.settings.bar_type == "progress_bar" then
197 bar_image = textures.bar
198 bar_size = nil
199 elseif hb.settings.bar_type == "statbar_classic" or hb.settings.bar_type == "statbar_modern" then
200 bar_image = textures.icon
201 bar_size = {x=24, y=24}
203 ids.bar = player:hud_add({
204 hud_elem_type = "statbar",
205 position = pos,
206 text = bar_image,
207 number = barnumber,
208 alignment = {x=-1,y=-1},
209 offset = offset,
210 direction = 0,
211 size = bar_size,
213 if hb.settings.bar_type == "progress_bar" then
214 ids.text = player:hud_add({
215 hud_elem_type = "text",
216 position = pos,
217 text = text,
218 alignment = {x=1,y=1},
219 number = text_color,
220 direction = 0,
221 offset = { x = offset.x + 2, y = offset.y - 1},
224 -- Do not forget to update hb.get_hudbar_state if you add new fields to the state table
225 state.hidden = start_hidden
226 state.value = start_value
227 state.max = start_max
228 state.text = text
229 state.barlength = hb.value_to_barlength(start_value, start_max)
231 local main_error_text =
232 "[hudbars] Bad initial values of HUD bar identifier “"..tostring(identifier).."” for player "..name..". "
234 if start_max < start_value then
235 minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than start_value ("..start_value..")!")
237 if start_max < 0 then
238 minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than 0!")
240 if start_value < 0 then
241 minetest.log("error", main_error_text.."start_value ("..start_value..") is smaller than 0!")
244 hb.hudtables[identifier].hudids[name] = ids
245 hb.hudtables[identifier].hudstate[name] = state
248 hudtable.identifier = identifier
249 hudtable.format_string = format_string
250 hudtable.label = label
251 hudtable.hudids = {}
252 hudtable.hudstate = {}
253 hudtable.default_start_hidden = default_start_hidden
254 hudtable.default_start_value = default_start_value
255 hudtable.default_start_max = default_start_max
257 hb.hudbars_count= hb.hudbars_count + 1
259 hb.hudtables[identifier] = hudtable
262 function hb.init_hudbar(player, identifier, start_value, start_max, start_hidden)
263 if not player_exists(player) then return false end
264 local hudtable = hb.get_hudtable(identifier)
265 hb.hudtables[identifier].add_all(player, hudtable, start_value, start_max, start_hidden)
266 return true
269 function hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon, new_bgicon, new_bar, new_label, new_text_color)
270 if new_value == nil and new_max_value == nil and new_icon == nil and new_bgicon == nil and new_bar == nil and new_label == nil and new_text_color == nil then
271 return true
273 if not player_exists(player) then
274 return false
277 local name = player:get_player_name()
278 local hudtable = hb.get_hudtable(identifier)
279 local value_changed, max_changed = false, false
281 if new_value ~= nil then
282 if new_value ~= hudtable.hudstate[name].value then
283 hudtable.hudstate[name].value = new_value
284 value_changed = true
286 else
287 new_value = hudtable.hudstate[name].value
289 if new_max_value ~= nil then
290 if new_max_value ~= hudtable.hudstate[name].max then
291 hudtable.hudstate[name].max = new_max_value
292 max_changed = true
294 else
295 new_max_value = hudtable.hudstate[name].max
298 if hb.settings.bar_type == "progress_bar" then
299 if new_icon ~= nil and hudtable.hudids[name].icon ~= nil then
300 player:hud_change(hudtable.hudids[name].icon, "text", new_icon)
302 if new_bgicon ~= nil and hudtable.hudids[name].bgicon ~= nil then
303 player:hud_change(hudtable.hudids[name].bgicon, "text", new_bgicon)
305 if new_bar ~= nil then
306 player:hud_change(hudtable.hudids[name].bar , "text", new_bar)
308 if new_label ~= nil then
309 hudtable.label = new_label
310 local new_text = string.format(hudtable.format_string, new_label, hudtable.hudstate[name].value, hudtable.hudstate[name].max)
311 player:hud_change(hudtable.hudids[name].text, "text", new_text)
313 if new_text_color ~= nil then
314 player:hud_change(hudtable.hudids[name].text, "number", new_text_color)
316 else
317 if new_icon ~= nil and hudtable.hudids[name].bar ~= nil then
318 player:hud_change(hudtable.hudids[name].bar, "text", new_icon)
320 if new_bgicon ~= nil and hudtable.hudids[name].bg ~= nil then
321 player:hud_change(hudtable.hudids[name].bg, "text", new_bgicon)
325 local main_error_text =
326 "[hudbars] Bad call to hb.change_hudbar, identifier: “"..tostring(identifier).."”, player name: “"..name.."”. "
327 if new_max_value < new_value then
328 minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than new_value ("..new_value..")!")
330 if new_max_value < 0 then
331 minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than 0!")
333 if new_value < 0 then
334 minetest.log("error", main_error_text.."new_value ("..new_value..") is smaller than 0!")
337 if hudtable.hudstate[name].hidden == false then
338 if max_changed and hb.settings.bar_type == "progress_bar" then
339 if hudtable.hudstate[name].max == 0 then
340 player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
341 else
342 player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
346 if value_changed or max_changed then
347 local new_barlength = hb.value_to_barlength(new_value, new_max_value)
348 if new_barlength ~= hudtable.hudstate[name].barlength then
349 player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(new_value, new_max_value))
350 hudtable.hudstate[name].barlength = new_barlength
353 if hb.settings.bar_type == "progress_bar" then
354 local new_text = string.format(hudtable.format_string, hudtable.label, new_value, new_max_value)
355 if new_text ~= hudtable.hudstate[name].text then
356 player:hud_change(hudtable.hudids[name].text, "text", new_text)
357 hudtable.hudstate[name].text = new_text
362 return true
365 function hb.hide_hudbar(player, identifier)
366 if not player_exists(player) then return false end
367 local name = player:get_player_name()
368 local hudtable = hb.get_hudtable(identifier)
369 if hudtable == nil then return false end
370 if(hudtable.hudstate[name].hidden == false) then
371 if hb.settings.bar_type == "progress_bar" then
372 if hudtable.hudids[name].icon ~= nil then
373 player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0})
375 player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
376 player:hud_change(hudtable.hudids[name].text, "text", "")
377 elseif hb.settings.bar_type == "statbar_modern" then
378 player:hud_change(hudtable.hudids[name].bg, "number", 0)
380 player:hud_change(hudtable.hudids[name].bar, "number", 0)
381 hudtable.hudstate[name].hidden = true
383 return true
386 function hb.unhide_hudbar(player, identifier)
387 if not player_exists(player) then return false end
388 local name = player:get_player_name()
389 local hudtable = hb.get_hudtable(identifier)
390 if hudtable == nil then return false end
391 if(hudtable.hudstate[name].hidden) then
392 local value = hudtable.hudstate[name].value
393 local max = hudtable.hudstate[name].max
394 if hb.settings.bar_type == "progress_bar" then
395 if hudtable.hudids[name].icon ~= nil then
396 player:hud_change(hudtable.hudids[name].icon, "scale", {x=1,y=1})
398 if hudtable.hudstate[name].max ~= 0 then
399 player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
401 player:hud_change(hudtable.hudids[name].text, "text", tostring(string.format(hudtable.format_string, hudtable.label, value, max)))
402 elseif hb.settings.bar_type == "statbar_modern" then
403 player:hud_change(hudtable.hudids[name].bg, "number", hb.settings.statbar_length)
405 player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(value, max))
406 hudtable.hudstate[name].hidden = false
408 return true
411 function hb.get_hudbar_state(player, identifier)
412 if not player_exists(player) then return nil end
413 local ref = hb.get_hudtable(identifier).hudstate[player:get_player_name()]
414 -- Do not forget to update this chunk of code in case the state changes
415 local copy = {
416 hidden = ref.hidden,
417 value = ref.value,
418 max = ref.max,
419 text = ref.text,
420 barlength = ref.barlength,
422 return copy
425 function hb.get_hudbar_identifiers()
426 local ids = {}
427 for id, _ in pairs(hb.hudtables) do
428 table.insert(ids, id)
430 return ids
433 --register built-in HUD bars
434 if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then
435 hb.register_hudbar("health", 0xFFFFFF, S("Health"), { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 20, 20, false)
436 hb.register_hudbar("breath", 0xFFFFFF, S("Breath"), { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png", bgicon = "hudbars_bgicon_breath.png" }, 10, 10, true)
439 local function hide_builtin(player)
440 local flags = player:hud_get_flags()
441 flags.healthbar = false
442 flags.breathbar = false
443 player:hud_set_flags(flags)
447 local function custom_hud(player)
448 if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then
449 local hide
450 if minetest.settings:get_bool("enable_damage") then
451 hide = false
452 else
453 hide = true
455 hb.init_hudbar(player, "health", player:get_hp(), nil, hide)
456 local breath = player:get_breath()
457 local hide_breath
458 if breath == 11 and hb.settings.autohide_breath == true then hide_breath = true else hide_breath = false end
459 hb.init_hudbar(player, "breath", math.min(breath, 10), nil, hide_breath or hide)
463 local function update_health(player)
464 hb.change_hudbar(player, "health", player:get_hp())
467 -- update built-in HUD bars
468 local function update_hud(player)
469 if not player_exists(player) then return end
470 if minetest.settings:get_bool("enable_damage") then
471 if hb.settings.forceload_default_hudbars then
472 hb.unhide_hudbar(player, "health")
474 --air
475 local breath = player:get_breath()
477 if breath == 11 and hb.settings.autohide_breath == true then
478 hb.hide_hudbar(player, "breath")
479 else
480 hb.unhide_hudbar(player, "breath")
481 hb.change_hudbar(player, "breath", math.min(breath, 10))
483 --health
484 update_health(player)
485 elseif hb.settings.forceload_default_hudbars then
486 hb.hide_hudbar(player, "health")
487 hb.hide_hudbar(player, "breath")
491 minetest.register_on_player_hpchange(function(player)
492 if hb.players[player:get_player_name()] ~= nil then
493 update_health(player)
495 end)
497 minetest.register_on_respawnplayer(function(player)
498 update_health(player)
499 hb.hide_hudbar(player, "breath")
500 end)
502 minetest.register_on_joinplayer(function(player)
503 hide_builtin(player)
504 custom_hud(player)
505 hb.players[player:get_player_name()] = player
506 end)
508 minetest.register_on_leaveplayer(function(player)
509 hb.players[player:get_player_name()] = nil
510 end)
512 local main_timer = 0
513 local timer = 0
514 minetest.register_globalstep(function(dtime)
515 main_timer = main_timer + dtime
516 timer = timer + dtime
517 if main_timer > hb.settings.tick or timer > 4 then
518 if main_timer > hb.settings.tick then main_timer = 0 end
519 -- only proceed if damage is enabled
520 if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then
521 for _, player in pairs(hb.players) do
522 -- update all hud elements
523 update_hud(player)
527 if timer > 4 then timer = 0 end
528 end)