Minor refactoring
[minetest_hudbars.git] / init.lua
blob06681dcb0032c673e0a64d781a2b6716585b47dd
1 hb = {}
3 hb.hudtables = {}
5 -- number of registered HUD bars
6 hb.hudbars_count = 0
8 hb.settings = {}
10 -- default settings
11 hb.settings.max_bar_length = 160
13 -- statbar positions
14 hb.settings.pos_left = { x=0.5, y=1 }
15 hb.settings.pos_right= { x = 0.5, y = 1 }
16 hb.settings.start_offset_left = { x = -175, y = -70 }
17 hb.settings.start_offset_right = { x = 15, y = -70 }
19 hb.settings.vmargin = 24
20 hb.settings.tick = 0.1
22 function hb.value_to_barlength(value, max)
23 if max == 0 then
24 return 0
25 else
26 return math.ceil((value/max) * hb.settings.max_bar_length)
27 end
28 end
30 function hb.get_hudtable(identifier)
31 return hb.hudtables[identifier]
32 end
34 function hb.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, start_hidden, format_string)
35 local hudtable = {}
36 local pos, offset
37 if hb.hudbars_count % 2 == 0 then
38 pos = hb.settings.pos_left
39 offset = {
40 x = hb.settings.start_offset_left.x,
41 y = hb.settings.start_offset_left.y - hb.settings.vmargin * math.floor(hb.hudbars_count/2)
43 else
44 pos = hb.settings.pos_right
45 offset = {
46 x = hb.settings.start_offset_right.x,
47 y = hb.settings.start_offset_right.y - hb.settings.vmargin * math.floor((hb.hudbars_count-1)/2)
49 end
50 if format_string == nil then
51 format_string = "%s: %d/%d"
52 end
54 hudtable.add_all = function(player, start_value, start_max)
55 if start_value == nil then start_value = default_start_value end
56 if start_max == nil then start_max = default_start_max end
57 local ids = {}
58 local state = {}
59 local name = player:get_player_name()
60 local bgscale, iconscale, text, barnumber
61 if start_max == 0 or start_hidden then
62 bgscale = { x=0, y=0 }
63 else
64 bgscale = { x=1, y=1 }
65 end
66 if start_hidden then
67 iconscale = { x=0, y=0 }
68 barnumber = 0
69 text = ""
70 else
71 iconscale = { x=1, y=1 }
72 barnumber = hb.value_to_barlength(start_value, start_max)
73 text = string.format(format_string, label, start_value, start_max)
74 end
75 ids.bg = player:hud_add({
76 hud_elem_type = "image",
77 position = pos,
78 scale = bgscale,
79 text = "hudbars_bar_background.png",
80 alignment = {x=1,y=1},
81 offset = { x = offset.x - 1, y = offset.y - 1 },
83 if textures.icon ~= nil then
84 ids.icon = player:hud_add({
85 hud_elem_type = "image",
86 position = pos,
87 scale = iconscale,
88 text = textures.icon,
89 alignment = {x=-1,y=1},
90 offset = { x = offset.x - 3, y = offset.y },
92 end
93 ids.bar = player:hud_add({
94 hud_elem_type = "statbar",
95 position = pos,
96 text = textures.bar,
97 number = barnumber,
98 alignment = {x=-1,y=-1},
99 offset = offset,
101 ids.text = player:hud_add({
102 hud_elem_type = "text",
103 position = pos,
104 text = text,
105 alignment = {x=1,y=1},
106 number = text_color,
107 direction = 0,
108 offset = { x = offset.x + 2, y = offset.y },
110 -- Do not forget to update hb.get_hudbar_state if you add new fields to the state table
111 state.hidden = start_hidden
112 state.value = start_value
113 state.max = start_max
114 state.text = text
115 state.barlength = hb.value_to_barlength(start_value, start_max)
117 local main_error_text =
118 "[hudbars] Bad initial values of HUD bar identifier “"..tostring(identifier).."” for player "..name..". "
120 if start_max < start_value then
121 minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than start_value ("..start_value..")!")
123 if start_max < 0 then
124 minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than 0!")
126 if start_value < 0 then
127 minetest.log("error", main_error_text.."start_value ("..start_value..") is smaller than 0!")
130 hb.hudtables[identifier].hudids[name] = ids
131 hb.hudtables[identifier].hudstate[name] = state
134 hudtable.identifier = identifier
135 hudtable.format_string = format_string
136 hudtable.label = label
137 hudtable.hudids = {}
138 hudtable.hudstate = {}
140 hb.hudbars_count= hb.hudbars_count + 1
142 hb.hudtables[identifier] = hudtable
145 function hb.init_hudbar(player, identifier, start_value, start_max)
146 hb.hudtables[identifier].add_all(player, start_value, start_max)
149 function hb.change_hudbar(player, identifier, new_value, new_max_value)
150 if new_value == nil and new_max_value == nil then
151 return
154 local name = player:get_player_name()
155 local hudtable = hb.get_hudtable(identifier)
156 local value_changed, max_changed = false, false
158 if new_value ~= nil then
159 if new_value ~= hudtable.hudstate[name].value then
160 hudtable.hudstate[name].value = new_value
161 value_changed = true
163 else
164 new_value = hudtable.hudstate[name].value
166 if new_max_value ~= nil then
167 if new_max_value ~= hudtable.hudstate[name].max then
168 hudtable.hudstate[name].max = new_max_value
169 max_changed = true
171 else
172 new_max_value = hudtable.hudstate[name].max
175 local main_error_text =
176 "[hudbars] Bad call to hb.change_hudbar, identifier: “"..tostring(identifier).."”, player name: “"..name.."”. "
177 if new_max_value < new_value then
178 minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than new_value ("..new_value..")!")
180 if new_max_value < 0 then
181 minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than 0!")
183 if new_value < 0 then
184 minetest.log("error", main_error_text.."new_value ("..new_value..") is smaller than 0!")
187 if hudtable.hudstate[name].hidden == false then
188 if max_changed then
189 if hudtable.hudstate[name].max == 0 then
190 player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
191 else
192 player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
196 if value_changed or max_changed then
197 local new_barlength = hb.value_to_barlength(new_value, new_max_value)
198 if new_barlength ~= hudtable.hudstate[name].barlength then
199 player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(new_value, new_max_value))
200 hudtable.hudstate[name].barlength = new_barlength
203 local new_text = string.format(hudtable.format_string, hudtable.label, new_value, new_max_value)
204 if new_text ~= hudtable.hudstate[name].text then
205 player:hud_change(hudtable.hudids[name].text, "text", new_text)
206 hudtable.hudstate[name].text = new_text
212 function hb.hide_hudbar(player, identifier)
213 local name = player:get_player_name()
214 local hudtable = hb.get_hudtable(identifier)
215 if(hudtable.hudstate[name].hidden == false) then
216 if hudtable.hudids[name].icon ~= nil then
217 player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0})
219 player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
220 player:hud_change(hudtable.hudids[name].bar, "number", 0)
221 player:hud_change(hudtable.hudids[name].text, "text", "")
222 hudtable.hudstate[name].hidden = true
226 function hb.unhide_hudbar(player, identifier)
227 local name = player:get_player_name()
228 local hudtable = hb.get_hudtable(identifier)
229 if(hudtable.hudstate[name].hidden) then
230 local name = player:get_player_name()
231 local value = hudtable.hudstate[name].value
232 local max = hudtable.hudstate[name].max
233 if hudtable.hudids[name].icon ~= nil then
234 player:hud_change(hudtable.hudids[name].icon, "scale", {x=1,y=1})
236 if hudtable.hudstate[name].max ~= 0 then
237 player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
239 player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(value, max))
240 player:hud_change(hudtable.hudids[name].text, "text", tostring(string.format(hudtable.format_string, hudtable.label, value, max)))
241 hudtable.hudstate[name].hidden = false
245 function hb.get_hudbar_state(player, identifier)
246 local ref = hb.get_hudtable(identifier).hudstate[player:get_player_name()]
247 -- Do not forget to update this chunk of code in case the state changes
248 local copy = {
249 hidden = ref.hidden,
250 value = ref.value,
251 max = ref.max,
252 text = ref.text,
253 barlength = ref.barlength,
255 return copy
258 --register built-in HUD bars
259 if minetest.setting_getbool("enable_damage") then
260 hb.register_hudbar("health", 0xFFFFFF, "Health", { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png" }, 20, 20, false)
261 hb.register_hudbar("breath", 0xFFFFFF, "Breath", { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png" }, 10, 10, true)
264 --load custom settings
265 local set = io.open(minetest.get_modpath("hudbars").."/hudbars.conf", "r")
266 if set then
267 dofile(minetest.get_modpath("hudbars").."/hudbars.conf")
268 set:close()
271 local function hide_builtin(player)
272 player:hud_set_flags({healthbar = false, breathbar = false})
276 local function custom_hud(player)
277 if minetest.setting_getbool("enable_damage") then
278 hb.init_hudbar(player, "health", player:get_hp())
279 hb.init_hudbar(player, "breath", math.min(player:get_breath(), 10))
284 -- update built-in HUD bars
285 local function update_hud(player)
286 if minetest.setting_getbool("enable_damage") then
287 --air
288 local air = player:get_breath()
290 if air == 11 then
291 hb.hide_hudbar(player, "breath")
292 else
293 hb.unhide_hudbar(player, "breath")
294 hb.change_hudbar(player, "breath", air)
297 --health
298 hb.change_hudbar(player, "health", player:get_hp())
302 minetest.register_on_joinplayer(function(player)
303 minetest.after(0.5, function()
304 hide_builtin(player)
305 custom_hud(player)
306 end)
307 end)
309 local main_timer = 0
310 local timer = 0
311 local timer2 = 0
312 minetest.after(2.5, function()
313 minetest.register_globalstep(function(dtime)
314 main_timer = main_timer + dtime
315 timer = timer + dtime
316 timer2 = timer2 + dtime
317 if main_timer > hb.settings.tick or timer > 4 then
318 if main_timer > hb.settings.tick then main_timer = 0 end
319 for _,player in ipairs(minetest.get_connected_players()) do
320 -- only proceed if damage is enabled
321 if minetest.setting_getbool("enable_damage") then
322 -- update all hud elements
323 update_hud(player)
328 if timer > 4 then timer = 0 end
329 end)
330 end)