From 70a4b6a2b15ff53f7dc9e06c44bbed5c38bf8cc3 Mon Sep 17 00:00:00 2001 From: Fryguy Date: Sun, 7 Jan 2024 02:05:16 -0500 Subject: [PATCH] [Bug Fix] DI/Death Pact Fix (#3867) * [Bug Fix] DI/Death Pact Fix Divine Intervention/Death Pact buffs were always fading the moment a person dropped below 16% regardless if it healed or not. It will now only fade if it succeeds in healing, and it will only check to heal when a person drops below 16% * Requested Updates --- zone/attack.cpp | 5 +++- zone/mob.h | 5 ++++ zone/spell_effects.cpp | 61 +++++++++++++++++++++++------------------- 3 files changed, 42 insertions(+), 29 deletions(-) diff --git a/zone/attack.cpp b/zone/attack.cpp index 4a92c21d6..aac26dd75 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -3810,6 +3810,8 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons if (damage > 0) { //if there is some damage being done and theres an attacker involved + int previous_hp_ratio = GetHPRatio(); + if (attacker) { // if spell is lifetap add hp to the caster if (IsValidSpell(spell_id) && IsLifetapSpell(spell_id)) { @@ -4035,8 +4037,9 @@ void Mob::CommonDamage(Mob* attacker, int64 &damage, const uint16 spell_id, cons } } else { - if (GetHPRatio() < 16) + if (GetHPRatio() < 16 && previous_hp_ratio >= 16) { TryDeathSave(); + } } TryTriggerOnCastRequirement(); diff --git a/zone/mob.h b/zone/mob.h index 0d208ef7b..cdf67df66 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -62,6 +62,11 @@ namespace EQ class ItemInstance; } +namespace DeathSave { + constexpr uint32 HP300 = 1; + constexpr uint32 HP8000 = 2; +} + enum class eSpecialAttacks : int { None, Rampage, diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index 372944791..a43ea8479 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -6970,8 +6970,9 @@ bool Mob::TryDivineSave() -If desired, additional spells can be triggered from the AA/item/spell effect, generally a heal. */ - int32 SuccessChance = aabonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_CHANCE] + itembonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_CHANCE] + spellbonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_CHANCE]; - if (SuccessChance && zone->random.Roll(SuccessChance)) + int32 success_chance = aabonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_CHANCE] + itembonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_CHANCE] + spellbonuses.DivineSaveChance[SBIndex::DIVINE_SAVE_CHANCE]; + + if (success_chance && zone->random.Roll(success_chance)) { SetHP(1); @@ -7016,36 +7017,37 @@ bool Mob::TryDeathSave() { if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE]){ - int SuccessChance = 0; + int success_chance = 0; int buffSlot = spellbonuses.DeathSave[SBIndex::DEATH_SAVE_BUFFSLOT]; int32 UD_HealMod = 0; int64 HealAmt = 300; //Death Pact max Heal if(buffSlot >= 0){ - UD_HealMod = buffs[buffSlot].ExtraDIChance; + success_chance = ((GetCHA() * (RuleI(Spells, DeathSaveCharismaMod))) + 1) / 10; //(CHA Mod Default = 3) - SuccessChance = ( (GetCHA() * (RuleI(Spells, DeathSaveCharismaMod))) + 1) / 10; //(CHA Mod Default = 3) + if (success_chance > 95) { + success_chance = 95; + } - if (SuccessChance > 95) - SuccessChance = 95; - - if(zone->random.Roll(SuccessChance)) { - - if(spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == 2) + if(zone->random.Roll(success_chance)) { + if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == DeathSave::HP8000) { HealAmt = RuleI(Spells, DivineInterventionHeal); //8000HP is how much LIVE Divine Intervention max heals + } //Check if bonus Heal amount can be applied ([3] Bonus Heal [2] Level limit) - if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_HEAL_AMT] && (GetLevel() >= spellbonuses.DeathSave[SBIndex::DEATH_SAVE_MIN_LEVEL_FOR_HEAL])) + if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_HEAL_AMT] && (GetLevel() >= spellbonuses.DeathSave[SBIndex::DEATH_SAVE_MIN_LEVEL_FOR_HEAL])) { HealAmt += spellbonuses.DeathSave[SBIndex::DEATH_SAVE_HEAL_AMT]; + } - if ((GetMaxHP() - GetHP()) < HealAmt) + if ((GetMaxHP() - GetHP()) < HealAmt) { HealAmt = GetMaxHP() - GetHP(); + } SetHP((GetHP()+HealAmt)); Message(Chat::Emote, "The gods have healed you for %i points of damage.", HealAmt); - if(spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == 2) + if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == DeathSave::HP8000) { entity_list.MessageCloseString( this, false, @@ -7053,38 +7055,40 @@ bool Mob::TryDeathSave() { Chat::MeleeCrit, DIVINE_INTERVENTION, GetCleanName()); - else + } else { entity_list.MessageCloseString(this, false, 200, Chat::MeleeCrit, DEATH_PACT, GetCleanName()); + } SendHPUpdate(); - BuffFadeBySlot(buffSlot); return true; } else if (UD_HealMod) { + success_chance = ((GetCHA() * (RuleI(Spells, DeathSaveCharismaMod))) + 1) / 10; - SuccessChance = ((GetCHA() * (RuleI(Spells, DeathSaveCharismaMod))) + 1) / 10; + if (success_chance > 95) { + success_chance = 95; + } - if (SuccessChance > 95) - SuccessChance = 95; - - if(zone->random.Roll(SuccessChance)) { - - if(spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == 2) + if (zone->random.Roll(success_chance)) { + if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == DeathSave::HP8000) { HealAmt = RuleI(Spells, DivineInterventionHeal); + } //Check if bonus Heal amount can be applied ([3] Bonus Heal [2] Level limit) - if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_HEAL_AMT] && (GetLevel() >= spellbonuses.DeathSave[SBIndex::DEATH_SAVE_MIN_LEVEL_FOR_HEAL])) + if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_HEAL_AMT] && (GetLevel() >= spellbonuses.DeathSave[SBIndex::DEATH_SAVE_MIN_LEVEL_FOR_HEAL])) { HealAmt += spellbonuses.DeathSave[SBIndex::DEATH_SAVE_HEAL_AMT]; + } HealAmt = HealAmt*UD_HealMod/100; - if ((GetMaxHP() - GetHP()) < HealAmt) + if ((GetMaxHP() - GetHP()) < HealAmt) { HealAmt = GetMaxHP() - GetHP(); + } SetHP((GetHP()+HealAmt)); Message(Chat::Emote, "The gods have healed you for %i points of damage.", HealAmt); - if(spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == 2) + if (spellbonuses.DeathSave[SBIndex::DEATH_SAVE_TYPE] == DeathSave::HP8000) { entity_list.MessageCloseString( this, false, @@ -7092,9 +7096,10 @@ bool Mob::TryDeathSave() { Chat::MeleeCrit, DIVINE_INTERVENTION, GetCleanName()); - else + } else { entity_list.MessageCloseString(this, false, 200, Chat::MeleeCrit, DEATH_PACT, GetCleanName()); - + } + SendHPUpdate(); BuffFadeBySlot(buffSlot); return true;