Skip to content

Commit

Permalink
Refactor lord_damage (WIP, Part II). Relates to #1509, #1620
Browse files Browse the repository at this point in the history
  • Loading branch information
Doloment committed Sep 5, 2024
1 parent f0c13ce commit 04ff400
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 74 deletions.
9 changes: 7 additions & 2 deletions mods/lord/_experimental/lord_damage/src/damage/DamageType.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,20 @@ function DamageType:new(damage_type_def)

local class = self

function self:instant(target, amount, reason, on_start)
local function instant(obj, target, amount, reason, on_start)

end


function self:periodic(target, amount, reason, on_start)
local function periodic(obj, target, amount, reason, on_start)

end

self.instant = instant
self.periodic = periodic



self = setmetatable({}, { __index = class })


Expand Down
128 changes: 56 additions & 72 deletions mods/lord/_experimental/lord_damage/src/damage/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -63,21 +63,30 @@ local function deal_damage(object, amount, reason, chunks, run)
return to_return
end

local function generate_damage_pattern(amount, portions, treat_portions_as_divisions)
local function generate_damage_pattern(amount, portion, treat_portion_as_divisions)
local pattern = {}
local max_entries

if treat_portions_as_divisions == true then
max_entries = portions
portions = math.floor(amount/max_entries)

if treat_portion_as_divisions == true then
max_entries = portion
portion = math.floor(amount/max_entries)
local leftover_damage = amount%portion
for i = 1, max_entries do
local buffer = portion
if i == max_entries then
buffer = buffer + leftover_damage
end
pattern[i] = buffer
end
else
max_entries = math.floor(amount/portions)
end
local leftover_damage = amount%portions

for i = 1, max_entries do
pattern[i] = 1
max_entries = math.floor(amount/portion)
local leftover_damage = amount%portion
for i = 1, max_entries do
pattern[i] = portion
if i == max_entries then
pattern[i+1] = leftover_damage
end
end
end

return pattern
Expand All @@ -92,66 +101,62 @@ local function base_behavior(object, amount, reason)
object:set_hp(object:get_hp() - amount, reason)
end


-- Track the respawn of the player somehow to reset all periodic damages
-- after death and respawn;
-- Not sure how, but it MUST be done
-- minetest.register_on_respawnplayer(function(ObjectRef)
-- end)

local function check_if_died_or_left_or_invalid(object)
if object:is_player() then
if object:get_hp() <= 0 then
return true
end
elseif not object:is_valid() or not object:get_luaentity() then
return true
end

return false
end

--- @param object Player|Entity
--- @param amount number
--- @param reason DamageReason
--- @param chunks number|nil
--- @param run function
local function periodic_base_behavior(object, amount, reason, chunks, run)
dump(chunks)
local damage_type = reason.damage_type
local cause = reason.cause
amount = calculate_damage_absorption(object, amount, damage_type)

run = run or function() end

local has_a_cause = false
if cause then
has_a_cause = true
end


local max_cycle = math.floor(amount/chunks)
local leftover_damage = amount%chunks
local player_has_died = false
local object_has_died = false
local player_has_left = false
local cause_removed = false


local abort_cycle = false
local max_cycle = math.floor(amount/chunks)
local cycle_number = 0

local cycle_number = 0
for i = 1, max_cycle do
minetest.after(cycle_number, function()
minetest.chat_send_all("Pass")
if not object then
if not object or abort_cycle then
-- THE FOLLOWING LINE IS FOR TESTING PURPOSES ONLY! REMOVE IT WHEN THE DAMAGE SYSTEM IS INTEGRATED INTO THE GAME.
minetest.chat_send_all("Pass".. tostring(abort_cycle))
return
end

if object:is_player() then
minetest.chat_send_all("Is player")
minetest.register_on_dieplayer(function(dieplayer)
if dieplayer:get_player_name() == object:get_player_name() then
player_has_died = true
end
end)
minetest.register_on_leaveplayer(function(leaveplayer)
if leaveplayer:get_player_name() == object:get_player_name() then
player_has_left = true
end
end)
else
if not object:is_valid() or not object:get_luaentity() then
minetest.chat_send_all("Died")
object_has_died = true
end
end
abort_cycle = check_if_died_or_left_or_invalid(object)

if has_a_cause and not object_has_died then
cause_removed = (cause and not get_cause(object, cause))
if has_a_cause and not abort_cycle then
abort_cycle = (cause and not get_cause(object, cause))
end

local reset_damage = player_has_died or player_has_left or object_has_died or cause_removed
if reset_damage then
minetest.chat_send_all("Reset")
if abort_cycle then
leftover_damage = 0
return
end
Expand All @@ -165,38 +170,17 @@ local function periodic_base_behavior(object, amount, reason, chunks, run)
cycle_number = cycle_number + 1
end
minetest.after(max_cycle, function()
if not object then
return
end

if leftover_damage == 0 then
if not object or leftover_damage == 0 or abort_cycle then
return
end

if object:is_player() then
minetest.register_on_dieplayer(function(dieplayer)
if dieplayer:get_player_name() == object:get_player_name() then
player_has_died = true
end
end)
minetest.register_on_leaveplayer(function(leaveplayer)
if leaveplayer:get_player_name() == object:get_player_name() then
player_has_left = true
end
end)
else
if not object:is_valid() or not object:get_luaentity() then
minetest.chat_send_all("Died")
object_has_died = true
end
end
abort_cycle = check_if_died_or_left_or_invalid(object)

if has_a_cause and not object_has_died then
cause_removed = (cause and not get_cause(object, cause))
if has_a_cause and not abort_cycle then
abort_cycle = (cause and not get_cause(object, cause))
end

local reset_damage = player_has_died or player_has_left or object_has_died or cause_removed
if reset_damage then
if abort_cycle then
return
end

Expand Down

0 comments on commit 04ff400

Please sign in to comment.