diff options
Diffstat (limited to 'builtin/game/statbars.lua')
-rw-r--r-- | builtin/game/statbars.lua | 188 |
1 files changed, 105 insertions, 83 deletions
diff --git a/builtin/game/statbars.lua b/builtin/game/statbars.lua index 61a8b9077..78d1d2728 100644 --- a/builtin/game/statbars.lua +++ b/builtin/game/statbars.lua @@ -1,84 +1,100 @@ - -local health_bar_definition = -{ - hud_elem_type = "statbar", - position = { x=0.5, y=1 }, - text = "heart.png", - number = 20, - direction = 0, - size = { x=24, y=24 }, - offset = { x=(-10*24)-25, y=-(48+24+16)}, -} - -local breath_bar_definition = -{ - hud_elem_type = "statbar", - position = { x=0.5, y=1 }, - text = "bubble.png", - number = 20, - direction = 0, - size = { x=24, y=24 }, - offset = {x=25,y=-(48+24+16)}, +-- cache setting +local enable_damage = core.settings:get_bool("enable_damage") + +local bar_definitions = { + hp = { + hud_elem_type = "statbar", + position = {x = 0.5, y = 1}, + text = "heart.png", + text2 = "heart_gone.png", + number = core.PLAYER_MAX_HP_DEFAULT, + item = core.PLAYER_MAX_HP_DEFAULT, + direction = 0, + size = {x = 24, y = 24}, + offset = {x = (-10 * 24) - 25, y = -(48 + 24 + 16)}, + }, + breath = { + hud_elem_type = "statbar", + position = {x = 0.5, y = 1}, + text = "bubble.png", + text2 = "bubble_gone.png", + number = core.PLAYER_MAX_BREATH_DEFAULT * 2, + item = core.PLAYER_MAX_BREATH_DEFAULT * 2, + direction = 0, + size = {x = 24, y = 24}, + offset = {x = 25, y= -(48 + 24 + 16)}, + }, } local hud_ids = {} -local function initialize_builtin_statbars(player) - - if not player:is_player() then - return - end +local function scaleToHudMax(player, field) + -- Scale "hp" or "breath" to the hud maximum dimensions + local current = player["get_" .. field](player) + local nominal = bar_definitions[field].item + local max_display = math.max(player:get_properties()[field .. "_max"], current) + return math.ceil(current / max_display * nominal) +end +local function update_builtin_statbars(player) local name = player:get_player_name() if name == "" then return end - if (hud_ids[name] == nil) then + local flags = player:hud_get_flags() + if not hud_ids[name] then hud_ids[name] = {} -- flags are not transmitted to client on connect, we need to make sure -- our current flags are transmitted by sending them actively - player:hud_set_flags(player:hud_get_flags()) + player:hud_set_flags(flags) end + local hud = hud_ids[name] + + local immortal = player:get_armor_groups().immortal == 1 - if player:hud_get_flags().healthbar and - core.is_yes(core.setting_get("enable_damage")) then - if hud_ids[name].id_healthbar == nil then - health_bar_definition.number = player:get_hp() - hud_ids[name].id_healthbar = player:hud_add(health_bar_definition) + if flags.healthbar and enable_damage and not immortal then + local number = scaleToHudMax(player, "hp") + if hud.id_healthbar == nil then + local hud_def = table.copy(bar_definitions.hp) + hud_def.number = number + hud.id_healthbar = player:hud_add(hud_def) + else + player:hud_change(hud.id_healthbar, "number", number) end - else - if hud_ids[name].id_healthbar ~= nil then - player:hud_remove(hud_ids[name].id_healthbar) - hud_ids[name].id_healthbar = nil + elseif hud.id_healthbar then + player:hud_remove(hud.id_healthbar) + hud.id_healthbar = nil + end + + local show_breathbar = flags.breathbar and enable_damage and not immortal + + local breath = player:get_breath() + local breath_max = player:get_properties().breath_max + if show_breathbar and breath <= breath_max then + local number = scaleToHudMax(player, "breath") + if not hud.id_breathbar and breath < breath_max then + local hud_def = table.copy(bar_definitions.breath) + hud_def.number = number + hud.id_breathbar = player:hud_add(hud_def) + elseif hud.id_breathbar then + player:hud_change(hud.id_breathbar, "number", number) end end - if (player:get_breath() < 11) then - if player:hud_get_flags().breathbar and - core.is_yes(core.setting_get("enable_damage")) then - if hud_ids[name].id_breathbar == nil then - hud_ids[name].id_breathbar = player:hud_add(breath_bar_definition) + if hud.id_breathbar and (not show_breathbar or breath == breath_max) then + core.after(1, function(player_name, breath_bar) + local player = core.get_player_by_name(player_name) + if player then + player:hud_remove(breath_bar) end - else - if hud_ids[name].id_breathbar ~= nil then - player:hud_remove(hud_ids[name].id_breathbar) - hud_ids[name].id_breathbar = nil - end - end - elseif hud_ids[name].id_breathbar ~= nil then - player:hud_remove(hud_ids[name].id_breathbar) - hud_ids[name].id_breathbar = nil + end, name, hud.id_breathbar) + hud.id_breathbar = nil end end local function cleanup_builtin_statbars(player) - - if not player:is_player() then - return - end - local name = player:get_player_name() if name == "" then @@ -93,65 +109,67 @@ local function player_event_handler(player,eventname) local name = player:get_player_name() - if name == "" then + if name == "" or not hud_ids[name] then return end if eventname == "health_changed" then - initialize_builtin_statbars(player) + update_builtin_statbars(player) - if hud_ids[name].id_healthbar ~= nil then - player:hud_change(hud_ids[name].id_healthbar,"number",player:get_hp()) + if hud_ids[name].id_healthbar then return true end end if eventname == "breath_changed" then - initialize_builtin_statbars(player) + update_builtin_statbars(player) - if hud_ids[name].id_breathbar ~= nil then - player:hud_change(hud_ids[name].id_breathbar,"number",player:get_breath()*2) + if hud_ids[name].id_breathbar then return true end end - if eventname == "hud_changed" then - initialize_builtin_statbars(player) + if eventname == "hud_changed" or eventname == "properties_changed" then + update_builtin_statbars(player) return true end return false end -function core.hud_replace_builtin(name, definition) - - if definition == nil or - type(definition) ~= "table" or - definition.hud_elem_type ~= "statbar" then +function core.hud_replace_builtin(hud_name, definition) + if type(definition) ~= "table" or + definition.hud_elem_type ~= "statbar" then return false end - if name == "health" then - health_bar_definition = definition + definition = table.copy(definition) + + if hud_name == "health" then + definition.item = definition.item or definition.number or core.PLAYER_MAX_HP_DEFAULT + bar_definitions.hp = definition - for name,ids in pairs(hud_ids) do + for name, ids in pairs(hud_ids) do local player = core.get_player_by_name(name) - if player and hud_ids[name].id_healthbar then - player:hud_remove(hud_ids[name].id_healthbar) - initialize_builtin_statbars(player) + if player and ids.id_healthbar then + player:hud_remove(ids.id_healthbar) + ids.id_healthbar = nil + update_builtin_statbars(player) end end return true end - if name == "breath" then - breath_bar_definition = definition + if hud_name == "breath" then + definition.item = definition.item or definition.number or core.PLAYER_MAX_BREATH_DEFAULT + bar_definitions.breath = definition - for name,ids in pairs(hud_ids) do + for name, ids in pairs(hud_ids) do local player = core.get_player_by_name(name) - if player and hud_ids[name].id_breathbar then - player:hud_remove(hud_ids[name].id_breathbar) - initialize_builtin_statbars(player) + if player and ids.id_breathbar then + player:hud_remove(ids.id_breathbar) + ids.id_breathbar = nil + update_builtin_statbars(player) end end return true @@ -160,6 +178,10 @@ function core.hud_replace_builtin(name, definition) return false end -core.register_on_joinplayer(initialize_builtin_statbars) +-- Append "update_builtin_statbars" as late as possible +-- This ensures that the HUD is hidden when the flags are updated in this callback +core.register_on_mods_loaded(function() + core.register_on_joinplayer(update_builtin_statbars) +end) core.register_on_leaveplayer(cleanup_builtin_statbars) core.register_playerevent(player_event_handler) |