Fix stupid bug (setting_getbool instead of setting_get)
[minetest_hudbars.git] / init.lua
blob85cd0f1d7b0eeb752649600b702a65844f358474
1 hb = {}
3 hb.hudtables = {}
5 -- number of registered HUD bars
6 hb.hudbars_count = 0
8 -- table which recoreds which HUD bar slots have been “registered” so far; used for automatic positioning
9 hb.registered_slots = {}
11 hb.settings = {}
13 -- default settings
14 hb.settings.max_bar_length = 160
16 -- statbar positions
17 hb.settings.pos_left = { x=0.5, y=1 }
18 hb.settings.pos_right= { x = 0.5, y = 1 }
19 hb.settings.start_offset_left = { x = -175, y = -86 }
20 hb.settings.start_offset_right = { x = 15, y = -86 }
22 hb.settings.vmargin = 24
23 hb.settings.tick = 0.1
25 --[[
26 - hudbars_alignment_pattern: This setting changes the way the HUD bars are ordered on the display. You can choose
27 between a zig-zag pattern or a vertically stacked pattern.
28 The following values are allowed:
29 zigzag: Starting from the left bottom, the next is right from the first,
30 the next is above the first, the next is right of the third, etc.
31 This is the default.
32 stack_up: The HUD bars are stacked vertically, going upwards.
33 stack_down: The HUD bars are stacked vertically. going downwards.
35 hb.settings.alignment_pattern = "zigzag"
36 local alignment_pattern = minetest.setting_get("hudbars_alignment_pattern")
37 if alignment_pattern ~= nil then
38 hb.settings.alignment_pattern = alignment_pattern
39 if alignment_pattern ~= "zigzag" and alignment_pattern ~= "stack_up" and alignment_pattern ~= "stack_down" then
40 hb.settings.alignment_pattern = "zigzag"
41 minetest.log("error", "[hudbars] Invalid value for hudbars_alignment_pattern! Using default (zigzag).")
42 end
43 end
45 hb.settings.bar_type = "progress_bar"
46 local bar_type = minetest.setting_get("hudbars_bar_type")
47 if bar_type ~= nil then
48 hb.settings.bar_type = bar_type
49 if bar_type ~= "progress_bar" and bar_type ~= "statbar_classic" and bar_type ~= "statbar_modern" then
50 hb.settings.bar_type = "progress_bar"
51 minetest.log("error", "[hudbars] Invalid value for hudbars_bar_type! Using default (progress_bar).")
52 end
53 end
57 hb.settings.autohide_breath = true
58 local autohide_breath = minetest.setting_getbool("hudbars_autohide_breath")
59 if autohide_breath ~= nil then
60 hb.settings.autohide_breath = autohide_breath
61 end
63 local sorting = minetest.setting_get("hudbars_sorting")
64 if sorting ~= nil then
65 hb.settings.sorting = {}
66 hb.settings.sorting_reverse = {}
67 for k,v in string.gmatch(sorting, "(%w+)=(%w+)") do
68 hb.settings.sorting[k] = tonumber(v)
69 hb.settings.sorting_reverse[tonumber(v)] = k
70 end
71 else
72 hb.settings.sorting = { ["health"] = 0, ["breath"] = 1 }
73 hb.settings.sorting_reverse = { [0] = "health", [1] = "breath" }
74 end
76 -- Table which contains all players with active default HUD bars (only for internal use)
77 hb.players = {}
79 function hb.value_to_barlength(value, max)
80 if max == 0 then
81 return 0
82 else
83 if hb.settings.bar_type == "progress_bar" then
84 return math.ceil((value/max) * hb.settings.max_bar_length)
85 else
86 return math.ceil((value/max) * 20)
87 end
88 end
89 end
91 function hb.get_hudtable(identifier)
92 return hb.hudtables[identifier]
93 end
95 function hb.get_hudbar_position_index(identifier)
96 if hb.settings.sorting[identifier] ~= nil then
97 return hb.settings.sorting[identifier]
98 else
99 local i = 0
100 while true do
101 if hb.registered_slots[i] ~= true and hb.settings.sorting_reverse[i] == nil then
102 return i
104 i = i + 1
109 function hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, default_start_hidden, format_string)
110 local hudtable = {}
111 local pos, offset
112 local index = math.floor(hb.get_hudbar_position_index(identifier))
113 hb.registered_slots[index] = true
114 if hb.settings.alignment_pattern == "stack_up" then
115 pos = hb.settings.pos_left
116 offset = {
117 x = hb.settings.start_offset_left.x,
118 y = hb.settings.start_offset_left.y - hb.settings.vmargin * index
120 elseif hb.settings.alignment_pattern == "stack_down" 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
126 else
127 if index % 2 == 0 then
128 pos = hb.settings.pos_left
129 offset = {
130 x = hb.settings.start_offset_left.x,
131 y = hb.settings.start_offset_left.y - hb.settings.vmargin * (index/2)
133 else
134 pos = hb.settings.pos_right
135 offset = {
136 x = hb.settings.start_offset_right.x,
137 y = hb.settings.start_offset_right.y - hb.settings.vmargin * ((index-1)/2)
141 if format_string == nil then
142 format_string = "%s: %d/%d"
145 hudtable.add_all = function(player, hudtable, start_value, start_max, start_hidden)
146 if start_value == nil then start_value = hudtable.default_start_value end
147 if start_max == nil then start_max = hudtable.default_start_max end
148 if start_hidden == nil then start_hidden = hudtable.default_start_hidden end
149 local ids = {}
150 local state = {}
151 local name = player:get_player_name()
152 local bgscale, iconscale, text, barnumber
153 if start_max == 0 or start_hidden then
154 bgscale = { x=0, y=0 }
155 else
156 bgscale = { x=1, y=1 }
158 if start_hidden then
159 iconscale = { x=0, y=0 }
160 barnumber = 0
161 text = ""
162 else
163 iconscale = { x=1, y=1 }
164 barnumber = hb.value_to_barlength(start_value, start_max)
165 text = string.format(format_string, label, start_value, start_max)
167 if hb.settings.bar_type == "progress_bar" then
168 ids.bg = player:hud_add({
169 hud_elem_type = "image",
170 position = pos,
171 scale = bgscale,
172 text = "hudbars_bar_background.png",
173 alignment = {x=1,y=1},
174 offset = { x = offset.x - 1, y = offset.y - 1 },
176 if textures.icon ~= nil then
177 ids.icon = player:hud_add({
178 hud_elem_type = "image",
179 position = pos,
180 scale = iconscale,
181 text = textures.icon,
182 alignment = {x=-1,y=1},
183 offset = { x = offset.x - 3, y = offset.y },
186 elseif hb.settings.bar_type == "statbar_modern" then
187 if textures.bgicon ~= nil then
188 ids.bg = player:hud_add({
189 hud_elem_type = "statbar",
190 position = pos,
191 scale = bgscale,
192 text = textures.bgicon,
193 number = 20,
194 alignment = {x=-1,y=-1},
195 offset = { x = offset.x, y = offset.y },
199 local bar_image
200 if hb.settings.bar_type == "progress_bar" then
201 bar_image = textures.bar
202 elseif hb.settings.bar_type == "statbar_classic" or hb.settings.bar_type == "statbar_modern" then
203 bar_image = textures.icon
205 ids.bar = player:hud_add({
206 hud_elem_type = "statbar",
207 position = pos,
208 text = bar_image,
209 number = barnumber,
210 alignment = {x=-1,y=-1},
211 offset = offset,
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 },
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 local hudtable = hb.get_hudtable(identifier)
264 hb.hudtables[identifier].add_all(player, hudtable, start_value, start_max, start_hidden)
267 function hb.change_hudbar(player, identifier, new_value, new_max_value)
268 if new_value == nil and new_max_value == nil then
269 return
272 local name = player:get_player_name()
273 local hudtable = hb.get_hudtable(identifier)
274 local value_changed, max_changed = false, false
276 if new_value ~= nil then
277 if new_value ~= hudtable.hudstate[name].value then
278 hudtable.hudstate[name].value = new_value
279 value_changed = true
281 else
282 new_value = hudtable.hudstate[name].value
284 if new_max_value ~= nil then
285 if new_max_value ~= hudtable.hudstate[name].max then
286 hudtable.hudstate[name].max = new_max_value
287 max_changed = true
289 else
290 new_max_value = hudtable.hudstate[name].max
293 local main_error_text =
294 "[hudbars] Bad call to hb.change_hudbar, identifier: “"..tostring(identifier).."”, player name: “"..name.."”. "
295 if new_max_value < new_value then
296 minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than new_value ("..new_value..")!")
298 if new_max_value < 0 then
299 minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than 0!")
301 if new_value < 0 then
302 minetest.log("error", main_error_text.."new_value ("..new_value..") is smaller than 0!")
305 if hudtable.hudstate[name].hidden == false then
306 if max_changed and hb.settings.bar_type == "progress_bar" then
307 if hudtable.hudstate[name].max == 0 then
308 player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
309 else
310 player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
314 if value_changed or max_changed then
315 local new_barlength = hb.value_to_barlength(new_value, new_max_value)
316 if new_barlength ~= hudtable.hudstate[name].barlength then
317 player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(new_value, new_max_value))
318 hudtable.hudstate[name].barlength = new_barlength
321 if hb.settings.bar_type == "progress_bar" then
322 local new_text = string.format(hudtable.format_string, hudtable.label, new_value, new_max_value)
323 if new_text ~= hudtable.hudstate[name].text then
324 player:hud_change(hudtable.hudids[name].text, "text", new_text)
325 hudtable.hudstate[name].text = new_text
332 function hb.hide_hudbar(player, identifier)
333 local name = player:get_player_name()
334 local hudtable = hb.get_hudtable(identifier)
335 if(hudtable.hudstate[name].hidden == false) then
336 if hb.settings.bar_type == "progress_bar" then
337 if hudtable.hudids[name].icon ~= nil then
338 player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0})
340 player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
341 player:hud_change(hudtable.hudids[name].text, "text", "")
343 player:hud_change(hudtable.hudids[name].bar, "number", 0)
344 hudtable.hudstate[name].hidden = true
348 function hb.unhide_hudbar(player, identifier)
349 local name = player:get_player_name()
350 local hudtable = hb.get_hudtable(identifier)
351 if(hudtable.hudstate[name].hidden) then
352 local name = player:get_player_name()
353 local value = hudtable.hudstate[name].value
354 local max = hudtable.hudstate[name].max
355 if hb.settings.bar_type == "progress_bar" then
356 if hudtable.hudids[name].icon ~= nil then
357 player:hud_change(hudtable.hudids[name].icon, "scale", {x=1,y=1})
359 if hudtable.hudstate[name].max ~= 0 then
360 player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
362 player:hud_change(hudtable.hudids[name].text, "text", tostring(string.format(hudtable.format_string, hudtable.label, value, max)))
364 player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(value, max))
365 hudtable.hudstate[name].hidden = false
369 function hb.get_hudbar_state(player, identifier)
370 local ref = hb.get_hudtable(identifier).hudstate[player:get_player_name()]
371 -- Do not forget to update this chunk of code in case the state changes
372 local copy = {
373 hidden = ref.hidden,
374 value = ref.value,
375 max = ref.max,
376 text = ref.text,
377 barlength = ref.barlength,
379 return copy
382 --register built-in HUD bars
383 if minetest.setting_getbool("enable_damage") then
384 hb.register_hudbar("health", 0xFFFFFF, "Health", { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 20, 20, false)
385 hb.register_hudbar("breath", 0xFFFFFF, "Breath", { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png" }, 10, 10, true)
388 --load custom settings
389 local set = io.open(minetest.get_modpath("hudbars").."/hudbars.conf", "r")
390 if set then
391 dofile(minetest.get_modpath("hudbars").."/hudbars.conf")
392 set:close()
395 local function hide_builtin(player)
396 local flags = player:hud_get_flags()
397 flags.healthbar = false
398 flags.breathbar = false
399 player:hud_set_flags(flags)
403 local function custom_hud(player)
404 if minetest.setting_getbool("enable_damage") then
405 hb.init_hudbar(player, "health", player:get_hp())
406 local breath = player:get_breath()
407 local hide_breath
408 if breath == 11 and hb.settings.autohide_breath == true then hide_breath = true else hide_breath = false end
409 hb.init_hudbar(player, "breath", math.min(breath, 10), nil, hide_breath)
414 -- update built-in HUD bars
415 local function update_hud(player)
416 if minetest.setting_getbool("enable_damage") then
417 --air
418 local breath = player:get_breath()
420 if breath == 11 and hb.settings.autohide_breath == true then
421 hb.hide_hudbar(player, "breath")
422 else
423 hb.unhide_hudbar(player, "breath")
424 hb.change_hudbar(player, "breath", math.min(breath, 10))
427 --health
428 hb.change_hudbar(player, "health", player:get_hp())
432 minetest.register_on_joinplayer(function(player)
433 hide_builtin(player)
434 custom_hud(player)
435 hb.players[player:get_player_name()] = player
436 end)
438 minetest.register_on_leaveplayer(function(player)
439 hb.players[player:get_player_name()] = nil
440 end)
442 local main_timer = 0
443 local timer = 0
444 minetest.register_globalstep(function(dtime)
445 main_timer = main_timer + dtime
446 timer = timer + dtime
447 if main_timer > hb.settings.tick or timer > 4 then
448 if main_timer > hb.settings.tick then main_timer = 0 end
449 for playername, player in pairs(hb.players) do
450 -- only proceed if damage is enabled
451 if minetest.setting_getbool("enable_damage") then
452 -- update all hud elements
453 update_hud(player)
457 if timer > 4 then timer = 0 end
458 end)