2024-10-25 13:46:47 +02:00

123 lines
3.4 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

--[[
Damage mod. This mod introduces a custom "damage" mechanic for players.
It is completely separate from Luanti's built-in health system,
which is ignored in this game.
Players can have 0 to lzr_damage.MAX_DAMAGE. Damage in this mod is
just a visual effect on the screen but has no gameplay effect on its own.
But it can be queried when the player has reached a certain damage.
Damage is never lethal.
The player damage can be added to, or reset to 0. When the player has
damage, it will slowly be reduced to 0 again.
Damage is mostly useful as an effect to simulate the player being
"hurt" without
]]
lzr_damage = {}
-- Note this game does NOT use regular damage and health, as defined
-- by Luanti, it's disabled. The "damage" here applies only to this mod!
lzr_damage.MAX_DAMAGE = 4
-- Reduce damage when player didn't take damage every HEAL_TIME
-- seconds.
local HEAL_TIME = 3.0
-- Player damage increases roughly every second the player is in danger,
-- and decreases while out of danger
local player_damage = 0
-- Count the time for how many consecutive seconds the player did
-- not take damage yet.
local safe_timer = 0
local damage_screen
local update_damage_screen = function(player)
if player_damage == 0 then
if damage_screen then
player:hud_remove(damage_screen)
damage_screen = nil
end
else
local texture = "lzr_damage_screen_"..player_damage..".png"
if not damage_screen then
damage_screen = player:hud_add({
type = "image",
scale = { x = -100, y = -100 },
text = texture,
alignment = { x = 1, y = 1 },
position = { x = 0, y = 0 },
z_index = -400,
})
else
player:hud_change(damage_screen, "text", texture)
end
end
end
lzr_damage.reset_player_damage = function(player)
player_damage = 0
update_damage_screen(player)
end
lzr_damage.damage_player = function(player, damage)
safe_timer = 0
player_damage = player_damage + (damage or 1)
if player_damage > lzr_damage.MAX_DAMAGE then
player_damage = lzr_damage.MAX_DAMAGE
end
local gain
if player_damage >= 3 then
gain = 1
elseif player_damage >= 2 then
gain = 0.7
else
gain = 0.4
end
local texture = "lzr_damage_screen_"..player_damage..".png"
update_damage_screen(player)
minetest.sound_play({name="lzr_damage_damage", gain=gain}, {to_player=player:get_player_name()}, true)
end
local undamage_player = function(player)
player_damage = math.max(0, player_damage - 1)
update_damage_screen(player)
end
lzr_damage.get_player_damage = function(player)
return player_damage
end
-- Slowly reduce damage to 0 when player hasnt been
-- damaged for a while.
minetest.register_globalstep(function(dtime)
safe_timer = safe_timer + dtime
if safe_timer < HEAL_TIME then
return
end
safe_timer = 0
local players = minetest.get_connected_players()
local state = lzr_gamestate.get_state()
if state ~= lzr_gamestate.LEVEL and state ~= lzr_gamestate.LEVEL_COMPLETE and state ~= lzr_gamestate.LEVEL_TEST then
return
end
for p=1, #players do
local player = players[p]
undamage_player(player)
end
end)
-- Reset player damage when entering any state but the level states
lzr_gamestate.register_on_enter_state(function(new_state)
if new_state ~= lzr_gamestate.LEVEL and new_state ~= lzr_gamestate.LEVEL_COMPLETE and new_state ~= lzr_gamestate.LEVEL_TEST then
local player = minetest.get_player_by_name("singleplayer")
if player then
lzr_damage.reset_player_damage(player)
end
end
end)