HUD: use the HUD API directly (#92)
Co-authored-by: luk3yx <luk3yx@users.noreply.github.com>
This commit is contained in:
parent
7624c29d96
commit
6e76ef4320
@ -1,167 +0,0 @@
|
||||
--[[
|
||||
From Better HUD mod
|
||||
Copyright (C) BlockMen (2013-2016)
|
||||
Copyright (C) MultiCraft Development Team (2019-2020)
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 3.0 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
]]
|
||||
|
||||
hud, hud_id = {}, {}
|
||||
|
||||
local items, sb_bg = {}, {}
|
||||
|
||||
local function throw_error(msg)
|
||||
core.log("error", "HUD: " .. msg)
|
||||
end
|
||||
|
||||
--
|
||||
-- API
|
||||
--
|
||||
|
||||
function hud.register(name, def)
|
||||
if not name or not def then
|
||||
throw_error("Not enough parameters given")
|
||||
return false
|
||||
end
|
||||
|
||||
if items[name] then
|
||||
throw_error("A statbar with name " .. name .. " already exists")
|
||||
return false
|
||||
end
|
||||
|
||||
-- actually register
|
||||
-- add background first since draworder is based on id
|
||||
if def.hud_elem_type == "statbar" and def.background then
|
||||
sb_bg[name] = table.copy(def)
|
||||
sb_bg[name].text = def.background
|
||||
if not def.autohide_bg and def.max then
|
||||
sb_bg[name].number = def.max
|
||||
end
|
||||
end
|
||||
-- add item itself
|
||||
items[name] = def
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function hud.change_item(player, name, def)
|
||||
if not player or not player:is_player() then
|
||||
return false
|
||||
end
|
||||
|
||||
if not name or not def then
|
||||
throw_error("Not enough parameters given")
|
||||
return false
|
||||
end
|
||||
|
||||
local i_name = player:get_player_name() .. "_" .. name
|
||||
local elem = hud_id[i_name]
|
||||
local item = items[name]
|
||||
|
||||
if not elem then
|
||||
-- throw_error("Given HUD element " .. dump(name) .. " does not exist")
|
||||
return false
|
||||
end
|
||||
|
||||
if def.number then
|
||||
if item.hud_elem_type ~= "statbar" then
|
||||
throw_error("Attempted to change an statbar HUD parameter for text HUD element " .. dump(name))
|
||||
return false
|
||||
end
|
||||
|
||||
if item.max and def.number > item.max then
|
||||
def.number = item.max
|
||||
end
|
||||
player:hud_change(elem.id, "number", def.number)
|
||||
|
||||
-- hide background when set
|
||||
if item.autohide_bg then
|
||||
local bg = hud_id[i_name .. "_bg"]
|
||||
if not bg then
|
||||
throw_error("Given HUD element " .. dump(name) .. "_bg does not exist")
|
||||
return false
|
||||
end
|
||||
|
||||
local num = def.number ~= 0 and (item.max or item.number) or 0
|
||||
player:hud_change(bg.id, "number", num)
|
||||
end
|
||||
elseif def.text then
|
||||
player:hud_change(elem.id, "text", def.text)
|
||||
elseif def.offset then
|
||||
player:hud_change(elem.id, "offset", def.offset)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function hud.remove_item(player, name)
|
||||
if not player or not player:is_player() then
|
||||
return false
|
||||
end
|
||||
|
||||
if not name then
|
||||
throw_error("Not enough parameters given")
|
||||
return false
|
||||
end
|
||||
|
||||
local i_name = player:get_player_name() .. "_" .. name
|
||||
local elem = hud_id[i_name]
|
||||
|
||||
if not elem then
|
||||
throw_error("Given HUD element " .. dump(name) .. " does not exist")
|
||||
return false
|
||||
end
|
||||
|
||||
player:hud_remove(elem.id)
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
--
|
||||
-- Add registered HUD items to joining players
|
||||
--
|
||||
|
||||
-- Following code is placed here to keep HUD ids internal
|
||||
local function add_hud_item(player, name, def)
|
||||
if not player or not name or not def then
|
||||
throw_error("Not enough parameters given")
|
||||
return false
|
||||
end
|
||||
|
||||
local i_name = player:get_player_name() .. "_" .. name
|
||||
hud_id[i_name] = {}
|
||||
hud_id[i_name].id = player:hud_add(def)
|
||||
end
|
||||
|
||||
core.register_on_joinplayer(function(player)
|
||||
-- add the backgrounds for statbars
|
||||
for name, item in pairs(sb_bg) do
|
||||
add_hud_item(player, name .. "_bg", item)
|
||||
end
|
||||
-- and finally the actual HUD items
|
||||
for name, item in pairs(items) do
|
||||
add_hud_item(player, name, item)
|
||||
end
|
||||
end)
|
||||
|
||||
core.register_on_leaveplayer(function(player)
|
||||
local player_name = player:get_player_name()
|
||||
for name, _ in pairs(sb_bg) do
|
||||
sb_bg[player_name .. "_" .. name] = nil
|
||||
end
|
||||
for name, _ in pairs(items) do
|
||||
hud_id[player_name .. "_" .. name] = nil
|
||||
end
|
||||
end)
|
@ -25,7 +25,9 @@ or not core.settings:get_bool("enable_hunger") then
|
||||
return
|
||||
end
|
||||
|
||||
hunger = {}
|
||||
hunger = {
|
||||
hud = {}
|
||||
}
|
||||
|
||||
local function get_setting(key, default)
|
||||
local setting = core.settings:get("hunger." .. key)
|
||||
@ -57,6 +59,7 @@ local settings = hunger.settings
|
||||
|
||||
local min, max = math.min, math.max
|
||||
local vlength = vector.length
|
||||
local tcopy = table.copy
|
||||
|
||||
local attribute = {
|
||||
saturation = "hunger:level",
|
||||
@ -83,9 +86,18 @@ function hunger.get_saturation(player)
|
||||
return tonumber(player:get_meta():get_string(attribute.saturation))
|
||||
end
|
||||
|
||||
function hunger.set_hud_level(player, level)
|
||||
if not is_player(player) then
|
||||
return
|
||||
end
|
||||
|
||||
local hud = hunger.hud[player:get_player_name()]
|
||||
player:hud_change(hud, "number", min(settings.visual_max, level))
|
||||
end
|
||||
|
||||
function hunger.set_saturation(player, level)
|
||||
player:get_meta():set_int(attribute.saturation, level)
|
||||
hud.change_item(player, "hunger", {number = min(settings.visual_max, level)})
|
||||
hunger.set_hud_level(player, level)
|
||||
end
|
||||
|
||||
hunger.registered_on_update_saturations = {}
|
||||
@ -145,14 +157,23 @@ function hunger.is_poisoned(player)
|
||||
return poisoned and poisoned == "yes"
|
||||
end
|
||||
|
||||
function hunger.set_hud_poisoned(player, poisoned)
|
||||
if not is_player(player) then
|
||||
return
|
||||
end
|
||||
|
||||
local hud = hunger.hud[player:get_player_name()]
|
||||
local texture = poisoned and "hunger_poisen.png" or "hunger.png"
|
||||
player:hud_change(hud, "text", texture)
|
||||
end
|
||||
|
||||
function hunger.set_poisoned(player, poisoned)
|
||||
if not is_player(player) then
|
||||
return
|
||||
end
|
||||
|
||||
local texture = poisoned and "hunger_poisen.png" or "hunger.png"
|
||||
hunger.set_hud_poisoned(player, poisoned)
|
||||
local attr = poisoned and "yes" or "no"
|
||||
hud.change_item(player, "hunger", {text = texture})
|
||||
player:get_meta():set_string(attribute.poisoned, attr)
|
||||
end
|
||||
|
||||
@ -298,9 +319,9 @@ local function health_tick()
|
||||
player:set_hp(hp + settings.heal)
|
||||
elseif is_starving then
|
||||
player:set_hp(hp - settings.starve)
|
||||
hud.change_item(player, "hunger", {number = 0})
|
||||
hunger.set_hud_level(player, 0)
|
||||
core.after(0.5, function()
|
||||
hud.change_item(player, "hunger", {number = min(settings.visual_max, saturation)})
|
||||
hunger.set_hud_level(player, min(settings.visual_max, saturation))
|
||||
end)
|
||||
end
|
||||
end
|
||||
@ -341,30 +362,37 @@ function hunger.item_eat(hp_change, user, poison)
|
||||
end
|
||||
end
|
||||
|
||||
hud.register("hunger", {
|
||||
hunger.bar_definition = {
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 1},
|
||||
offset = {x = 8, y = -94},
|
||||
size = {x = 24, y = 24},
|
||||
text = "hunger.png",
|
||||
background = "hunger_gone.png",
|
||||
number = settings.visual_max
|
||||
})
|
||||
text2 = "hunger_gone.png",
|
||||
number = settings.visual_max,
|
||||
item = settings.visual_max,
|
||||
size = {x = 24, y = 24},
|
||||
offset = {x = -265, y = -126}
|
||||
}
|
||||
|
||||
core.register_on_joinplayer(function(player)
|
||||
local level = hunger.get_saturation(player) or settings.level_max
|
||||
local level = hunger.get_saturation(player)
|
||||
if not level then
|
||||
level = settings.level_max
|
||||
player:get_meta():set_int(attribute.saturation, level)
|
||||
end
|
||||
|
||||
-- add HUD
|
||||
if hunger.bar_definition then
|
||||
local def = tcopy(hunger.bar_definition)
|
||||
def.number = min(settings.visual_max, level)
|
||||
hunger.hud[player:get_player_name()] = player:hud_add(def)
|
||||
end
|
||||
|
||||
-- reset poisoned
|
||||
hunger.set_poisoned(player, false)
|
||||
-- set saturation
|
||||
player:get_meta():set_int(attribute.saturation, level)
|
||||
|
||||
-- we must manually update the HUD
|
||||
if level < settings.visual_max then
|
||||
core.after(1, function()
|
||||
hud.change_item(player, "hunger", {number = min(settings.visual_max, level)})
|
||||
end)
|
||||
end
|
||||
|
||||
core.register_on_leaveplayer(function(player)
|
||||
hunger.hud[player:get_player_name()] = nil
|
||||
end)
|
||||
|
||||
local exhaust = hunger.exhaust_player
|
||||
|
@ -31,7 +31,6 @@ assert(loadfile(gamepath .. "falling.lua"))(builtin_shared)
|
||||
dofile(gamepath .. "features.lua")
|
||||
dofile(gamepath .. "voxelarea.lua")
|
||||
dofile(gamepath .. "forceloading.lua")
|
||||
dofile(gamepath .. "hud.lua")
|
||||
dofile(gamepath .. "statbars.lua")
|
||||
dofile(gamepath .. "knockback.lua")
|
||||
dofile(gamepath .. "hunger.lua")
|
||||
|
@ -1,28 +1,44 @@
|
||||
-- cache setting
|
||||
local enable_damage = core.settings:get_bool("enable_damage")
|
||||
local disable_health = false
|
||||
|
||||
local max = math.max
|
||||
local tcopy = table.copy
|
||||
|
||||
local health_bar_definition = {
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 1},
|
||||
offset = {x = -247, y = -94},
|
||||
size = {x = 24, y = 24},
|
||||
text = "heart.png",
|
||||
background = "heart_gone.png",
|
||||
number = 20
|
||||
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)},
|
||||
}
|
||||
|
||||
local breath_bar_definition = {
|
||||
hud_elem_type = "statbar",
|
||||
position = {x = 0.5, y = 1},
|
||||
offset = {x = 8, y = -120},
|
||||
size = {x = 24, y = 24},
|
||||
text = "bubble.png",
|
||||
number = 20
|
||||
text2 = "bubble_gone.png",
|
||||
number = core.PLAYER_MAX_BREATH_DEFAULT,
|
||||
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 scaleToDefault(player, field)
|
||||
-- Scale "hp" or "breath" to the default dimensions
|
||||
local current = player["get_" .. field](player)
|
||||
local nominal = core["PLAYER_MAX_" .. field:upper() .. "_DEFAULT"]
|
||||
local max_display = max(nominal,
|
||||
max(player:get_properties()[field .. "_max"], current))
|
||||
return current / max_display * nominal
|
||||
end
|
||||
|
||||
local function update_builtin_statbars(player)
|
||||
local name = player:get_player_name()
|
||||
|
||||
@ -37,24 +53,45 @@ local function update_builtin_statbars(player)
|
||||
-- our current flags are transmitted by sending them actively
|
||||
player:hud_set_flags(flags)
|
||||
end
|
||||
local hud_id = hud_ids[name]
|
||||
local hud = hud_ids[name]
|
||||
|
||||
if flags.healthbar and not disable_health then
|
||||
hud.change_item(player, "health", {number = player:get_hp()})
|
||||
end
|
||||
|
||||
if flags.breathbar and player:get_breath() < 10 then
|
||||
local number = player:get_breath() * 2
|
||||
if hud_id.id_breathbar == nil then
|
||||
local hud_def = table.copy(breath_bar_definition)
|
||||
if flags.healthbar and enable_damage then
|
||||
local number = scaleToDefault(player, "hp")
|
||||
if hud.id_healthbar == nil then
|
||||
local hud_def = tcopy(health_bar_definition)
|
||||
hud_def.number = number
|
||||
hud_id.id_breathbar = player:hud_add(hud_def)
|
||||
hud.id_healthbar = player:hud_add(hud_def)
|
||||
else
|
||||
player:hud_change(hud_id.id_breathbar, "number", number)
|
||||
player:hud_change(hud.id_healthbar, "number", number)
|
||||
end
|
||||
elseif hud_id.id_breathbar then
|
||||
player:hud_remove(hud_id.id_breathbar)
|
||||
hud_id.id_breathbar = 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
|
||||
|
||||
local breath = player:get_breath()
|
||||
local breath_max = player:get_properties().breath_max
|
||||
if show_breathbar and breath <= breath_max then
|
||||
local number = 2 * scaleToDefault(player, "breath")
|
||||
if not hud.id_breathbar and breath < breath_max then
|
||||
local hud_def = tcopy(breath_bar_definition)
|
||||
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 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
|
||||
end, name, hud.id_breathbar)
|
||||
hud.id_breathbar = nil
|
||||
end
|
||||
end
|
||||
|
||||
@ -73,7 +110,7 @@ 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
|
||||
|
||||
@ -102,16 +139,25 @@ local function player_event_handler(player,eventname)
|
||||
end
|
||||
|
||||
function core.hud_replace_builtin(hud_name, definition)
|
||||
if hud_name == "health" then
|
||||
disable_health = true
|
||||
return true
|
||||
end
|
||||
|
||||
if type(definition) ~= "table" or
|
||||
definition.hud_elem_type ~= "statbar" then
|
||||
return false
|
||||
end
|
||||
|
||||
if hud_name == "health" then
|
||||
health_bar_definition = definition
|
||||
|
||||
for name, ids in pairs(hud_ids) do
|
||||
local player = core.get_player_by_name(name)
|
||||
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 hud_name == "breath" then
|
||||
breath_bar_definition = definition
|
||||
|
||||
@ -131,13 +177,8 @@ end
|
||||
|
||||
-- Append "update_builtin_statbars" as late as possible
|
||||
-- This ensures that the HUD is hidden when the flags are updated in this callback
|
||||
if enable_damage then
|
||||
core.register_on_mods_loaded(function()
|
||||
if not disable_health then
|
||||
hud.register("health", health_bar_definition)
|
||||
core.register_on_joinplayer(update_builtin_statbars)
|
||||
end
|
||||
end)
|
||||
core.register_on_leaveplayer(cleanup_builtin_statbars)
|
||||
core.register_playerevent(player_event_handler)
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user