Withering effect and effect immunities

Added withering effect and immunities to effects.

Signed-off-by: Nauta Turbidus <88062389+nauta-turbidus@users.noreply.github.com>
This commit is contained in:
Nauta Turbidus 2023-08-08 02:53:01 +02:00 committed by the-real-herowl
parent f1568483b3
commit a1b6819756
17 changed files with 239 additions and 17 deletions

@ -21,6 +21,8 @@ local function atan(x)
end
end
mcl_mobs.effect_functions = {}
-- check if daytime and also if mob is docile during daylight hours
function mob_class:day_docile()
@ -1103,6 +1105,11 @@ function mob_class:do_states_attack (dtime)
full_punch_interval = 1.0,
damage_groups = {fleshy = self.damage}
}, nil)
if self.dealt_effect then
mcl_mobs.effect_functions[self.dealt_effect.name](
self.attack, self.dealt_effect.factor, self.dealt_effect.dur
)
end
end
else
self.custom_attack(self, p)

@ -312,6 +312,8 @@ function mcl_mobs.register_mob(name, def)
return self:mob_activate(staticdata, def, dtime)
end,
harmed_by_heal = def.harmed_by_heal,
is_boss = def.is_boss,
dealt_effect = def.dealt_effect,
on_lightning_strike = def.on_lightning_strike
}
minetest.register_entity(name, setmetatable(final_def,mcl_mobs.mob_class_meta))

@ -16,8 +16,13 @@ for _, d in pairs(dim) do
end
local function check_schem(pos, schem)
local cn_name
for _, n in pairs(schem) do
if minetest.get_node(vector.add(pos, n)).name ~= n.name then
cn_name = minetest.get_node(vector.add(pos, n)).name
if string.find(cn_name, "mcl_heads:wither_skeleton") then
cn_name = "mcl_heads:wither_skeleton"
end
if cn_name ~= n.name then
return false
end
end

@ -136,6 +136,7 @@ mcl_mobs.register_mob("mobs_mc:enderdragon", {
end
end,
fire_resistant = true,
is_boss = true,
})

@ -96,6 +96,11 @@ mcl_mobs.register_mob("mobs_mc:witherskeleton", {
fear_height = 4,
harmed_by_heal = true,
fire_resistant = true,
dealt_effect = {
name = "withering",
factor = 1,
dur = 10,
},
})
--spawn

@ -138,6 +138,11 @@ cave_spider.walk_velocity = 1.3
cave_spider.run_velocity = 3.2
cave_spider.sounds = table.copy(spider.sounds)
cave_spider.sounds.base_pitch = 1.25
cave_spider.dealt_effect = {
name = "poison",
factor = 2.5,
dur = 7,
}
mcl_mobs.register_mob("mobs_mc:cave_spider", cave_spider)

@ -67,12 +67,14 @@ mcl_mobs.register_mob("mobs_mc:wither", {
run_start = 0, run_end = 20,
},
harmed_by_heal = true,
is_boss = true,
do_custom = function(self)
if self.health < (self.hp_max / 2) then
self.base_texture = "mobs_mc_wither_half_health.png"
self.fly = false
self.object:set_properties({textures={self.base_texture}})
self.armor = {undead = 80, fleshy = 80}
self.arrow = "mobs_mc:wither_skull_strong"
end
mcl_bossbars.update_boss(self.object, "Wither", "dark_purple")
end,
@ -86,11 +88,18 @@ local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
local wither_rose_soil = { "group:grass_block", "mcl_core:dirt", "mcl_core:coarse_dirt", "mcl_nether:netherrack", "group:soul_block", "mcl_mud:mud", "mcl_moss:moss" }
mcl_mobs.register_arrow("mobs_mc:wither_skull", {
visual = "sprite",
visual = "cube",
visual_size = {x = 0.75, y = 0.75},
-- TODO: 3D projectile, replace tetxture
textures = {"mobs_mc_TEMP_wither_projectile.png"},
textures = {
"mobs_mc_wither_projectile.png^[verticalframe:6:0", -- top
"mobs_mc_wither_projectile.png^[verticalframe:6:1", -- bottom
"mobs_mc_wither_projectile.png^[verticalframe:6:2", -- left
"mobs_mc_wither_projectile.png^[verticalframe:6:3", -- right
"mobs_mc_wither_projectile.png^[verticalframe:6:4", -- back
"mobs_mc_wither_projectile.png^[verticalframe:6:5", -- front
},
velocity = 6,
rotate = 90,
-- direct hit
hit_player = function(self, player)
@ -98,6 +107,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", {
full_punch_interval = 0.5,
damage_groups = {fleshy = 8},
}, nil)
mcl_mobs.effect_functions["withering"](player, 0.5, 10)
mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1)
end,
@ -106,6 +116,7 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", {
full_punch_interval = 0.5,
damage_groups = {fleshy = 8},
}, nil)
mcl_mobs.effect_functions["withering"](mob, 0.5, 10)
mcl_mobs.mob_class.boom(self,self.object:get_pos(), 1)
local l = mob:get_luaentity()
if l and l.health - 8 <= 0 then
@ -126,7 +137,70 @@ mcl_mobs.register_arrow("mobs_mc:wither_skull", {
mcl_mobs.mob_class.boom(self,pos, 1)
end
})
-- TODO: Add blue wither skull
mcl_mobs.register_arrow("mobs_mc:wither_skull_strong", {
visual = "cube",
visual_size = {x = 0.75, y = 0.75},
textures = {
"mobs_mc_wither_projectile_strong.png^[verticalframe:6:0", -- top
"mobs_mc_wither_projectile_strong.png^[verticalframe:6:1", -- bottom
"mobs_mc_wither_projectile_strong.png^[verticalframe:6:2", -- left
"mobs_mc_wither_projectile_strong.png^[verticalframe:6:3", -- right
"mobs_mc_wither_projectile_strong.png^[verticalframe:6:4", -- back
"mobs_mc_wither_projectile_strong.png^[verticalframe:6:5", -- front
},
velocity = 3,
rotate = 90,
-- direct hit
hit_player = function(self, player)
player:punch(self.object, 1.0, {
full_punch_interval = 0.5,
damage_groups = {fleshy = 12},
}, nil)
mcl_mobs.effect_functions["withering"](player, 0.5, 10)
local pos = self.object:get_pos()
if mobs_griefing and not minetest.is_protected(pos, "") then
mcl_explosions.explode(pos, 1, { drop_chance = 1.0, max_blast_resistance = 0, }, self.object)
else
mcl_mobs.mob_class.safe_boom(self, pos, 1) --need to call it this way bc self is the "arrow" object here
end
end,
hit_mob = function(self, mob)
mob:punch(self.object, 1.0, {
full_punch_interval = 0.5,
damage_groups = {fleshy = 12},
}, nil)
mcl_mobs.effect_functions["withering"](mob, 0.5, 10)
local pos = self.object:get_pos()
if mobs_griefing and not minetest.is_protected(pos, "") then
mcl_explosions.explode(pos, 1, { drop_chance = 1.0, max_blast_resistance = 0, }, self.object)
else
mcl_mobs.mob_class.safe_boom(self, pos, 1) --need to call it this way bc self is the "arrow" object here
end
local l = mob:get_luaentity()
if l and l.health - 8 <= 0 then
local n = minetest.find_node_near(mob:get_pos(),2,wither_rose_soil)
if n then
local p = vector.offset(n,0,1,0)
if minetest.get_node(p).name == "air" then
if not ( mobs_griefing and minetest.place_node(p,{name="mcl_flowers:wither_rose"}) ) then
minetest.add_item(p,"mcl_flowers:wither_rose")
end
end
end
end
end,
-- node hit, explode
hit_node = function(self, pos, node)
if mobs_griefing and not minetest.is_protected(pos, "") then
mcl_explosions.explode(pos, 1, { drop_chance = 1.0, max_blast_resistance = 0, }, self.object)
else
mcl_mobs.mob_class.safe_boom(self, pos, 1) --need to call it this way bc self is the "arrow" object here
end
end
})
--Spawn egg
mcl_mobs.register_egg("mobs_mc:wither", S("Wither"), "#4f4f4f", "#4f4f4f", 0, true)

@ -20,6 +20,7 @@ get_chat_function["leaping"] = mcl_potions.leaping_func
get_chat_function["swiftness"] = mcl_potions.swiftness_func
get_chat_function["heal"] = mcl_potions.healing_func
get_chat_function["bad_omen"] = mcl_potions.bad_omen_func
get_chat_function["withering"] = mcl_potions.withering_func
minetest.register_chatcommand("effect",{
params = S("<effect> <duration> [<factor>]"),

@ -10,6 +10,7 @@ EF.swift = {} -- for swiftness AND slowness
EF.night_vision = {}
EF.fire_proof = {}
EF.bad_omen = {}
EF.withering = {}
local EFFECT_TYPES = 0
for _,_ in pairs(EF) do
@ -19,8 +20,11 @@ end
local icon_ids = {}
local function potions_set_hudbar(player)
if EF.poisoned[player] and EF.regenerating[player] then
if EF.withering[player] and EF.regenerating[player] then
hb.change_hudbar(player, "health", nil, nil, "mcl_potions_icon_regen_wither.png", nil, "hudbars_bar_health.png")
elseif EF.withering[player] then
hb.change_hudbar(player, "health", nil, nil, "mcl_potions_icon_wither.png", nil, "hudbars_bar_health.png")
elseif EF.poisoned[player] and EF.regenerating[player] then
hb.change_hudbar(player, "health", nil, nil, "hbhunger_icon_regen_poison.png", nil, "hudbars_bar_health.png")
elseif EF.poisoned[player] then
hb.change_hudbar(player, "health", nil, nil, "hbhunger_icon_health_poison.png", nil, "hudbars_bar_health.png")
@ -123,6 +127,33 @@ minetest.register_globalstep(function(dtime)
end
-- Check for withering players
for player, vals in pairs(EF.withering) do
is_player = player:is_player()
entity = player:get_luaentity()
EF.withering[player].timer = EF.withering[player].timer + dtime
EF.withering[player].hit_timer = (EF.withering[player].hit_timer or 0) + dtime
if player:get_pos() then mcl_potions._add_spawner(player, "#000000") end
if EF.withering[player].hit_timer >= EF.withering[player].step then
if is_player or entity then mcl_util.deal_damage(player, 1, {type = "magic"}) end
if EF.withering[player] then EF.withering[player].hit_timer = 0 end
end
if EF.withering[player] and EF.withering[player].timer >= EF.withering[player].dur then
EF.withering[player] = nil
if is_player then
meta = player:get_meta()
meta:set_string("_is_withering", minetest.serialize(EF.withering[player]))
potions_set_hud(player)
end
end
end
-- Check for poisoned players
for player, vals in pairs(EF.poisoned) do
@ -152,7 +183,7 @@ minetest.register_globalstep(function(dtime)
end
-- Check for regnerating players
-- Check for regenerating players
for player, vals in pairs(EF.regenerating) do
is_player = player:is_player()
@ -408,6 +439,7 @@ function mcl_potions._clear_cached_player_data(player)
EF.night_vision[player] = nil
EF.fire_proof[player] = nil
EF.bad_omen[player] = nil
EF.withering[player] = nil
meta = player:get_meta()
meta:set_int("night_vision", 0)
@ -452,6 +484,7 @@ function mcl_potions._save_player_effects(player)
meta:set_string("_is_cat", minetest.serialize(EF.night_vision[player]))
meta:set_string("_is_fire_proof", minetest.serialize(EF.fire_proof[player]))
meta:set_string("_has_bad_omen", minetest.serialize(EF.bad_omen[player]))
meta:set_string("_is_withering", minetest.serialize(EF.withering[player]))
end
@ -507,6 +540,10 @@ function mcl_potions._load_player_effects(player)
EF.bad_omen[player] = minetest.deserialize(meta:get_string("_has_bad_omen"))
end
if minetest.deserialize(meta:get_string("_is_withering")) then
EF.withering[player] = minetest:deserialize(meta:get_string("_is_withering"))
end
end
-- Returns true if player has given effect
@ -725,6 +762,9 @@ end
function mcl_potions.swiftness_func(player, factor, duration)
local entity = player:get_luaentity()
if entity and entity.is_boss then return false end
if not player:get_meta() then
return false
end
@ -753,6 +793,9 @@ end
function mcl_potions.leaping_func(player, factor, duration)
local entity = player:get_luaentity()
if entity and entity.is_boss then return false end
if not player:get_meta() then
return false
end
@ -781,6 +824,9 @@ end
function mcl_potions.weakness_func(player, factor, duration)
local entity = player:get_luaentity()
if entity and entity.is_boss then return false end
if not EF.weak[player] then
EF.weak[player] = {dur = duration, timer = 0, factor = factor}
@ -804,6 +850,9 @@ end
function mcl_potions.strength_func(player, factor, duration)
local entity = player:get_luaentity()
if entity and entity.is_boss then return false end
if not EF.strong[player] then
EF.strong[player] = {dur = duration, timer = 0, factor = factor}
@ -825,8 +874,37 @@ function mcl_potions.strength_func(player, factor, duration)
end
function mcl_potions.withering_func(player, factor, duration)
local entity = player:get_luaentity()
if entity and (entity.is_boss or string.find(entity.name, "wither")) then return false end
if not EF.withering[player] then
EF.withering[player] = {step = factor, dur = duration, timer = 0}
else
local victim = EF.withering[player]
victim.step = math.min(victim.step, factor)
victim.dur = math.max(duration, victim.dur - victim.timer)
victim.timer = 0
end
if player:is_player() then
potions_set_hud(player)
end
end
function mcl_potions.poison_func(player, factor, duration)
local entity = player:get_luaentity()
if entity and (entity.is_boss or entity.harmed_by_heal or string.find(entity.name, "spider")) then return false end
if not EF.poisoned[player] then
EF.poisoned[player] = {step = factor, dur = duration, timer = 0}
@ -850,6 +928,9 @@ end
function mcl_potions.regeneration_func(player, factor, duration)
local entity = player:get_luaentity()
if entity and (entity.is_boss or entity.harmed_by_heal) then return false end
if not EF.regenerating[player] then
EF.regenerating[player] = {step = factor, dur = duration, timer = 0}
@ -873,6 +954,9 @@ end
function mcl_potions.invisiblility_func(player, null, duration)
local entity = player:get_luaentity()
if entity and entity.is_boss then return false end
if not EF.invisible[player] then
EF.invisible[player] = {dur = duration, timer = 0}
@ -895,6 +979,9 @@ end
function mcl_potions.water_breathing_func(player, null, duration)
local entity = player:get_luaentity()
if entity and entity.is_boss then return false end
if not EF.water_breathing[player] then
EF.water_breathing[player] = {dur = duration, timer = 0}
@ -917,6 +1004,9 @@ end
function mcl_potions.fire_resistance_func(player, null, duration)
local entity = player:get_luaentity()
if entity and entity.is_boss then return false end
if not EF.fire_proof[player] then
EF.fire_proof[player] = {dur = duration, timer = 0}
@ -938,6 +1028,9 @@ end
function mcl_potions.night_vision_func(player, null, duration)
local entity = player:get_luaentity()
if entity and entity.is_boss then return false end
meta = player:get_meta()
if not EF.night_vision[player] then

@ -356,6 +356,7 @@ local awkward_table = {
["mcl_fishing:pufferfish_raw"] = "mcl_potions:water_breathing",
["mcl_mobitems:ghast_tear"] = "mcl_potions:regeneration",
["mcl_mobitems:spider_eye"] = "mcl_potions:poison",
["mcl_flowers:wither_rose"] = "mcl_potions:withering",
["mcl_mobitems:rabbit_foot"] = "mcl_potions:leaping",
}
@ -373,7 +374,7 @@ local potions = {}
for i, potion in ipairs({"healing","harming","swiftness","slowness",
"leaping","poison","regeneration","invisibility","fire_resistance",
-- "weakness","strength",
"water_breathing","night_vision"}) do
"water_breathing","night_vision", "withering"}) do
table.insert(potions, potion)
@ -461,6 +462,18 @@ function mcl_potions.get_alchemy(ingr, pot)
return false
end
mcl_mobs.effect_functions["poison"] = mcl_potions.poison_func
mcl_mobs.effect_functions["regeneration"] = mcl_potions.regeneration_func
mcl_mobs.effect_functions["invisibility"] = mcl_potions.invisiblility_func
mcl_mobs.effect_functions["fire_resistance"] = mcl_potions.fire_resistance_func
mcl_mobs.effect_functions["night_vision"] = mcl_potions.night_vision_func
mcl_mobs.effect_functions["water_breathing"] = mcl_potions.water_breathing_func
mcl_mobs.effect_functions["leaping"] = mcl_potions.leaping_func
mcl_mobs.effect_functions["swiftness"] = mcl_potions.swiftness_func
mcl_mobs.effect_functions["heal"] = mcl_potions.healing_func
mcl_mobs.effect_functions["bad_omen"] = mcl_potions.bad_omen_func
mcl_mobs.effect_functions["withering"] = mcl_potions.withering_func
mcl_wip.register_wip_item("mcl_potions:night_vision")
mcl_wip.register_wip_item("mcl_potions:night_vision_plus")
mcl_wip.register_wip_item("mcl_potions:night_vision_splash")

@ -1,2 +1,2 @@
name = mcl_potions
depends = mcl_core, mcl_farming, mcl_mobitems, mcl_fishing, mcl_bows, mcl_end, mcl_weather, playerphysics, mcl_wip
depends = mcl_core, mcl_farming, mcl_flowers, mcl_mobitems, mcl_mobs, mcl_fishing, mcl_bows, mcl_end, mcl_weather, playerphysics, mcl_wip

@ -79,7 +79,7 @@ local function register_potion(def)
if def.is_inv then
dur = dur * mcl_potions.INV_FACTOR
end
if def.name == "poison" or def.name == "regeneration" then
if def.name == "poison" or def.name == "regeneration" or def.name == "withering" then
dur = 45
end
@ -93,7 +93,7 @@ local function register_potion(def)
local _tt
if effect and def.is_dur then
_tt = perc_string(effect).." | "..time_string(dur)
if def.name == "poison" or def.name == "regeneration" then
if def.name == "poison" or def.name == "regeneration" or def.name == "withering" then
_tt = S("1 HP/@1s | @2", effect, time_string(dur))
end
elseif def.name == "healing" or def.name == "harming" then
@ -235,6 +235,8 @@ local function register_potion(def)
effect_II = def.effect*mcl_potions.II_FACTOR
elseif def.name == "poison" or def.name == "regeneration" then
effect_II = 1.2
elseif def.name == "withering" then
effect_II = 2
else
effect_II = def.effect^mcl_potions.II_FACTOR
end
@ -327,7 +329,7 @@ local function register_potion(def)
if def.is_plus then
local dur_pl = dur * mcl_potions.PLUS_FACTOR
if def.name == "poison" or def.name == "regeneration" then
if def.name == "poison" or def.name == "regeneration" or def.name == "withering" then
dur_pl = 90
end
@ -533,6 +535,20 @@ local leaping_def = {
is_plus = true,
}
local withering_def = {
name = "withering",
description = S("Withering"),
_tt = nil,
_longdesc = S("Applies the withering effect which deals damage at a regular interval and can kill."),
color = "#000000",
effect = 4,
is_dur = true,
on_use = mcl_potions.withering_func,
is_II = true,
is_plus = true,
is_inv = true,
}
local poison_def = {
name = "poison",
description = S("Poison"),
@ -597,7 +613,7 @@ local fire_resistance_def = {
local defs = { awkward_def, mundane_def, thick_def, dragon_breath_def,
healing_def, harming_def, night_vision_def, swiftness_def,
slowness_def, leaping_def, poison_def, regeneration_def,
slowness_def, leaping_def, withering_def, poison_def, regeneration_def,
invisibility_def, water_breathing_def, fire_resistance_def}
for _, def in ipairs(defs) do

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 674 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 660 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B