diff --git a/sql/updates/world/custom/custom_2019_07_28_02_world.sql b/sql/updates/world/custom/custom_2019_07_28_02_world.sql new file mode 100644 index 0000000000..263d32be50 --- /dev/null +++ b/sql/updates/world/custom/custom_2019_07_28_02_world.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_script_names` WHERE `ScriptName`= 'spell_pri_spirit_of_redemption'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(20711, 'spell_pri_spirit_of_redemption'); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index b48904f0e7..eccc62a95a 100644 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -11782,29 +11782,8 @@ void Unit::Kill(Unit* victim, bool durabilityLoss) if (Player* killerPlayer = GetCharmerOrOwnerPlayerOrPlayerItself()) killerPlayer->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_GET_KILLING_BLOWS, 1, 0, 0, victim); - // if talent known but not triggered - bool spiritOfRedemption = false; - if (AuraEffect const* aurEff = victim->GetAuraEffect(SPELL_AURA_DUMMY, SPELLFAMILY_PRIEST, 0, 0, 0x200)) - { - // save value before aura remove - uint32 ressSpellId = victim->GetUInt32Value(PLAYER_SELF_RES_SPELL); - if (!ressSpellId) - ressSpellId = victim->ToPlayer()->GetResurrectionSpellId(); - // Remove all expected to remove at death auras (most important negative case like DoT or periodic triggers) - victim->RemoveAllAurasOnDeath(); - // restore for use at real death - victim->SetUInt32Value(PLAYER_SELF_RES_SPELL, ressSpellId); - - // FORM_SPIRITOFREDEMPTION and related auras - victim->CastSpell(victim, 27827, aurEff); - spiritOfRedemption = true; - } - - if (!spiritOfRedemption) - { - TC_LOG_DEBUG("entities.unit", "SET JUST_DIED"); - victim->setDeathState(JUST_DIED); - } + TC_LOG_DEBUG("entities.unit", "SET JUST_DIED"); + victim->setDeathState(JUST_DIED); // Inform pets (if any) when player kills target) // MUST come after victim->setDeathState(JUST_DIED); or pet next target diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h index 3d16bea3a8..1fd372cba9 100644 --- a/src/server/game/Miscellaneous/SharedDefines.h +++ b/src/server/game/Miscellaneous/SharedDefines.h @@ -325,6 +325,12 @@ enum WorgenRacialSpells SPELL_ALTERED_FORM_RACIAL = 97709 }; +enum SpiritOfRedemptionSpells +{ + SPELL_SPIRIT_OF_REDEMPTION_IMMUNITY = 62371, + SPELL_UNTRANSFORM_HERO = 25100 +}; + const uint32 ItemQualityColors[MAX_ITEM_QUALITY] = { 0xff9d9d9d, //GREY diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index 979acd7bf5..1eaff5b213 100644 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -1656,26 +1656,18 @@ void AuraEffect::HandleSpiritOfRedemption(AuraApplication const* aurApp, uint8 m if (!(mode & AURA_EFFECT_HANDLE_REAL)) return; - Unit* target = aurApp->GetTarget(); - - if (target->GetTypeId() != TYPEID_PLAYER) + Player* target = aurApp->GetTarget()->ToPlayer(); + if (!target) return; - // prepare spirit state if (apply) { - if (target->GetTypeId() == TYPEID_PLAYER) - { - // set stand state (expected in this form) - if (!target->IsStandState()) - target->SetStandState(UNIT_STAND_STATE_STAND); - } - - target->SetHealth(1); + target->RemoveAllAurasOnDeath(); + target->CastSpell(target, SPELL_UNTRANSFORM_HERO, true); + target->CastSpell(target, SPELL_SPIRIT_OF_REDEMPTION_IMMUNITY, true); + target->SetFullHealth(); } - // die at aura end - else if (target->IsAlive()) - // call functions which may have additional effects after chainging state of unit + else target->setDeathState(JUST_DIED); } diff --git a/src/server/scripts/Spells/spell_priest.cpp b/src/server/scripts/Spells/spell_priest.cpp index 37b169d733..a3826cd3c1 100644 --- a/src/server/scripts/Spells/spell_priest.cpp +++ b/src/server/scripts/Spells/spell_priest.cpp @@ -86,6 +86,7 @@ enum PriestSpells SPELL_PRIEST_SHADOWFORM_VISUAL_WITHOUT_GLYPH = 107903, SPELL_PRIEST_SHADOWFORM_VISUAL_WITH_GLYPH = 107904, SPELL_PRIEST_SHADOW_WORD_DEATH = 32409, + SPELL_PRIEST_SPIRIT_OF_REDEMPTION_TRIGGERED = 27827, SPELL_PRIEST_STRENGTH_OF_SOUL_R1 = 89488, SPELL_PRIEST_STRENGTH_OF_SOUL_TRIGGERED_R1 = 96266, SPELL_PRIEST_STRENGTH_OF_SOUL_TRIGGERED_R2 = 96267, @@ -1587,6 +1588,39 @@ class spell_pri_atonement_heal : public SpellScript } }; +class spell_pri_spirit_of_redemption : public AuraScript +{ + PrepareAuraScript(spell_pri_spirit_of_redemption); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_PRIEST_SPIRIT_OF_REDEMPTION_TRIGGERED }); + } + + void CalculateAmount(AuraEffect const* /*aurEff*/, int32& amount, bool& canBeRecalculated) + { + amount = -1; + } + + void Absorb(AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount) + { + Unit* target = GetTarget(); + uint32 damage = dmgInfo.GetDamage(); + + if (damage >= target->GetHealth() && target->GetAuraEffectsByType(SPELL_AURA_SPIRIT_OF_REDEMPTION).empty()) + { + absorbAmount = damage; + target->CastSpell(target, SPELL_PRIEST_SPIRIT_OF_REDEMPTION_TRIGGERED, true, nullptr, aurEff); + } + } + + void Register() override + { + DoEffectCalcAmount += AuraEffectCalcAmountFn(spell_pri_spirit_of_redemption::CalculateAmount, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB); + OnEffectAbsorb += AuraEffectAbsorbFn(spell_pri_spirit_of_redemption::Absorb, EFFECT_0); + } +}; + void AddSC_priest_spell_scripts() { RegisterSpellScript(spell_pri_archangel); @@ -1625,6 +1659,7 @@ void AddSC_priest_spell_scripts() RegisterAuraScript(spell_pri_shadow_orb_power); RegisterAuraScript(spell_pri_strength_of_soul); RegisterSpellScript(spell_pri_strength_of_soul_script); + RegisterAuraScript(spell_pri_spirit_of_redemption); RegisterAuraScript(spell_pri_renew); RegisterSpellScript(spell_pri_shadow_word_death); RegisterAuraScript(spell_pri_shadowform);