Skip to content

Commit

Permalink
Effects System: reset all effects on player leave or die. Closes #1832.
Browse files Browse the repository at this point in the history
Closes #1833
  • Loading branch information
alek13 committed Dec 11, 2024
1 parent 331da7a commit 11e9510
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 10 deletions.
24 changes: 20 additions & 4 deletions mods/lord/Core/effects/src/effects/ForPlayer.lua
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
local pairs, unpack
= pairs, unpack

local Registered = require('effects.Registered')
local Processor = require('effects.Processor')
local Logger = minetest.get_mod_logger()


--- @class effects.ForPlayer.Active
--- @field reason effects.Effect.Reason
--- @field effect effects.Effect
--- @field amount number
--- @field duration number
Expand Down Expand Up @@ -61,20 +65,32 @@ function ForPlayer:apply(effect_name, amount, duration, reason, ...)
self.effects[effect_name] = self.effects[effect_name] or {}

if effect.stop_with_same_reason and self.effects[effect_name][reason.name] then
self.effects[effect_name][reason.name].effect:stop(self.player, amount, duration, unpack({ reason, ... }))
self.effects[effect_name][reason.name].job:cancel()
Processor.stop_for(self.player, self.effects[effect_name][reason.name], unpack({ reason, ... }))
end

self.effects[effect_name][reason.name] = {
reason = reason,
amount = amount,
duration = duration,
effect = effect,
job = Processor.run_effect_for(self.player, effect, amount, duration, { reason, ... }, function(player)
-- TODO: the `player` could have already left. #1673
self.effects[effect_name][reason.name] = nil
if self.effects[effect_name] and self.effects[effect_name][reason.name] then
self.effects[effect_name][reason.name] = nil
end
end)
}
end

function ForPlayer:reset(...)
for effect_name, reasoned_effects in pairs(self.effects) do
for reason_name, active_effect in pairs(reasoned_effects) do
Processor.stop_for(self.player, active_effect, ...)
if self.effects[effect_name] and self.effects[effect_name][reason_name] then
self.effects[effect_name][reason_name] = nil
end
end
end
end


return ForPlayer
27 changes: 21 additions & 6 deletions mods/lord/Core/effects/src/effects/Processor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,43 @@ local Processor = {}

function Processor.init()
minetest.register_on_joinplayer(function(player, last_login)
-- Get State (from ObjectState)
-- Get State (from ObjectState) ??? (or in Character, TODO #1673)
end)
minetest.register_on_leaveplayer(function(player, last_login)
-- Clean up in-memory State (also we can additionally save it into ObjectState)
minetest.register_on_leaveplayer(function(player, timed_out)
--if timed_out then
-- Save State (into ObjectState) ??? (or in Character, TODO #1673)
--end

effects.for_player(player):reset()
end)
minetest.register_on_dieplayer(function(player, reason)
effects.for_player(player):reset()
end)
end

--- @param player Player
--- @param effect effects.Effect
--- @param amount number
--- @param duration number
--- @param after_stop fun(player:Player,effect:effects.Effect)
--- @param after_stop fun(player:Player,effect:effects.Effect) @ /!\ warn: the `player` could have already left.
--- @return job
function Processor.run_effect_for(player, effect, amount, duration, params, after_stop)
effect:start(player, amount, duration, unpack(params))
-- TODO: effect can be reapplied. #1650

return minetest.after(duration, function()
-- TODO: the `player` could have already left. #1673
effect:stop(player, amount, duration, unpack(params))
after_stop(player, effect)
end)
end

--- @param player Player
--- @param active_effect effects.ForPlayer.Active
function Processor.stop_for(player, active_effect, ...)
active_effect.effect:stop(
player, active_effect.amount, active_effect.duration, unpack({ active_effect.reason, ... })
)
active_effect.job:cancel()
end


return Processor

0 comments on commit 11e9510

Please sign in to comment.