Use identifier instead of table in API functions
[minetest_hudbars.git] / init.lua
blobe63956fe0ae38ce534c7e89198db9132fe300c5b
1 hud = {}
3 -- HUD statbar values
4 hud.health = {}
5 hud.air = {}
7 hud.hudtables = {}
9 -- number of registered HUD bars
10 hud.hudbars_count = 0
12 -- HUD item ids
13 local health_hud = {}
14 local health_hud_text = {}
15 local health_hud_icon = {}
16 local health_hud_bg = {}
17 local air_hud = {}
18 local air_hud_text = {}
19 local air_hud_icon = {}
20 local air_hud_bg = {}
22 -- default settings
24 HUD_SCALEABLE = false
25 HUD_BARLENGTH = 160
27 -- statbar positions
28 HUD_HEALTH_POS = {x=0.5,y=0.9}
29 HUD_HEALTH_OFFSET = {x=-175, y=2}
30 HUD_AIR_POS = {x=0.5,y=0.9}
31 HUD_AIR_OFFSET = {x=15,y=2}
33 -- dirty way to check for new statbars
34 if dump(minetest.hud_replace_builtin) ~= "nil" then
35 HUD_SCALEABLE = true
36 HUD_HEALTH_POS = {x=0.5,y=1}
37 HUD_HEALTH_OFFSET = {x=-175, y=-70}
38 HUD_AIR_POS = {x=0.5,y=1}
39 HUD_AIR_OFFSET = {x=15,y=-70}
40 end
42 HUD_CUSTOM_POS_LEFT = HUD_HEALTH_POS
43 HUD_CUSTOM_POS_RIGHT = HUD_AIR_POS
45 HUD_CUSTOM_VMARGIN = 24
46 if minetest.setting_getbool("enable_damage") then
47 HUD_CUSTOM_START_OFFSET_LEFT = {x=HUD_HEALTH_OFFSET.x, y=HUD_HEALTH_OFFSET.y - HUD_CUSTOM_VMARGIN}
48 HUD_CUSTOM_START_OFFSET_RIGHT = {x=HUD_AIR_OFFSET.x, y=HUD_AIR_OFFSET.y - HUD_CUSTOM_VMARGIN}
49 else
50 HUD_CUSTOM_START_OFFSET_LEFT = {x=HUD_HEALTH_OFFSET.x, y=HUD_HEALTH_OFFSET.y }
51 HUD_CUSTOM_START_OFFSET_RIGHT = {x=HUD_AIR_OFFSET.x, y=HUD_AIR_OFFSET.y }
52 end
54 HUD_TICK = 0.1
56 function hud.value_to_barlength(value, max)
57 if max == 0 then
58 return 0
59 else
60 return math.ceil((value/max) * HUD_BARLENGTH)
61 end
62 end
64 function hud.get_hudtable(identifier)
65 return hud.hudtables[identifier]
66 end
68 function hud.register_hudbar(identifier, text_color, label, textures, default_start_value, default_start_max, start_hide, format_string)
69 local hudtable = {}
70 local pos, offset
71 if hud.hudbars_count % 2 == 0 then
72 pos = HUD_CUSTOM_POS_LEFT
73 offset = {
74 x = HUD_CUSTOM_START_OFFSET_LEFT.x,
75 y = HUD_CUSTOM_START_OFFSET_LEFT.y - HUD_CUSTOM_VMARGIN * math.floor(hud.hudbars_count/2)
77 else
78 pos = HUD_CUSTOM_POS_RIGHT
79 offset = {
80 x = HUD_CUSTOM_START_OFFSET_RIGHT.x,
81 y = HUD_CUSTOM_START_OFFSET_RIGHT.y - HUD_CUSTOM_VMARGIN * math.floor((hud.hudbars_count-1)/2)
83 end
84 if format_string == nil then
85 format_string = "%s: %d/%d"
86 end
88 hudtable.add_all = function(player, start_value, start_max)
89 if start_value == nil then start_value = default_start_value end
90 if start_max == nil then start_max = default_start_max end
91 local ids = {}
92 local state = {}
93 local name = player:get_player_name()
94 local bgscale
95 if start_max == 0 then
96 bgscale = { x=0, y=0 }
97 else
98 bgscale = { x=1, y=1 }
99 end
100 ids.bg = player:hud_add({
101 hud_elem_type = "image",
102 position = pos,
103 scale = bgscale,
104 text = "hudbars_bar_background.png",
105 alignment = {x=1,y=1},
106 offset = { x = offset.x - 1, y = offset.y - 1 },
108 if textures.icon ~= nil then
109 ids.icon = player:hud_add({
110 hud_elem_type = "image",
111 position = pos,
112 scale = { x = 1, y = 1 },
113 text = textures.icon,
114 alignment = {x=-1,y=1},
115 offset = { x = offset.x - 3, y = offset.y },
118 ids.bar = player:hud_add({
119 hud_elem_type = "statbar",
120 position = pos,
121 text = textures.bar,
122 number = hud.value_to_barlength(start_value, start_max),
123 alignment = {x=-1,y=-1},
124 offset = offset,
126 ids.text = player:hud_add({
127 hud_elem_type = "text",
128 position = pos,
129 text = tostring(string.format(format_string, label, start_value, start_max)),
130 alignment = {x=1,y=1},
131 number = text_color,
132 direction = 0,
133 offset = { x = offset.x + 2, y = offset.y },
135 state.hidden = start_hide
136 state.value = start_value
137 state.max = start_max
139 hud.hudtables[identifier].hudids[name] = ids
140 hud.hudtables[identifier].hudstate[name] = state
143 hudtable.identifier = identifier
144 hudtable.format_string = format_string
145 hudtable.label = label
146 hudtable.hudids = {}
147 hudtable.hudstate = {}
149 hud.hudbars_count= hud.hudbars_count + 1
151 hud.hudtables[identifier] = hudtable
154 function hud.change_hudbar(player, identifier, new_value, new_max_value)
155 local name = player:get_player_name()
156 local hudtable = hud.get_hudtable(identifier)
157 hudtable.hudstate[name].value = new_value
158 hudtable.hudstate[name].max = new_max_value
159 if hudtable.hudstate[name].hidden == false then
160 if hudtable.hudstate[name].max == 0 then
161 player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
162 else
163 player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
165 player:hud_change(hudtable.hudids[name].bar, "number", hud.value_to_barlength(new_value, new_max_value))
166 player:hud_change(hudtable.hudids[name].text, "text",
167 tostring(string.format(hudtable.format_string, hudtable.label, new_value, new_max_value))
172 function hud.hide_hudbar(player, identifier)
173 local name = player:get_player_name()
174 local hudtable = hud.get_hudtable(identifier)
175 if(hudtable.hudstate[name].hidden == false) then
176 player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0})
177 player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
178 player:hud_change(hudtable.hudids[name].bar, "number", 0)
179 player:hud_change(hudtable.hudids[name].text, "text", "")
180 hudtable.hudstate[name].hidden = true
184 function hud.unhide_hudbar(player, identifier)
185 local name = player:get_player_name()
186 local hudtable = hud.get_hudtable(identifier)
187 if(hudtable.hudstate[name].hidden) then
188 local name = player:get_player_name()
189 local value = hudtable.hudstate[name].value
190 local max = hudtable.hudstate[name].max
191 player:hud_change(hudtable.hudids[name].icon, "scale", {x=1,y=1})
192 if hudtable.hudstate[name].max ~= 0 then
193 player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
195 player:hud_change(hudtable.hudids[name].bar, "number", hud.value_to_barlength(value, max))
196 player:hud_change(hudtable.hudids[name].text, "text", tostring(string.format(hudtable.format_string, hudtable.label, value, max)))
197 hudtable.hudstate[name].hidden = false
202 --load custom settings
203 local set = io.open(minetest.get_modpath("hudbars").."/hud.conf", "r")
204 if set then
205 dofile(minetest.get_modpath("hudbars").."/hud.conf")
206 set:close()
209 local function hide_builtin(player)
210 player:hud_set_flags({crosshair = true, hotbar = true, healthbar = false, wielditem = true, breathbar = false})
214 local function custom_hud(player)
215 local name = player:get_player_name()
217 if minetest.setting_getbool("enable_damage") then
218 --health
219 health_hud_icon[name] = player:hud_add({
220 hud_elem_type = "image",
221 position = HUD_HEALTH_POS,
222 scale = { x = 1, y = 1 },
223 text = "hudbars_icon_health.png",
224 alignment = {x=-1,y=1},
225 offset = { x = HUD_HEALTH_OFFSET.x - 3, y = HUD_HEALTH_OFFSET.y },
227 health_hud_bg[name] = player:hud_add({
228 hud_elem_type = "image",
229 position = HUD_HEALTH_POS,
230 scale = { x = 1, y = 1 },
231 text = "hudbars_bar_background.png",
232 alignment = {x=1,y=1},
233 offset = { x = HUD_HEALTH_OFFSET.x - 1, y = HUD_HEALTH_OFFSET.y - 1 },
235 health_hud[name] = player:hud_add({
236 hud_elem_type = "statbar",
237 position = HUD_HEALTH_POS,
238 text = "hudbars_bar_health.png",
239 number = hud.value_to_barlength(player:get_hp(), 20),
240 alignment = {x=-1,y=-1},
241 offset = HUD_HEALTH_OFFSET,
243 health_hud_text[name] = player:hud_add({
244 hud_elem_type = "text",
245 position = HUD_HEALTH_POS,
246 text = tostring(string.format("Health: %d/%d", player:get_hp(), 20)),
247 alignment = {x=1,y=1},
248 number = 0xFFFFFF,
249 direction = 0,
250 offset = { x = HUD_HEALTH_OFFSET.x + 2, y = HUD_HEALTH_OFFSET.y },
253 --air
254 local airnumber, airtext, airscale
255 local air = player:get_breath()
256 if air == 11 then
257 airnumber = 0
258 airtext = ""
259 airscale = {x=0, y=0}
260 else
261 airnumber = hud.value_to_barlength(math.min(air, 10), 10)
262 airtext = tostring(string.format("Breath: %d/%d", math.min(air, 10), 10))
263 airscale = {x=1, y=1}
265 air_hud_icon[name] = player:hud_add({
266 hud_elem_type = "image",
267 position = HUD_AIR_POS,
268 scale = airscale,
269 text = "hudbars_icon_breath.png",
270 alignment = {x=-1,y=1},
271 offset = { x = HUD_AIR_OFFSET.x - 3, y = HUD_AIR_OFFSET.y },
273 air_hud_bg[name] = player:hud_add({
274 hud_elem_type = "image",
275 position = HUD_AIR_POS,
276 scale = airscale,
277 text = "hudbars_bar_background.png",
278 alignment = {x=1,y=1},
279 offset = { x = HUD_AIR_OFFSET.x - 1, y = HUD_AIR_OFFSET.y - 1 },
281 air_hud[name] = player:hud_add({
282 hud_elem_type = "statbar",
283 position = HUD_AIR_POS,
284 text = "hudbars_bar_breath.png",
285 number = airnumber,
286 alignment = {x=-1,y=-1},
287 offset = HUD_AIR_OFFSET,
289 air_hud_text[name] = player:hud_add({
290 hud_elem_type = "text",
291 position = HUD_AIR_POS,
292 text = airtext,
293 alignment = {x=1,y=1},
294 number = 0xFFFFFF,
295 direction = 0,
296 offset = { x = HUD_AIR_OFFSET.x + 2, y = HUD_AIR_OFFSET.y },
303 -- update hud elemtens if value has changed
304 local function update_hud(player)
305 local name = player:get_player_name()
306 --air
307 local air = tonumber(hud.air[name])
308 if player:get_breath() ~= air then
309 air = player:get_breath()
310 hud.air[name] = air
311 local airnumber, airtext, airscale
312 if air == 11 then
313 airnumber = 0
314 airtext = ""
315 airscale = {x=0, y=0}
316 else
317 airnumber = hud.value_to_barlength(math.min(air, 10), 10)
318 airtext = tostring(string.format("Breath: %d/%d", math.min(player:get_breath(), 10), 10))
319 airscale = {x=1, y=1}
321 player:hud_change(air_hud[name], "number", airnumber)
322 player:hud_change(air_hud_text[name], "text", airtext)
323 player:hud_change(air_hud_icon[name], "scale", airscale)
324 player:hud_change(air_hud_bg[name], "scale", airscale)
326 --health
327 local hp = tonumber(hud.health[name])
328 if player:get_hp() ~= hp then
329 hp = player:get_hp()
330 hud.health[name] = hp
331 player:hud_change(health_hud[name], "number", hud.value_to_barlength(hp, 20))
332 player:hud_change(health_hud_text[name], "text",
333 tostring(string.format("Health: %d/%d", hp, 20))
339 minetest.register_on_joinplayer(function(player)
340 local name = player:get_player_name()
341 local inv = player:get_inventory()
342 hud.health[name] = player:get_hp()
343 local air = player:get_breath()
344 hud.air[name] = air
345 minetest.after(0.5, function()
346 hide_builtin(player)
347 custom_hud(player)
348 end)
349 end)
351 local main_timer = 0
352 local timer = 0
353 local timer2 = 0
354 minetest.after(2.5, function()
355 minetest.register_globalstep(function(dtime)
356 main_timer = main_timer + dtime
357 timer = timer + dtime
358 timer2 = timer2 + dtime
359 if main_timer > HUD_TICK or timer > 4 then
360 if main_timer > HUD_TICK then main_timer = 0 end
361 for _,player in ipairs(minetest.get_connected_players()) do
362 local name = player:get_player_name()
364 -- only proceed if damage is enabled
365 if minetest.setting_getbool("enable_damage") then
366 local hp = player:get_hp()
368 -- update all hud elements
369 update_hud(player)
375 if timer > 4 then timer = 0 end
376 end)
377 end)