From c15319c59f0fefa9dcdbe187a53d94f5aff56936 Mon Sep 17 00:00:00 2001 From: the-real-herowl Date: Mon, 22 Apr 2024 04:51:01 +0200 Subject: [PATCH] Added effect stacking option to the potions API Also: * Frost and Food Poisoning potion now stack their effects * fixed a crash related to tipped arrows --- mods/HELP/mcl_tt/snippets_mcl.lua | 1 + mods/ITEMS/mcl_potions/lingering.lua | 5 ++++- mods/ITEMS/mcl_potions/potions.lua | 26 ++++++++++++++++++------- mods/ITEMS/mcl_potions/splash.lua | 7 +++++-- mods/ITEMS/mcl_potions/tipped_arrow.lua | 15 ++++++++------ 5 files changed, 38 insertions(+), 16 deletions(-) diff --git a/mods/HELP/mcl_tt/snippets_mcl.lua b/mods/HELP/mcl_tt/snippets_mcl.lua index c8958f656..f39c1dc79 100644 --- a/mods/HELP/mcl_tt/snippets_mcl.lua +++ b/mods/HELP/mcl_tt/snippets_mcl.lua @@ -162,6 +162,7 @@ tt.register_snippet(function(itemstring, _, itemstack) if effect.uses_factor then factor = effect.level_to_factor(ef_level) end if effect.get_tt then ef_tt = minetest.colorize("grey", effect.get_tt(factor)) else ef_tt = "" end if ef_tt ~= "" then s = s.. ef_tt.. "\n" end + if details.effect_stacks then s = s.. minetest.colorize("grey", S("...stacks")).. "\n" end end end return s:trim() diff --git a/mods/ITEMS/mcl_potions/lingering.lua b/mods/ITEMS/mcl_potions/lingering.lua index ea0d0f36c..0eeb40b50 100644 --- a/mods/ITEMS/mcl_potions/lingering.lua +++ b/mods/ITEMS/mcl_potions/lingering.lua @@ -90,6 +90,9 @@ minetest.register_globalstep(function(dtime) else dur = details.dur end + if details.effect_stacks then + ef_level = ef_level + mcl_potions.get_effect_level(obj, name) + end if mcl_potions.give_effect_by_level(name, obj, ef_level, dur) then applied = true end @@ -97,7 +100,7 @@ minetest.register_globalstep(function(dtime) end if vals.def.custom_effect - and vals.def.custom_effect(obj, (vals.potency+1) * mcl_potions.LINGERING_FACTOR) then + and vals.def.custom_effect(obj, (vals.potency+1) * mcl_potions.LINGERING_FACTOR, plus) then applied = true end diff --git a/mods/ITEMS/mcl_potions/potions.lua b/mods/ITEMS/mcl_potions/potions.lua index 0d6d1940c..9ebf64ad2 100644 --- a/mods/ITEMS/mcl_potions/potions.lua +++ b/mods/ITEMS/mcl_potions/potions.lua @@ -64,7 +64,7 @@ function return_on_use(def, effect, dur) --def.on_use(user, effect, dur) -- Will do effect immediately but not reduce item count until eating delay ends which makes it exploitable by deliberately not finishing delay - -- Wrapper for handling mcl_hunger delayed eating + -- Wrapper for handling mcl_hunger delayed eating TODO migrate to the new function local name = user:get_player_name() mcl_hunger.eat_internal[name]._custom_itemstack = itemstack -- Used as comparison to make sure the custom wrapper executes only when the same item is eaten mcl_hunger.eat_internal[name]._custom_var = { @@ -122,11 +122,14 @@ local function generate_on_use(effects, color, on_use, custom_effect) else dur = details.dur end + if details.effect_stacks then + ef_level = ef_level + mcl_potions.get_effect_level(user, name) + end mcl_potions.give_effect_by_level(name, user, ef_level, dur) end if on_use then on_use(user, potency+1) end - if custom_effect then custom_effect(user, potency+1) end + if custom_effect then custom_effect(user, potency+1, plus) end itemstack = minetest.do_item_eat(0, "mcl_potions:glass_bottle", itemstack, user, pointed_thing) if itemstack then mcl_potions._use_potion(user, color) end @@ -162,6 +165,7 @@ end -- -- -- dur_variable - bool - whether variants of the potion should have the length of this effect changed - -- -- -- - defaults to true -- -- -- - if at least one effect has this set to true, the potion has a "plus" variant +-- -- -- effect_stacks - bool - whether the effect stacks - defaults to false -- uses_level - bool - whether the potion should come at different levels - -- - defaults to true if uses_level is true for at least one effect, else false -- drinkable - bool - defaults to true @@ -172,7 +176,7 @@ end -- default_potent_level - int - potion level used for the default potent variant - defaults to 2 -- default_extend_level - int - extention level (amount of +) used for the default extended variant - defaults to 1 -- custom_on_use - function(user, level) - called when the potion is drunk, returns true on success --- custom_effect - function(object, level) - called when the potion effects are applied, returns true on success +-- custom_effect - function(object, level, plus) - called when the potion effects are applied, returns true on success -- custom_splash_effect - function(pos, level) - called when the splash potion explodes, returns true on success -- custom_linger_effect - function(pos, radius, level) - called on the lingering potion step, returns true on success function mcl_potions.register_potion(def) @@ -195,6 +199,9 @@ function mcl_potions.register_potion(def) pdef.description = S("Strange Potion") end pdef._tt_help = def._tt + if def._tt and def.effect_stacks then + pdef._tt_help = pdef._tt_help .. "\n" .. S("Stacks the effect") + end pdef._dynamic_tt = def._dynamic_tt local potion_longdesc = def._longdesc if def._effect_list then @@ -230,6 +237,7 @@ function mcl_potions.register_potion(def) level_scaling = details.level_scaling or 1, dur = details.dur or mcl_potions.DURATION, dur_variable = durvar, + effect_stacks = details.effect_stacks and true or false } else error("Unable to register potion: effect not registered") @@ -727,10 +735,12 @@ mcl_potions.register_potion({ _longdesc = S("Freezes..."), color = "#5B7DAA", _effect_list = { - frost = {}, + frost = { + dur = mcl_potions.DURATION_POISON, + effect_stacks = true, + }, }, has_arrow = true, - -- TODO implement effect stacking? }) mcl_potions.register_potion({ @@ -764,10 +774,12 @@ mcl_potions.register_potion({ _longdesc = S("Moves bowels too fast."), color = "#83A061", _effect_list = { - food_poisoning = {dur=mcl_potions.DURATION_POISON}, + food_poisoning = { + dur = mcl_potions.DURATION_POISON, + effect_stacks = true, + }, }, has_arrow = true, - -- TODO implement effect stacking? }) mcl_potions.register_potion({ diff --git a/mods/ITEMS/mcl_potions/splash.lua b/mods/ITEMS/mcl_potions/splash.lua index 2fb9f362c..3b9261458 100644 --- a/mods/ITEMS/mcl_potions/splash.lua +++ b/mods/ITEMS/mcl_potions/splash.lua @@ -151,6 +151,9 @@ function mcl_potions.register_splash(name, descr, color, def) else dur = details.dur end + if details.effect_stacks then + ef_level = ef_level + mcl_potions.get_effect_level(obj, name) + end if rad > 0 then mcl_potions.give_effect_by_level(name, obj, ef_level, redux_map[rad]*dur) else @@ -162,9 +165,9 @@ function mcl_potions.register_splash(name, descr, color, def) if def.custom_effect then local power = (potency+1) * mcl_potions.SPLASH_FACTOR if rad > 0 then - def.custom_effect(obj, redux_map[rad] * power) + def.custom_effect(obj, redux_map[rad] * power, plus) else - def.custom_effect(obj, power) + def.custom_effect(obj, power, plus) end end end diff --git a/mods/ITEMS/mcl_potions/tipped_arrow.lua b/mods/ITEMS/mcl_potions/tipped_arrow.lua index 90e69d43e..ac760b1f0 100644 --- a/mods/ITEMS/mcl_potions/tipped_arrow.lua +++ b/mods/ITEMS/mcl_potions/tipped_arrow.lua @@ -301,10 +301,14 @@ function mcl_potions.register_arrow(name, desc, color, def) else dur = details.dur end + dur = dur * mcl_potions.SPLASH_FACTOR + if details.effect_stacks then + ef_level = ef_level + mcl_potions.get_effect_level(obj, name) + end mcl_potions.give_effect_by_level(name, obj, ef_level, dur) end end - if def.custom_effect then def.custom_effect(obj, potency+1) end + if def.custom_effect then def.custom_effect(obj, potency+1, plus) end end else obj:punch(self.object, 1.0, { @@ -329,14 +333,13 @@ function mcl_potions.register_arrow(name, desc, color, def) dur = details.dur end dur = dur * mcl_potions.SPLASH_FACTOR - if rad > 0 then - mcl_potions.give_effect_by_level(name, obj, ef_level, redux_map[rad]*dur) - else - mcl_potions.give_effect_by_level(name, obj, ef_level, dur) + if details.effect_stacks then + ef_level = ef_level + mcl_potions.get_effect_level(obj, name) end + mcl_potions.give_effect_by_level(name, obj, ef_level, dur) end end - if def.custom_effect then def.custom_effect(obj, potency+1) end + if def.custom_effect then def.custom_effect(obj, potency+1, plus) end end if is_player then