From 2840cb117405acaaa214dc3629178d7c200b2cb2 Mon Sep 17 00:00:00 2001 From: Xaver-DaRed Date: Mon, 2 Jun 2025 11:59:10 +0200 Subject: [PATCH] Fix Bio/Nightmare sleep interactions --- scripts/actions/abilities/pets/nightmare.lua | 25 +++++++++++++------- scripts/actions/mobskills/nightmare.lua | 12 ++++++++-- scripts/effects/bio.lua | 8 +++---- scripts/effects/sleep.lua | 13 ---------- src/map/lua/lua_baseentity.cpp | 4 ++-- src/map/status_effect_container.cpp | 4 ++-- 6 files changed, 34 insertions(+), 32 deletions(-) diff --git a/scripts/actions/abilities/pets/nightmare.lua b/scripts/actions/abilities/pets/nightmare.lua index 5c62fed708e..c3d16429119 100644 --- a/scripts/actions/abilities/pets/nightmare.lua +++ b/scripts/actions/abilities/pets/nightmare.lua @@ -15,28 +15,35 @@ end abilityObject.onPetAbility = function(target, pet, petskill, summoner, action) xi.job_utils.summoner.onUseBloodPact(target, petskill, summoner, action) - local duration = 90 + local duration = 90 local dotdamage = 2 - local sleepTier = 1 - local dINT = pet:getStat(xi.mod.INT) - target:getStat(xi.mod.INT) - local bonus = xi.summon.getSummoningSkillOverCap(pet) - local resm = xi.mobskills.applyPlayerResistance(pet, -1, target, dINT, bonus, xi.element.DARK) - if resm < 0.5 then + local dINT = pet:getStat(xi.mod.INT) - target:getStat(xi.mod.INT) + local bonus = xi.summon.getSummoningSkillOverCap(pet) + local tier = 4 + local resist = xi.mobskills.applyPlayerResistance(pet, -1, target, dINT, bonus, xi.element.DARK) + if resist < 0.5 then petskill:setMsg(xi.msg.basic.JA_MISS_2) -- resist message return xi.effect.SLEEP_I end - duration = duration * resm + duration = math.floor(duration * resist) + + --No effect if target:hasImmunity(xi.immunity.DARK_SLEEP) or target:hasStatusEffect(xi.effect.SLEEP_I) or target:hasStatusEffect(xi.effect.SLEEP_II) or target:hasStatusEffect(xi.effect.LULLABY) then - --No effect petskill:setMsg(xi.msg.basic.JA_NO_EFFECT_2) - elseif target:addStatusEffect(xi.effect.SLEEP_I, 1, 0, duration, 0, dotdamage, sleepTier) then + + -- Apply sleep and bio + elseif target:addStatusEffect(xi.effect.SLEEP_I, 1, 0, duration, 0, dotdamage, tier) then petskill:setMsg(xi.msg.basic.JA_GAIN_EFFECT) + target:delStatusEffectSilent(xi.effect.BIO) + target:addStatusEffect(xi.effect.BIO, dotdamage, 3, duration, 0, 10, 5) + + -- Miss else petskill:setMsg(xi.msg.basic.JA_MISS_2) end diff --git a/scripts/actions/mobskills/nightmare.lua b/scripts/actions/mobskills/nightmare.lua index b964091f3f7..54b259cf7e6 100644 --- a/scripts/actions/mobskills/nightmare.lua +++ b/scripts/actions/mobskills/nightmare.lua @@ -33,8 +33,16 @@ mobskillObject.onMobSkillCheck = function(target, mob, skill) end mobskillObject.onMobWeaponSkill = function(target, mob, skill) - local dotdamage = 15 - skill:setMsg(xi.mobskills.mobStatusEffectMove(mob, target, xi.effect.SLEEP_I, 1, 0, math.random(20, 30), 0, dotdamage, 2)) + local bioPower = 15 + local duration = math.random(20, 30) + local effectTierier = 5 + + -- Handle unbreakable sleep + skill:setMsg(xi.mobskills.mobStatusEffectMove(mob, target, xi.effect.SLEEP_I, 1, 0, duration, 0, 0, effectTierier)) + + -- Handle special Bio + target:delStatusEffectSilent(xi.effect.BIO) + target:addStatusEffect(xi.effect.BIO, bioPower, 3, duration, 0, 10, effectTierier) return xi.effect.SLEEP_I end diff --git a/scripts/effects/bio.lua b/scripts/effects/bio.lua index 5cabfbce52a..519cd9278d5 100644 --- a/scripts/effects/bio.lua +++ b/scripts/effects/bio.lua @@ -1,13 +1,13 @@ ----------------------------------- -- xi.effect.BIO --- Tier > 0 signals this is a bio that doesn't break sleep +-- Tier >= 5 signals this is a bio that doesn't break sleep -- See mobskills/nightmare.lua for full explanation ----------------------------------- ---@type TEffect local effectObject = {} effectObject.onEffectGain = function(target, effect) - if effect:getTier() == 0 then + if effect:getTier() < 5 then -- Regular bio application. effect:addMod(xi.mod.REGEN_DOWN, effect:getPower()) end @@ -15,9 +15,9 @@ effectObject.onEffectGain = function(target, effect) end effectObject.onEffectTick = function(target, effect) - -- Bio with Tier > 0 is a signal that we don't wake up targets from this dot damage + -- Bio with Tier >= 5 is a signal that we don't wake up targets from this dot damage -- handle diabolos nightmare bio damage explicitly - if effect:getTier() > 0 then + if effect:getTier() >= 5 then -- re-using logic from helix effect processing local dmg = utils.stoneskin(target, effect:getPower()) diff --git a/scripts/effects/sleep.lua b/scripts/effects/sleep.lua index 2d5de97c625..8702a743291 100644 --- a/scripts/effects/sleep.lua +++ b/scripts/effects/sleep.lua @@ -7,19 +7,6 @@ local effectObject = {} effectObject.onEffectGain = function(target, effect) -- Immunobreak reset. target:setMod(xi.mod.SLEEP_IMMUNOBREAK, 0) - - if effect:getTier() > 0 then - -- bio with subpower > 0 is a signal that we don't wake up targets from this dot damage - -- dot damage = sleep subpower - -- see mobskills/nightmare.lua for full explanation - local attpReduction = 10 - if effect:getTier() > 1 then - attpReduction = effect:getSubPower() - end - - target:delStatusEffectSilent(xi.effect.BIO) - target:addStatusEffect(xi.effect.BIO, effect:getSubPower(), 3, effect:getDuration(), 0, attpReduction, 1) - end end effectObject.onEffectTick = function(target, effect) diff --git a/src/map/lua/lua_baseentity.cpp b/src/map/lua/lua_baseentity.cpp index 461b7e2e432..30c49b879c7 100644 --- a/src/map/lua/lua_baseentity.cpp +++ b/src/map/lua/lua_baseentity.cpp @@ -9851,7 +9851,7 @@ void CLuaBaseEntity::takeDamage(int32 damage, sol::object const& attacker, sol:: // Check to see if the target has a nightmare effect active, reset wakeUp accordingly // see mobskills/nightmare.lua for full explanation if (PDefender->StatusEffectContainer->GetStatusEffect(EFFECT_SLEEP) && - PDefender->StatusEffectContainer->GetStatusEffect(EFFECT_SLEEP)->GetTier() > 0) + PDefender->StatusEffectContainer->GetStatusEffect(EFFECT_SLEEP)->GetTier() >= 4) // Tier 4 = Player Avatar Nightmare { // Don't break nightmare sleep from any dmg that doesn't break bind (DoT damage) if (breakBind == false) @@ -9862,7 +9862,7 @@ void CLuaBaseEntity::takeDamage(int32 damage, sol::object const& attacker, sol:: // Diabolos NM/mob ability // "Damage will not wake you up from Nightmare, only Cure and Benediction (Benediction will also remove the Bio effect)." if (wakeUp == true && - PDefender->StatusEffectContainer->GetStatusEffect(EFFECT_SLEEP)->GetTier() > 1) + PDefender->StatusEffectContainer->GetStatusEffect(EFFECT_SLEEP)->GetTier() >= 5) // Tier 5 = Diabolos NM Nightmare { wakeUp = false; } diff --git a/src/map/status_effect_container.cpp b/src/map/status_effect_container.cpp index 7b06265df18..87a2a99d7d2 100644 --- a/src/map/status_effect_container.cpp +++ b/src/map/status_effect_container.cpp @@ -823,7 +823,7 @@ void CStatusEffectContainer::DelStatusEffectsByFlag(uint32 flag, EffectNotice no if ( flag & EFFECTFLAG_DAMAGE && PStatusEffect->GetStatusID() == EFFECT_SLEEP && - PStatusEffect->GetTier() > 1) + PStatusEffect->GetTier() >= 5) // Tier 5 = Diabolos NM Nightmare { continue; } @@ -2076,7 +2076,7 @@ void CStatusEffectContainer::TickRegen(timer::time_point tick) if ( !( m_POwner->StatusEffectContainer->GetStatusEffect(EFFECT_SLEEP) && - m_POwner->StatusEffectContainer->GetStatusEffect(EFFECT_SLEEP)->GetTier() > 0)) + m_POwner->StatusEffectContainer->GetStatusEffect(EFFECT_SLEEP)->GetTier() >= 4)) // Tier 4 = Player Avatar Nightmare { WakeUp(); }