forked from VoxeLibre/VoxeLibre
New lua breath system, respiration enchant and water breating support
This commit is contained in:
parent
65d6cb1d83
commit
69bb75036e
|
@ -52,3 +52,5 @@ else
|
|||
hb.settings.sorting_reverse[tonumber(v)] = k
|
||||
end
|
||||
end
|
||||
|
||||
hb.settings.breath_max = hb.load_setting("mcl_breath_max", "number", 10)
|
||||
|
|
|
@ -16,6 +16,7 @@ hb = {
|
|||
settings = {},
|
||||
-- Table which contains all players with active default HUD bars (only for internal use)
|
||||
players = {},
|
||||
breath_time = {},
|
||||
}
|
||||
|
||||
function hb.load_setting(sname, stype, defaultval, valid_values)
|
||||
|
@ -499,6 +500,17 @@ local function hide_builtin(player)
|
|||
player:hud_set_flags(flags)
|
||||
end
|
||||
|
||||
function hb.get_breath(player)
|
||||
local breath = tonumber(player:get_meta():get_string("mcl_hudbars:breath")) or hb.settings.breath_max
|
||||
return breath
|
||||
end
|
||||
|
||||
function hb.set_breath(player, value, update_hudbar)
|
||||
player:get_meta():set_string("mcl_hudbars:breath", tostring(value))
|
||||
if update_hudbar == true then
|
||||
update_breath(player)
|
||||
end
|
||||
end
|
||||
|
||||
local function custom_hud(player)
|
||||
if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then
|
||||
|
@ -511,8 +523,9 @@ local function custom_hud(player)
|
|||
local hp = player:get_hp()
|
||||
local hp_max = player:get_properties().hp_max
|
||||
hb.init_hudbar(player, "health", math.min(hp, hp_max), hp_max, hide)
|
||||
local breath = player:get_breath()
|
||||
local breath_max = player:get_properties().breath_max
|
||||
local breath = hb.get_breath(player)
|
||||
local breath_max = hb.settings.breath_max
|
||||
hb.set_breath(player, math.min(breath_max, math.max(0, breath)))
|
||||
local hide_breath
|
||||
if breath >= breath_max and hb.settings.autohide_breath == true then hide_breath = true else hide_breath = false end
|
||||
hb.init_hudbar(player, "breath", math.min(breath, breath_max), breath_max, hide_breath or hide)
|
||||
|
@ -526,23 +539,66 @@ local function update_health(player)
|
|||
hb.change_hudbar(player, "health", hp, hp_max)
|
||||
end
|
||||
|
||||
local function update_breath(player, in_water)
|
||||
local breath = hb.get_breath(player)
|
||||
local breath_max = hb.settings.breath_max
|
||||
if breath >= breath_max and hb.settings.autohide_breath == true and not in_water then
|
||||
hb.hide_hudbar(player, "breath")
|
||||
else
|
||||
hb.unhide_hudbar(player, "breath")
|
||||
hb.change_hudbar(player, "breath", math.min(breath, breath_max), breath_max)
|
||||
end
|
||||
end
|
||||
|
||||
local function do_breath_tick(player, dtime)
|
||||
-- don't use default breath
|
||||
player:set_breath(player:get_properties().breath_max)
|
||||
|
||||
local breath_max = hb.settings.breath_max
|
||||
local player_name = player:get_player_name()
|
||||
local node_head = mcl_playerinfo[player_name].node_head
|
||||
local in_water = node_head and minetest.get_item_group(node_head, "water") > 0
|
||||
local current_breath = hb.get_breath(player)
|
||||
|
||||
local helmet = player:get_inventory():get_stack("armor", 2)
|
||||
local respiration = mcl_enchanting.get_enchantment(helmet, "respiration") or 0
|
||||
local scaled_dtime = dtime / (respiration + 1)
|
||||
|
||||
if in_water and not mcl_potions.has_effect(player, "water_breathing") then
|
||||
-- in water, use respiration scaled_dtime
|
||||
hb.breath_time[player] = (hb.breath_time[player] or 0) + scaled_dtime
|
||||
if current_breath > 0 and hb.breath_time[player] > 1.5 then
|
||||
-- min used to stop breath changing rapidly after extreme server lag
|
||||
hb.breath_time[player] = math.min(hb.breath_time[player] - 1.5, 1.5)
|
||||
hb.set_breath(player, current_breath - 1)
|
||||
elseif current_breath == 0 and hb.breath_time[player] > 1 then
|
||||
hb.breath_time[player] = math.min(hb.breath_time[player] - 1, 1)
|
||||
if player:get_hp() > 0 then
|
||||
mcl_util.deal_damage(player, 2, {type = "drown"})
|
||||
end
|
||||
end
|
||||
else
|
||||
-- out of water/has water breathing, use normal dtime
|
||||
hb.breath_time[player] = (hb.breath_time[player] or 0) + dtime
|
||||
if current_breath == breath_max then hb.breath_time[player] = 0
|
||||
elseif hb.breath_time[player] > 0.2 then
|
||||
-- no min here as players should be able to regen breath fast despite server lag
|
||||
hb.breath_time[player] = hb.breath_time[player] - 0.2
|
||||
hb.set_breath(player, current_breath + 1)
|
||||
end
|
||||
end
|
||||
return in_water
|
||||
end
|
||||
|
||||
-- update built-in HUD bars
|
||||
local function update_hud(player, has_damage)
|
||||
local function update_hud(player, has_damage, in_water)
|
||||
if not player_exists(player) then return end
|
||||
if has_damage then
|
||||
if hb.settings.forceload_default_hudbars then
|
||||
hb.unhide_hudbar(player, "health")
|
||||
end
|
||||
--air
|
||||
local breath_max = player:get_properties().breath_max
|
||||
local breath = player:get_breath()
|
||||
|
||||
if breath >= breath_max and hb.settings.autohide_breath == true then
|
||||
hb.hide_hudbar(player, "breath")
|
||||
else
|
||||
hb.unhide_hudbar(player, "breath")
|
||||
hb.change_hudbar(player, "breath", math.min(breath, breath_max), breath_max)
|
||||
end
|
||||
update_breath(player, in_water)
|
||||
--health
|
||||
update_health(player)
|
||||
elseif hb.settings.forceload_default_hudbars then
|
||||
|
@ -559,10 +615,15 @@ end)
|
|||
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
update_health(player)
|
||||
hb.hide_hudbar(player, "breath")
|
||||
|
||||
local breath_max = hb.settings.breath_max
|
||||
hb.breath_time[player] = 0
|
||||
hb.set_breath(player, breath_max)
|
||||
update_breath(player)
|
||||
end)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
-- minetest.debug("Player joined:", player)
|
||||
hide_builtin(player)
|
||||
custom_hud(player)
|
||||
hb.players[player:get_player_name()] = player
|
||||
|
@ -570,23 +631,30 @@ end)
|
|||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
hb.players[player:get_player_name()] = nil
|
||||
hb.breath_time[player] = nil
|
||||
end)
|
||||
|
||||
local main_timer = 0
|
||||
local timer = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
local is_hud_step = false
|
||||
local has_dmg
|
||||
main_timer = main_timer + dtime
|
||||
timer = timer + dtime
|
||||
if main_timer > hb.settings.tick or timer > 4 then
|
||||
if main_timer > hb.settings.tick then main_timer = 0 end
|
||||
-- only proceed if damage is enabled
|
||||
local has_dmg = minetest.settings:get_bool("enable_damage")
|
||||
has_dmg = minetest.settings:get_bool("enable_damage")
|
||||
if has_dmg or hb.settings.forceload_default_hudbars then
|
||||
for _, player in pairs(hb.players) do
|
||||
-- update all hud elements
|
||||
update_hud(player, has_dmg)
|
||||
end
|
||||
is_hud_step = true
|
||||
end
|
||||
end
|
||||
if timer > 4 then timer = 0 end
|
||||
for _, player in pairs(hb.players) do
|
||||
-- update all hud elements
|
||||
local in_water = do_breath_tick(player, dtime)
|
||||
if is_hud_step then
|
||||
update_hud(player, has_dmg, in_water)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -586,8 +586,8 @@ mcl_enchanting.enchantments.quick_charge = {
|
|||
inv_tool_tab = false,
|
||||
}
|
||||
|
||||
-- unimplemented
|
||||
--[[mcl_enchanting.enchantments.respiration = {
|
||||
-- implemented in mcl_hudbars
|
||||
mcl_enchanting.enchantments.respiration = {
|
||||
name = S("Respiration"),
|
||||
max_level = 3,
|
||||
primary = {armor_head = true},
|
||||
|
@ -603,7 +603,7 @@ mcl_enchanting.enchantments.quick_charge = {
|
|||
power_range_table = {{10, 40}, {20, 50}, {30, 60}},
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}]]--
|
||||
}
|
||||
|
||||
-- requires missing MineClone2 feature
|
||||
--[[mcl_enchanting.enchantments.riptide = {
|
||||
|
|
|
@ -303,12 +303,6 @@ mcl_potions.register_effect({
|
|||
res_condition = function(object)
|
||||
return (not object:is_player()) -- TODO add support for breath setting for mobs
|
||||
end,
|
||||
on_step = function(dtime, object, factor, duration)
|
||||
if object:get_breath() then
|
||||
hb.hide_hudbar(object, "breath")
|
||||
if object:get_breath() < 10 then object:set_breath(10) end
|
||||
end
|
||||
end,
|
||||
particle_color = "#2E5299",
|
||||
uses_factor = false,
|
||||
})
|
||||
|
|
|
@ -109,6 +109,10 @@ mcl_health_regen_delay (Health regen delay) float 0.5 0
|
|||
# Default: 1.61 s
|
||||
mcl_eating_delay (Eating delay) float 1.61 0
|
||||
|
||||
# Default breath of players
|
||||
# Default: 10
|
||||
mcl_breath_max (Maximum breath) int 10 0
|
||||
|
||||
[Mobs]
|
||||
# If enabled, mobs will spawn naturally. This does not affect
|
||||
# affect mob spawners.
|
||||
|
|
Loading…
Reference in New Issue