diff options
author | Nay <dnpd.dd@gmail.com> | 2012-09-25 09:26:48 +0100 |
---|---|---|
committer | Nay <dnpd.dd@gmail.com> | 2012-09-25 09:26:48 +0100 |
commit | 15c05ed771331f35c3c32dd692586e599e8f430e (patch) | |
tree | 0bff511acaa52ec3eb9b72dd6a4a2c97b12b75c4 /src | |
parent | 1f79ac8c304d136933eba86391652d552082ed1f (diff) | |
parent | 1b2a010a70ca4462292168da36466341faa537d7 (diff) |
Merge remote-tracking branch 'origin/master' into 4.3.4
Conflicts:
src/server/game/Entities/Unit/Unit.cpp
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 3 | ||||
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 41 | ||||
-rwxr-xr-x | src/server/game/Spells/Auras/SpellAuras.cpp | 15 | ||||
-rwxr-xr-x | src/server/game/Spells/Auras/SpellAuras.h | 2 | ||||
-rwxr-xr-x | src/server/game/Spells/SpellScript.cpp | 18 | ||||
-rwxr-xr-x | src/server/game/Spells/SpellScript.h | 17 | ||||
-rw-r--r-- | src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_hunter.cpp | 2 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_paladin.cpp | 104 |
9 files changed, 193 insertions, 11 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index 463be7b42db..4c9df5f0ed4 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2158,6 +2158,9 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati else sLog->outDebug(LOG_FILTER_MAPS, "Player %s is being teleported to map %u", GetName(), mapid); + if (m_vehicle) + ExitVehicle(); + // reset movement flags at teleport, because player will continue move with these flags after teleport SetUnitMovementFlags(0); DisableSpline(); diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 71976bb3bfd..b9c08296840 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1684,8 +1684,10 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe for (AuraEffectList::iterator itr = vSplitDamagePctCopy.begin(), next; (itr != vSplitDamagePctCopy.end()) && (dmgInfo.GetDamage() > 0); ++itr) { // Check if aura was removed during iteration - we don't need to work on such auras - if (!((*itr)->GetBase()->IsAppliedOnTarget(victim->GetGUID()))) + AuraApplication const* aurApp = (*itr)->GetBase()->GetApplicationOfTarget(victim->GetGUID()); + if (!aurApp) continue; + // check damage school mask if (!((*itr)->GetMiscValue() & schoolMask)) continue; @@ -1695,13 +1697,14 @@ void Unit::CalcAbsorbResist(Unit* victim, SpellSchoolMask schoolMask, DamageEffe if (!caster || (caster == victim) || !caster->IsInWorld() || !caster->isAlive()) continue; - int32 splitDamage = CalculatePctN(dmgInfo.GetDamage(), (*itr)->GetAmount()); + uint32 splitDamage = CalculatePctN(dmgInfo.GetDamage(), (*itr)->GetAmount()); + + (*itr)->GetBase()->CallScriptEffectSplitHandlers((*itr), aurApp, dmgInfo, splitDamage); // absorb must be smaller than the damage itself - splitDamage = RoundToInterval(splitDamage, 0, int32(dmgInfo.GetDamage())); + splitDamage = RoundToInterval(splitDamage, uint32(0), uint32(dmgInfo.GetDamage())); dmgInfo.AbsorbDamage(splitDamage); - uint32 splitted = splitDamage; uint32 split_absorb = 0; DealDamageMods(caster, splitted, &split_absorb); @@ -6338,13 +6341,24 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere // Light's Beacon - Beacon of Light if (dummySpell->Id == 53651) { - if (this->GetTypeId() != TYPEID_PLAYER) + if (!victim) return false; - // Check Party/Raid Group - if (Group *group = this->ToPlayer()->GetGroup()) + triggered_spell_id = 0; + Unit* beaconTarget = NULL; + if (this->GetTypeId() != TYPEID_PLAYER) { - for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + beaconTarget = triggeredByAura->GetBase()->GetCaster(); + if (beaconTarget == this || !(beaconTarget->GetAura(53563, victim->GetGUID()))) + return false; + basepoints0 = int32(damage); + triggered_spell_id = procSpell->IsRankOf(sSpellMgr->GetSpellInfo(365)) ? 53652 : 53654; + } + else + { // Check Party/Raid Group + if (Group *group = this->ToPlayer()->GetGroup()) { + for (GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next()) + { Player* Member = itr->getSource(); // check if it was heal by paladin which casted this beacon of light @@ -6375,10 +6389,15 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere } basepoints0 = CalculatePctN(damage, percent); victim->CastCustomSpell(beaconTarget, 53652, &basepoints0, NULL, NULL, true); - return true; } } } + + if (triggered_spell_id && beaconTarget) + { + victim->CastCustomSpell(beaconTarget, triggered_spell_id, &basepoints0, NULL, NULL, true, 0, triggeredByAura); + return true; + } else return false; } @@ -15391,12 +15410,16 @@ void Unit::RemoveCharmedBy(Unit* charmer) charmer->ToPlayer()->SetClientControl(charmer, 1); charmer->ToPlayer()->SetViewpoint(this, false); charmer->ToPlayer()->SetClientControl(this, 0); + if (GetTypeId() == TYPEID_PLAYER) + ToPlayer()->SetMover(this); break; case CHARM_TYPE_POSSESS: charmer->ToPlayer()->SetClientControl(charmer, 1); charmer->ToPlayer()->SetViewpoint(this, false); charmer->ToPlayer()->SetClientControl(this, 0); charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + if (GetTypeId() == TYPEID_PLAYER) + ToPlayer()->SetMover(this); break; case CHARM_TYPE_CHARM: if (GetTypeId() == TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK) diff --git a/src/server/game/Spells/Auras/SpellAuras.cpp b/src/server/game/Spells/Auras/SpellAuras.cpp index b2c76fe56f0..3cbb5b3ce39 100755 --- a/src/server/game/Spells/Auras/SpellAuras.cpp +++ b/src/server/game/Spells/Auras/SpellAuras.cpp @@ -2059,6 +2059,21 @@ void Aura::CallScriptEffectAfterManaShieldHandlers(AuraEffect* aurEff, AuraAppli } } +void Aura::CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & splitAmount) +{ + for (std::list<AuraScript*>::iterator scritr = m_loadedScripts.begin(); scritr != m_loadedScripts.end(); ++scritr) + { + (*scritr)->_PrepareScriptCall(AURA_SCRIPT_HOOK_EFFECT_SPLIT, aurApp); + std::list<AuraScript::EffectSplitHandler>::iterator effEndItr = (*scritr)->OnEffectSplit.end(), effItr = (*scritr)->OnEffectSplit.begin(); + for (; effItr != effEndItr; ++effItr) + { + if ((*effItr).IsEffectAffected(m_spellInfo, aurEff->GetEffIndex())) + (*effItr).Call(*scritr, aurEff, dmgInfo, splitAmount); + } + (*scritr)->_FinishScriptCall(); + } +} + UnitAura::UnitAura(SpellInfo const* spellproto, uint8 effMask, WorldObject* owner, Unit* caster, int32 *baseAmount, Item* castItem, uint64 casterGUID) : Aura(spellproto, owner, caster, castItem, casterGUID) { diff --git a/src/server/game/Spells/Auras/SpellAuras.h b/src/server/game/Spells/Auras/SpellAuras.h index 36398bafa97..76b972581bb 100755 --- a/src/server/game/Spells/Auras/SpellAuras.h +++ b/src/server/game/Spells/Auras/SpellAuras.h @@ -217,6 +217,8 @@ class Aura void CallScriptEffectAfterAbsorbHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount); void CallScriptEffectManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount, bool & defaultPrevented); void CallScriptEffectAfterManaShieldHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & absorbAmount); + void CallScriptEffectSplitHandlers(AuraEffect* aurEff, AuraApplication const* aurApp, DamageInfo & dmgInfo, uint32 & splitAmount); + std::list<AuraScript*> m_loadedScripts; private: void _DeleteRemovedApplications(); diff --git a/src/server/game/Spells/SpellScript.cpp b/src/server/game/Spells/SpellScript.cpp index 1399934efeb..f7ab6e22f2e 100755 --- a/src/server/game/Spells/SpellScript.cpp +++ b/src/server/game/Spells/SpellScript.cpp @@ -675,6 +675,10 @@ bool AuraScript::_Validate(SpellInfo const* entry) if (!(*itr).GetAffectedEffectsMask(entry)) sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `AfterEffectManaShield` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + for (std::list<EffectSplitHandler>::iterator itr = OnEffectSplit.begin(); itr != OnEffectSplit.end(); ++itr) + if (!(*itr).GetAffectedEffectsMask(entry)) + sLog->outError(LOG_FILTER_TSCR, "Spell `%u` Effect `%s` of script `%s` did not match dbc effect data - handler bound to hook `OnEffectSplit` of AuraScript won't be executed", entry->Id, (*itr).ToString().c_str(), m_scriptName->c_str()); + return _SpellScript::_Validate(entry); } @@ -803,6 +807,17 @@ void AuraScript::EffectManaShieldHandler::Call(AuraScript* auraScript, AuraEffec (auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, absorbAmount); } +AuraScript::EffectSplitHandler::EffectSplitHandler(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex) + : AuraScript::EffectBase(_effIndex, SPELL_AURA_SPLIT_DAMAGE_PCT) +{ + pEffectHandlerScript = _pEffectHandlerScript; +} + +void AuraScript::EffectSplitHandler::Call(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& splitAmount) +{ + (auraScript->*pEffectHandlerScript)(aurEff, dmgInfo, splitAmount); +} + bool AuraScript::_Load(Aura* aura) { m_aura = aura; @@ -837,6 +852,7 @@ bool AuraScript::_IsDefaultActionPrevented() case AURA_SCRIPT_HOOK_EFFECT_REMOVE: case AURA_SCRIPT_HOOK_EFFECT_PERIODIC: case AURA_SCRIPT_HOOK_EFFECT_ABSORB: + case AURA_SCRIPT_HOOK_EFFECT_SPLIT: return m_defaultActionPrevented; default: ASSERT(false && "AuraScript::_IsDefaultActionPrevented is called in a wrong place"); @@ -852,6 +868,7 @@ void AuraScript::PreventDefaultAction() case AURA_SCRIPT_HOOK_EFFECT_REMOVE: case AURA_SCRIPT_HOOK_EFFECT_PERIODIC: case AURA_SCRIPT_HOOK_EFFECT_ABSORB: + case AURA_SCRIPT_HOOK_EFFECT_SPLIT: m_defaultActionPrevented = true; break; default: @@ -1033,6 +1050,7 @@ Unit* AuraScript::GetTarget() const case AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB: case AURA_SCRIPT_HOOK_EFFECT_MANASHIELD: case AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD: + case AURA_SCRIPT_HOOK_EFFECT_SPLIT: return m_auraApplication->GetTarget(); default: sLog->outError(LOG_FILTER_TSCR, "Script: `%s` Spell: `%u` AuraScript::GetTarget called in a hook in which the call won't have effect!", m_scriptName->c_str(), m_scriptSpellId); diff --git a/src/server/game/Spells/SpellScript.h b/src/server/game/Spells/SpellScript.h index 460a4e20d7f..a5d77806739 100755 --- a/src/server/game/Spells/SpellScript.h +++ b/src/server/game/Spells/SpellScript.h @@ -423,6 +423,7 @@ enum AuraScriptHookType AURA_SCRIPT_HOOK_EFFECT_AFTER_ABSORB, AURA_SCRIPT_HOOK_EFFECT_MANASHIELD, AURA_SCRIPT_HOOK_EFFECT_AFTER_MANASHIELD, + AURA_SCRIPT_HOOK_EFFECT_SPLIT, AURA_SCRIPT_HOOK_CHECK_AREA_TARGET, AURA_SCRIPT_HOOK_DISPEL, AURA_SCRIPT_HOOK_AFTER_DISPEL @@ -449,6 +450,7 @@ class AuraScript : public _SpellScript typedef void(CLASSNAME::*AuraEffectCalcPeriodicFnType)(AuraEffect const*, bool &, int32 &); \ typedef void(CLASSNAME::*AuraEffectCalcSpellModFnType)(AuraEffect const*, SpellModifier* &); \ typedef void(CLASSNAME::*AuraEffectAbsorbFnType)(AuraEffect*, DamageInfo &, uint32 &); \ + typedef void(CLASSNAME::*AuraEffectSplitFnType)(AuraEffect*, DamageInfo &, uint32 &); \ AURASCRIPT_FUNCTION_TYPE_DEFINES(AuraScript) @@ -540,6 +542,14 @@ class AuraScript : public _SpellScript private: AuraEffectAbsorbFnType pEffectHandlerScript; }; + class EffectSplitHandler : public EffectBase + { + public: + EffectSplitHandler(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex); + void Call(AuraScript* auraScript, AuraEffect* aurEff, DamageInfo & dmgInfo, uint32 & splitAmount); + private: + AuraEffectSplitFnType pEffectHandlerScript; + }; #define AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) \ class CheckAreaTargetFunction : public AuraScript::CheckAreaTargetHandler { public: CheckAreaTargetFunction(AuraCheckAreaTargetFnType _pHandlerScript) : AuraScript::CheckAreaTargetHandler((AuraScript::AuraCheckAreaTargetFnType)_pHandlerScript) {} }; \ @@ -552,6 +562,7 @@ class AuraScript : public _SpellScript class EffectApplyHandlerFunction : public AuraScript::EffectApplyHandler { public: EffectApplyHandlerFunction(AuraEffectApplicationModeFnType _pEffectHandlerScript, uint8 _effIndex, uint16 _effName, AuraEffectHandleModes _mode) : AuraScript::EffectApplyHandler((AuraScript::AuraEffectApplicationModeFnType)_pEffectHandlerScript, _effIndex, _effName, _mode) {} }; \ class EffectAbsorbFunction : public AuraScript::EffectAbsorbHandler { public: EffectAbsorbFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectAbsorbHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \ class EffectManaShieldFunction : public AuraScript::EffectManaShieldHandler { public: EffectManaShieldFunction(AuraEffectAbsorbFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectManaShieldHandler((AuraScript::AuraEffectAbsorbFnType)_pEffectHandlerScript, _effIndex) {} }; \ + class EffectSplitFunction : public AuraScript::EffectSplitHandler { public: EffectSplitFunction(AuraEffectSplitFnType _pEffectHandlerScript, uint8 _effIndex) : AuraScript::EffectSplitHandler((AuraScript::AuraEffectSplitFnType)_pEffectHandlerScript, _effIndex) {} }; \ #define PrepareAuraScript(CLASSNAME) AURASCRIPT_FUNCTION_TYPE_DEFINES(CLASSNAME) AURASCRIPT_FUNCTION_CAST_DEFINES(CLASSNAME) @@ -676,6 +687,12 @@ class AuraScript : public _SpellScript // where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& absorbAmount); HookList<EffectManaShieldHandler> AfterEffectManaShield; + // executed when the caster of some spell with split dmg aura gets damaged through it + // example: OnEffectSplit += AuraEffectSplitFn(class::function, EffectIndexSpecifier); + // where function is: void function (AuraEffect* aurEff, DamageInfo& dmgInfo, uint32& splitAmount); + HookList<EffectSplitHandler> OnEffectSplit; + #define AuraEffectSplitFn(F, I) EffectSplitFunction(&F, I) + // AuraScript interface - hook/effect execution manipulators // prevents default action of a hook from being executed (works only while called in a hook which default action can be prevented) diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp index 5a0560293da..03427a4cfc2 100644 --- a/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp +++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_rotface.cpp @@ -124,9 +124,9 @@ class boss_rotface : public CreatureScript void JustDied(Unit* /*killer*/) { + instance->DoRemoveAurasDueToSpellOnPlayers(MUTATED_INFECTION); _JustDied(); Talk(SAY_DEATH); - instance->DoRemoveAurasDueToSpellOnPlayers(MUTATED_INFECTION); if (Creature* professor = Unit::GetCreature(*me, instance->GetData64(DATA_PROFESSOR_PUTRICIDE))) professor->AI()->DoAction(ACTION_ROTFACE_DEATH); } diff --git a/src/server/scripts/Spells/spell_hunter.cpp b/src/server/scripts/Spells/spell_hunter.cpp index a2ee6c1c3a3..e445f68cfba 100644 --- a/src/server/scripts/Spells/spell_hunter.cpp +++ b/src/server/scripts/Spells/spell_hunter.cpp @@ -574,7 +574,7 @@ class spell_hun_misdirection : public SpellScriptLoader void OnRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) { if (Unit* caster = GetCaster()) - if (!GetDuration()) + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_DEFAULT) caster->SetReducedThreatPercent(0, 0); } diff --git a/src/server/scripts/Spells/spell_paladin.cpp b/src/server/scripts/Spells/spell_paladin.cpp index 557cef24ee6..3570c9e8d75 100644 --- a/src/server/scripts/Spells/spell_paladin.cpp +++ b/src/server/scripts/Spells/spell_paladin.cpp @@ -24,6 +24,7 @@ #include "ScriptMgr.h" #include "SpellScript.h" #include "SpellAuraEffects.h" +#include "Group.h" enum PaladinSpells @@ -47,6 +48,9 @@ enum PaladinSpells SPELL_FORBEARANCE = 25771, SPELL_AVENGING_WRATH_MARKER = 61987, SPELL_IMMUNE_SHIELD_MARKER = 61988, + + SPELL_HAND_OF_SACRIFICE = 6940, + SPELL_DIVINE_SACRIFICE = 64205, }; // 31850 - Ardent Defender @@ -566,6 +570,104 @@ class spell_pal_exorcism_and_holy_wrath_damage : public SpellScriptLoader } }; +class spell_pal_hand_of_sacrifice : public SpellScriptLoader +{ + public: + spell_pal_hand_of_sacrifice() : SpellScriptLoader("spell_pal_hand_of_sacrifice") { } + + class spell_pal_hand_of_sacrifice_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_hand_of_sacrifice_AuraScript); + + int32 remainingAmount; + + bool Load() + { + if (Unit* caster = GetCaster()) + { + remainingAmount = caster->GetMaxHealth(); + return true; + } + return false; + } + + void Split(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & splitAmount) + { + remainingAmount -= splitAmount; + + if (remainingAmount <= 0) + { + GetTarget()->RemoveAura(SPELL_HAND_OF_SACRIFICE); + } + } + + void Register() + { + OnEffectSplit += AuraEffectSplitFn(spell_pal_hand_of_sacrifice_AuraScript::Split, EFFECT_0); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pal_hand_of_sacrifice_AuraScript(); + } +}; + +class spell_pal_divine_sacrifice : public SpellScriptLoader +{ + public: + spell_pal_divine_sacrifice() : SpellScriptLoader("spell_pal_divine_sacrifice") { } + + class spell_pal_divine_sacrifice_AuraScript : public AuraScript + { + PrepareAuraScript(spell_pal_divine_sacrifice_AuraScript); + + uint32 groupSize, minHpPct; + int32 remainingAmount; + + bool Load() + { + + if (Unit* caster = GetCaster()) + { + if (caster->GetTypeId() == TYPEID_PLAYER) + { + if (caster->ToPlayer()->GetGroup()) + groupSize = caster->ToPlayer()->GetGroup()->GetMembersCount(); + else + groupSize = 1; + } + else + return false; + + remainingAmount = (caster->CountPctFromMaxHealth(GetSpellInfo()->Effects[EFFECT_2].CalcValue(caster)) * groupSize); + minHpPct = GetSpellInfo()->Effects[EFFECT_1].CalcValue(caster); + return true; + } + return false; + } + + void Split(AuraEffect* /*aurEff*/, DamageInfo & /*dmgInfo*/, uint32 & splitAmount) + { + remainingAmount -= splitAmount; + // break when absorbed everything it could, or if the casters hp drops below 20% + if (Unit* caster = GetCaster()) + if (remainingAmount <= 0 || (caster->GetHealthPct() < minHpPct)) + caster->RemoveAura(SPELL_DIVINE_SACRIFICE); + } + + void Register() + { + OnEffectSplit += AuraEffectSplitFn(spell_pal_divine_sacrifice_AuraScript::Split, EFFECT_0); + } + }; + + AuraScript* GetAuraScript() const + { + return new spell_pal_divine_sacrifice_AuraScript(); + } +}; + void AddSC_paladin_spell_scripts() { //new spell_pal_ardent_defender(); @@ -579,4 +681,6 @@ void AddSC_paladin_spell_scripts() new spell_pal_lay_on_hands(); new spell_pal_righteous_defense(); new spell_pal_exorcism_and_holy_wrath_damage(); + new spell_pal_hand_of_sacrifice(); + new spell_pal_divine_sacrifice(); } |