Copy-editing in API.md
[minetest_hudbars.git] / init.lua
blob32ac1bfebf0cbca1412a25ec1b37dac98fb77349
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.init_hudbar(player, identifier, start_value, start_max)
155 hud.hudtables[identifier].add_all(player, start_value, start_max)
158 function hud.change_hudbar(player, identifier, new_value, new_max_value)
159 if new_value == nil and new_max_value == nil then
160 return
163 local name = player:get_player_name()
164 local hudtable = hud.get_hudtable(identifier)
166 if new_value ~= nil then
167 hudtable.hudstate[name].value = new_value
168 else
169 new_value = hudtable.hudstate[name].value
171 if new_max_value ~= nil then
172 hudtable.hudstate[name].max = new_max_value
173 else
174 new_max_value = hudtable.hudstate[name].max
177 if hudtable.hudstate[name].hidden == false then
178 if hudtable.hudstate[name].max == 0 then
179 player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
180 else
181 player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
183 player:hud_change(hudtable.hudids[name].bar, "number", hud.value_to_barlength(new_value, new_max_value))
184 player:hud_change(hudtable.hudids[name].text, "text",
185 tostring(string.format(hudtable.format_string, hudtable.label, new_value, new_max_value))
190 function hud.hide_hudbar(player, identifier)
191 local name = player:get_player_name()
192 local hudtable = hud.get_hudtable(identifier)
193 if(hudtable.hudstate[name].hidden == false) then
194 player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0})
195 player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
196 player:hud_change(hudtable.hudids[name].bar, "number", 0)
197 player:hud_change(hudtable.hudids[name].text, "text", "")
198 hudtable.hudstate[name].hidden = true
202 function hud.unhide_hudbar(player, identifier)
203 local name = player:get_player_name()
204 local hudtable = hud.get_hudtable(identifier)
205 if(hudtable.hudstate[name].hidden) then
206 local name = player:get_player_name()
207 local value = hudtable.hudstate[name].value
208 local max = hudtable.hudstate[name].max
209 player:hud_change(hudtable.hudids[name].icon, "scale", {x=1,y=1})
210 if hudtable.hudstate[name].max ~= 0 then
211 player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
213 player:hud_change(hudtable.hudids[name].bar, "number", hud.value_to_barlength(value, max))
214 player:hud_change(hudtable.hudids[name].text, "text", tostring(string.format(hudtable.format_string, hudtable.label, value, max)))
215 hudtable.hudstate[name].hidden = false
220 --load custom settings
221 local set = io.open(minetest.get_modpath("hudbars").."/hud.conf", "r")
222 if set then
223 dofile(minetest.get_modpath("hudbars").."/hud.conf")
224 set:close()
227 local function hide_builtin(player)
228 player:hud_set_flags({crosshair = true, hotbar = true, healthbar = false, wielditem = true, breathbar = false})
232 local function custom_hud(player)
233 local name = player:get_player_name()
235 if minetest.setting_getbool("enable_damage") then
236 --health
237 health_hud_icon[name] = player:hud_add({
238 hud_elem_type = "image",
239 position = HUD_HEALTH_POS,
240 scale = { x = 1, y = 1 },
241 text = "hudbars_icon_health.png",
242 alignment = {x=-1,y=1},
243 offset = { x = HUD_HEALTH_OFFSET.x - 3, y = HUD_HEALTH_OFFSET.y },
245 health_hud_bg[name] = player:hud_add({
246 hud_elem_type = "image",
247 position = HUD_HEALTH_POS,
248 scale = { x = 1, y = 1 },
249 text = "hudbars_bar_background.png",
250 alignment = {x=1,y=1},
251 offset = { x = HUD_HEALTH_OFFSET.x - 1, y = HUD_HEALTH_OFFSET.y - 1 },
253 health_hud[name] = player:hud_add({
254 hud_elem_type = "statbar",
255 position = HUD_HEALTH_POS,
256 text = "hudbars_bar_health.png",
257 number = hud.value_to_barlength(player:get_hp(), 20),
258 alignment = {x=-1,y=-1},
259 offset = HUD_HEALTH_OFFSET,
261 health_hud_text[name] = player:hud_add({
262 hud_elem_type = "text",
263 position = HUD_HEALTH_POS,
264 text = tostring(string.format("Health: %d/%d", player:get_hp(), 20)),
265 alignment = {x=1,y=1},
266 number = 0xFFFFFF,
267 direction = 0,
268 offset = { x = HUD_HEALTH_OFFSET.x + 2, y = HUD_HEALTH_OFFSET.y },
271 --air
272 local airnumber, airtext, airscale
273 local air = player:get_breath()
274 if air == 11 then
275 airnumber = 0
276 airtext = ""
277 airscale = {x=0, y=0}
278 else
279 airnumber = hud.value_to_barlength(math.min(air, 10), 10)
280 airtext = tostring(string.format("Breath: %d/%d", math.min(air, 10), 10))
281 airscale = {x=1, y=1}
283 air_hud_icon[name] = player:hud_add({
284 hud_elem_type = "image",
285 position = HUD_AIR_POS,
286 scale = airscale,
287 text = "hudbars_icon_breath.png",
288 alignment = {x=-1,y=1},
289 offset = { x = HUD_AIR_OFFSET.x - 3, y = HUD_AIR_OFFSET.y },
291 air_hud_bg[name] = player:hud_add({
292 hud_elem_type = "image",
293 position = HUD_AIR_POS,
294 scale = airscale,
295 text = "hudbars_bar_background.png",
296 alignment = {x=1,y=1},
297 offset = { x = HUD_AIR_OFFSET.x - 1, y = HUD_AIR_OFFSET.y - 1 },
299 air_hud[name] = player:hud_add({
300 hud_elem_type = "statbar",
301 position = HUD_AIR_POS,
302 text = "hudbars_bar_breath.png",
303 number = airnumber,
304 alignment = {x=-1,y=-1},
305 offset = HUD_AIR_OFFSET,
307 air_hud_text[name] = player:hud_add({
308 hud_elem_type = "text",
309 position = HUD_AIR_POS,
310 text = airtext,
311 alignment = {x=1,y=1},
312 number = 0xFFFFFF,
313 direction = 0,
314 offset = { x = HUD_AIR_OFFSET.x + 2, y = HUD_AIR_OFFSET.y },
321 -- update hud elemtens if value has changed
322 local function update_hud(player)
323 local name = player:get_player_name()
324 --air
325 local air = tonumber(hud.air[name])
326 if player:get_breath() ~= air then
327 air = player:get_breath()
328 hud.air[name] = air
329 local airnumber, airtext, airscale
330 if air == 11 then
331 airnumber = 0
332 airtext = ""
333 airscale = {x=0, y=0}
334 else
335 airnumber = hud.value_to_barlength(math.min(air, 10), 10)
336 airtext = tostring(string.format("Breath: %d/%d", math.min(player:get_breath(), 10), 10))
337 airscale = {x=1, y=1}
339 player:hud_change(air_hud[name], "number", airnumber)
340 player:hud_change(air_hud_text[name], "text", airtext)
341 player:hud_change(air_hud_icon[name], "scale", airscale)
342 player:hud_change(air_hud_bg[name], "scale", airscale)
344 --health
345 local hp = tonumber(hud.health[name])
346 if player:get_hp() ~= hp then
347 hp = player:get_hp()
348 hud.health[name] = hp
349 player:hud_change(health_hud[name], "number", hud.value_to_barlength(hp, 20))
350 player:hud_change(health_hud_text[name], "text",
351 tostring(string.format("Health: %d/%d", hp, 20))
357 minetest.register_on_joinplayer(function(player)
358 local name = player:get_player_name()
359 local inv = player:get_inventory()
360 hud.health[name] = player:get_hp()
361 local air = player:get_breath()
362 hud.air[name] = air
363 minetest.after(0.5, function()
364 hide_builtin(player)
365 custom_hud(player)
366 end)
367 end)
369 local main_timer = 0
370 local timer = 0
371 local timer2 = 0
372 minetest.after(2.5, function()
373 minetest.register_globalstep(function(dtime)
374 main_timer = main_timer + dtime
375 timer = timer + dtime
376 timer2 = timer2 + dtime
377 if main_timer > HUD_TICK or timer > 4 then
378 if main_timer > HUD_TICK then main_timer = 0 end
379 for _,player in ipairs(minetest.get_connected_players()) do
380 local name = player:get_player_name()
382 -- only proceed if damage is enabled
383 if minetest.setting_getbool("enable_damage") then
384 local hp = player:get_hp()
386 -- update all hud elements
387 update_hud(player)
393 if timer > 4 then timer = 0 end
394 end)
395 end)