diff options
Diffstat (limited to 'src')
| -rwxr-xr-x | src/server/game/Spells/SpellEffects.cpp | 7 | ||||
| -rwxr-xr-x | src/server/game/Spells/SpellMgr.cpp | 9 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp | 692 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp | 27 | ||||
| -rw-r--r-- | src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h | 1 |
5 files changed, 439 insertions, 297 deletions
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 4c0fec17774..dc1c1f78b12 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -1633,13 +1633,6 @@ void Spell::EffectForceCast(SpellEffIndex effIndex) } } - switch (triggered_spell_id) - { - case 62056: case 63985: // Stone Grip Forcecast (10m, 25m) - unitTarget->CastSpell(unitTarget, spellInfo, true); // Don't send m_originalCasterGUID param here or underlying - return; // AureEffect::HandleAuraControlVehicle will fail on caster == target - } - Unit * caster = GetTriggeredSpellCaster(spellInfo, m_caster, unitTarget); caster->CastSpell(unitTarget, spellInfo, true, NULL, NULL, m_originalCasterGUID); diff --git a/src/server/game/Spells/SpellMgr.cpp b/src/server/game/Spells/SpellMgr.cpp index d0b6fefa10d..0b8276f2c74 100755 --- a/src/server/game/Spells/SpellMgr.cpp +++ b/src/server/game/Spells/SpellMgr.cpp @@ -3946,7 +3946,16 @@ void SpellMgr::LoadSpellCustomAttr() spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_MASTER; count++; break; + // ULDUAR SPELLS + // + case 63342: // Focused Eyebeam Summon Trigger + spellInfo->MaxAffectedTargets = 1; + count++; + break; + // ENDOF ULDUAR SPELLS + // // ICECROWN CITADEL SPELLS + // // THESE SPELLS ARE WORKING CORRECTLY EVEN WITHOUT THIS HACK // THE ONLY REASON ITS HERE IS THAT CURRENT GRID SYSTEM // DOES NOT ALLOW FAR OBJECT SELECTION (dist > 333) diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp index 4128c6940cb..a7633d27dd3 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp @@ -85,385 +85,496 @@ enum class boss_kologarn : public CreatureScript { -public: - boss_kologarn() : CreatureScript("boss_kologarn") { } - - CreatureAI* GetAI(Creature* pCreature) const - { - return new boss_kologarnAI (pCreature); - } - - struct boss_kologarnAI : public BossAI - { - boss_kologarnAI(Creature *pCreature) : BossAI(pCreature, TYPE_KOLOGARN), vehicle(pCreature->GetVehicleKit()), - left(false), right(false) - { - ASSERT(vehicle); - - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); - SetCombatMovement(false); - Reset(); - } + public: + boss_kologarn() : CreatureScript("boss_kologarn") { } - Vehicle *vehicle; - bool left, right; - uint64 eyebeamTarget; - - void EnterCombat(Unit * who) + CreatureAI* GetAI(Creature* pCreature) const { - DoScriptText(SAY_AGGRO, me); - - events.ScheduleEvent(EVENT_MELEE_CHECK, 6000); - events.ScheduleEvent(EVENT_SMASH, 5000); - events.ScheduleEvent(EVENT_SWEEP, 19000); - events.ScheduleEvent(EVENT_STONE_GRIP, 25000); - events.ScheduleEvent(EVENT_FOCUSED_EYEBEAM, 21000); - events.ScheduleEvent(EVENT_ENRAGE, 600000); - - Unit* arm = NULL; - if (arm = vehicle->GetPassenger(0)) - arm->Attack(who, true); - if (arm = vehicle->GetPassenger(1)) - arm->Attack(who, true); - - _EnterCombat(); + return new boss_kologarnAI (pCreature); } - void Reset() + struct boss_kologarnAI : public BossAI { - _Reset(); + boss_kologarnAI(Creature *pCreature) : BossAI(pCreature, TYPE_KOLOGARN), vehicle(pCreature->GetVehicleKit()), + left(false), right(false) + { + ASSERT(vehicle); - if (Creature* arm = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_LEFT_ARM) : 0)) - RespawnArm(arm); - if (Creature* arm = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_RIGHT_ARM) : 0)) - RespawnArm(arm); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE); + SetCombatMovement(false); + Reset(); + } - eyebeamTarget = 0; - } + Vehicle *vehicle; + bool left, right; + uint64 eyebeamTarget; - void JustDied(Unit * /*victim*/) - { - DoScriptText(SAY_DEATH, me); - _JustDied(); - } + void EnterCombat(Unit * who) + { + DoScriptText(SAY_AGGRO, me); + + events.ScheduleEvent(EVENT_MELEE_CHECK, 6000); + events.ScheduleEvent(EVENT_SMASH, 5000); + events.ScheduleEvent(EVENT_SWEEP, 19000); + events.ScheduleEvent(EVENT_STONE_GRIP, 25000); + events.ScheduleEvent(EVENT_FOCUSED_EYEBEAM, 21000); + events.ScheduleEvent(EVENT_ENRAGE, 600000); + + for (uint8 i = 0; i < 2; ++i) + if (Unit* arm = vehicle->GetPassenger(i)) + arm->ToCreature()->SetInCombatWithZone(); + + _EnterCombat(); + } - void KilledUnit(Unit* /*who*/) - { - DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me); - } + void Reset() + { + _Reset(); - void PassengerBoarded(Unit *who, int8 /*seatId*/, bool apply) - { - if (who->GetEntry() == NPC_LEFT_ARM) + if (Creature* arm = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_LEFT_ARM) : 0)) + RespawnArm(arm); + if (Creature* arm = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_RIGHT_ARM) : 0)) + RespawnArm(arm); + + eyebeamTarget = 0; + } + + void JustDied(Unit * /*victim*/) { - left = apply; - if (!apply) - { - DoScriptText(SAY_LEFT_ARM_GONE, me); - events.ScheduleEvent(EVENT_RESPAWN_LEFT_ARM, 40000); - } - else - instance->SetData64(DATA_LEFT_ARM, who->GetGUID()); + DoScriptText(SAY_DEATH, me); + _JustDied(); } - else if (who->GetEntry() == NPC_RIGHT_ARM) + void KilledUnit(Unit* /*who*/) { - right = apply; - if (!apply) - { - DoScriptText(SAY_RIGHT_ARM_GONE, me); - events.ScheduleEvent(EVENT_RESPAWN_RIGHT_ARM, 40000); - } - else - instance->SetData64(DATA_RIGHT_ARM, who->GetGUID()); + DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me); } - if (!apply) + void PassengerBoarded(Unit *who, int8 /*seatId*/, bool apply) { - who->CastSpell(me, SPELL_ARM_DEAD_DAMAGE, true); - who->GetMotionMaster()->MoveTargetedHome(); - - if (Creature* rubbleStalker = me->FindNearestCreature(NPC_RUBBLE_STALKER, 20.0f)) + if (who->GetEntry() == NPC_LEFT_ARM) + { + left = apply; + if (!apply) + { + DoScriptText(SAY_LEFT_ARM_GONE, me); + events.ScheduleEvent(EVENT_RESPAWN_LEFT_ARM, 40000); + } + else + instance->SetData64(DATA_LEFT_ARM, who->GetGUID()); + } + + else if (who->GetEntry() == NPC_RIGHT_ARM) { - if (rubbleStalker) + right = apply; + if (!apply) { - rubbleStalker->CastSpell(rubbleStalker, SPELL_FALLING_RUBBLE, true); - rubbleStalker->CastSpell(rubbleStalker, SPELL_SUMMON_RUBBLE, true); + DoScriptText(SAY_RIGHT_ARM_GONE, me); + events.ScheduleEvent(EVENT_RESPAWN_RIGHT_ARM, 40000); } + else + instance->SetData64(DATA_RIGHT_ARM, who->GetGUID()); } - if (!right && !left) - events.ScheduleEvent(EVENT_STONE_SHOUT, 5000); + if (!apply) + { + who->CastSpell(me, SPELL_ARM_DEAD_DAMAGE, true); + who->GetMotionMaster()->MoveTargetedHome(); + + if (Creature* rubbleStalker = me->FindNearestCreature(NPC_RUBBLE_STALKER, 20.0f)) + { + if (rubbleStalker) + { + rubbleStalker->CastSpell(rubbleStalker, SPELL_FALLING_RUBBLE, true); + rubbleStalker->CastSpell(rubbleStalker, SPELL_SUMMON_RUBBLE, true); + } + } + + if (!right && !left) + events.ScheduleEvent(EVENT_STONE_SHOUT, 5000); - if (instance) - instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_DISARMED_START_EVENT); + if (instance) + instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_DISARMED_START_EVENT); + } + else + { + events.CancelEvent(EVENT_STONE_SHOUT); + who->ToCreature()->SetInCombatWithZone(); + } } - else - events.CancelEvent(EVENT_STONE_SHOUT); - } - void JustSummoned(Creature *summon) - { - switch (summon->GetEntry()) + void JustSummoned(Creature *summon) { - case NPC_FOCUSED_EYEBEAM: - summon->CastSpell(me, SPELL_FOCUSED_EYEBEAM_VISUAL_LEFT, true); - break; - case NPC_FOCUSED_EYEBEAM_RIGHT: - summon->CastSpell(me, SPELL_FOCUSED_EYEBEAM_VISUAL_RIGHT, true); - break; - default: - return; - } + switch (summon->GetEntry()) + { + case NPC_FOCUSED_EYEBEAM: + summon->CastSpell(me, SPELL_FOCUSED_EYEBEAM_VISUAL_LEFT, true); + break; + case NPC_FOCUSED_EYEBEAM_RIGHT: + summon->CastSpell(me, SPELL_FOCUSED_EYEBEAM_VISUAL_RIGHT, true); + break; + default: + return; + } - summon->CastSpell(summon, SPELL_FOCUSED_EYEBEAM_PERIODIC, true); - summon->CastSpell(summon, SPELL_FOCUSED_EYEBEAM_VISUAL, true); - summon->SetReactState(REACT_PASSIVE); - summon->SetFlag(UNIT_FIELD_ATTACK_POWER, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED); - // One of the above spells is a channeled spell, we need to clear this unit state for MoveChase to work - summon->ClearUnitState(UNIT_STAT_CASTING); + summon->CastSpell(summon, SPELL_FOCUSED_EYEBEAM_PERIODIC, true); + summon->CastSpell(summon, SPELL_FOCUSED_EYEBEAM_VISUAL, true); + summon->SetReactState(REACT_PASSIVE); + summon->SetFlag(UNIT_FIELD_ATTACK_POWER, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_PACIFIED); + // One of the above spells is a channeled spell, we need to clear this unit state for MoveChase to work + summon->ClearUnitState(UNIT_STAT_CASTING); - // Victim gets 67351 - if (eyebeamTarget) - { - if (Unit* target = Unit::GetUnit(*summon, eyebeamTarget)) + // Victim gets 67351 + if (eyebeamTarget) { - summon->Attack(target, false); - summon->GetMotionMaster()->MoveChase(target); + if (Unit* target = Unit::GetUnit(*summon, eyebeamTarget)) + { + summon->Attack(target, false); + summon->GetMotionMaster()->MoveChase(target); + } } } - } - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + void UpdateAI(const uint32 diff) + { + if (!UpdateVictim()) + return; - events.Update(diff); + events.Update(diff); - if (me->HasUnitState(UNIT_STAT_CASTING)) - return; + if (me->HasUnitState(UNIT_STAT_CASTING)) + return; - switch (events.GetEvent()) - { - case EVENT_MELEE_CHECK: - if (!me->IsWithinMeleeRange(me->getVictim())) - DoCast(SPELL_PETRIFY_BREATH); - events.RepeatEvent(1000); - break; - case EVENT_SWEEP: - DoCast(me->FindNearestCreature(NPC_ARM_SWEEP_STALKER, 500.0f, true), SPELL_ARM_SWEEP, true); - events.RepeatEvent(25000); - break; - case EVENT_SMASH: - if (left && right) - DoCastVictim(SPELL_TWO_ARM_SMASH); - else if (left || right) - DoCastVictim(SPELL_ONE_ARM_SMASH); - events.RepeatEvent(15000); - break; - case EVENT_STONE_SHOUT: - DoCast(SPELL_STONE_SHOUT); - events.RepeatEvent(2000); - break; - case EVENT_ENRAGE: - DoCast(SPELL_BERSERK); - DoScriptText(SAY_BERSERK, me); - events.CancelEvent(EVENT_ENRAGE); - break; - case EVENT_RESPAWN_LEFT_ARM: - { - if (Creature* arm = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_LEFT_ARM) : 0)) - RespawnArm(arm->ToCreature()); - events.CancelEvent(EVENT_RESPAWN_LEFT_ARM); - break; - } - case EVENT_RESPAWN_RIGHT_ARM: + switch (events.GetEvent()) { - if (Creature* arm = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_RIGHT_ARM) : 0)) - RespawnArm(arm->ToCreature()); - events.CancelEvent(EVENT_RESPAWN_RIGHT_ARM); - break; - } - case EVENT_STONE_GRIP: - { - if (right) + case EVENT_MELEE_CHECK: + if (!me->IsWithinMeleeRange(me->getVictim())) + DoCast(SPELL_PETRIFY_BREATH); + events.RepeatEvent(1000); + break; + case EVENT_SWEEP: + DoCast(me->FindNearestCreature(NPC_ARM_SWEEP_STALKER, 500.0f, true), SPELL_ARM_SWEEP, true); + events.RepeatEvent(25000); + break; + case EVENT_SMASH: + if (left && right) + DoCastVictim(SPELL_TWO_ARM_SMASH); + else if (left || right) + DoCastVictim(SPELL_ONE_ARM_SMASH); + events.RepeatEvent(15000); + break; + case EVENT_STONE_SHOUT: + DoCast(SPELL_STONE_SHOUT); + events.RepeatEvent(2000); + break; + case EVENT_ENRAGE: + DoCast(SPELL_BERSERK); + DoScriptText(SAY_BERSERK, me); + events.CancelEvent(EVENT_ENRAGE); + break; + case EVENT_RESPAWN_LEFT_ARM: + { + if (Creature* arm = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_LEFT_ARM) : 0)) + RespawnArm(arm->ToCreature()); + events.CancelEvent(EVENT_RESPAWN_LEFT_ARM); + break; + } + case EVENT_RESPAWN_RIGHT_ARM: + { + if (Creature* arm = Unit::GetCreature(*me, instance ? instance->GetData64(DATA_RIGHT_ARM) : 0)) + RespawnArm(arm->ToCreature()); + events.CancelEvent(EVENT_RESPAWN_RIGHT_ARM); + break; + } + case EVENT_STONE_GRIP: { - std::list<Unit*> targetList; - std::list<Unit*>::const_iterator itr; - SelectTargetList(targetList, RAID_MODE(1, 3), SELECT_TARGET_RANDOM, 0.0f, true); - for (itr = targetList.begin(); itr != targetList.end(); ++itr) + if (right) { - DoCast((*itr), SPELL_STONE_GRIP, true); - /* 10 man: */ - // Cast 62056 -> HandleAuraLinked (64224) -> Apply 64224 -> Absorb damage - // -> Apply Stun with basepoints 64290 - // Cast 64290 -> Trigger spell (64708) Squeezed Lifeless - // -> Periodic damage - // Cast 63962 -> Visual + DoCast(SPELL_STONE_GRIP); + DoScriptText(SAY_GRAB_PLAYER, me); } - DoScriptText(SAY_GRAB_PLAYER, me); + events.RepeatEvent(25000); } - events.RepeatEvent(25000); + break; + case EVENT_FOCUSED_EYEBEAM: + Unit* eyebeamTargetUnit = SelectTarget(SELECT_TARGET_FARTHEST, 0, -10.0f, true); + if (eyebeamTargetUnit) + { + eyebeamTarget = eyebeamTargetUnit->GetGUID(); + DoCast(SPELL_SUMMON_FOCUSED_EYEBEAM); + } + events.RepeatEvent(urand(15000, 35000)); + break; } - break; - case EVENT_FOCUSED_EYEBEAM: - Unit* eyebeamTargetUnit = SelectTarget(SELECT_TARGET_RANDOM); - if (!eyebeamTargetUnit) - return; - eyebeamTarget = eyebeamTargetUnit->GetGUID(); - DoCast(SPELL_SUMMON_FOCUSED_EYEBEAM); - events.RepeatEvent(urand(15000, 35000)); - break; + DoMeleeAttackIfReady(); } - DoMeleeAttackIfReady(); - } + void RespawnArm(Creature* arm) + { + if (!arm->isAlive()) + arm->Respawn(); - void RespawnArm(Creature* arm) + arm->EnterVehicle(vehicle); + arm->CastSpell(arm, SPELL_ARM_ENTER_VISUAL, true); + } + }; +}; + +class spell_ulduar_rubble_summon : public SpellScriptLoader +{ + public: + spell_ulduar_rubble_summon() : SpellScriptLoader("spell_ulduar_rubble_summon") { } + + class spell_ulduar_rubble_summonSpellScript : public SpellScript { - if (!arm->isAlive()) - arm->Respawn(); + PrepareSpellScript(spell_ulduar_rubble_summonSpellScript); + + void HandleScript(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + uint32 spellId = GetEffectValue(); + for (uint8 i = 0; i < 5; ++i) + caster->CastSpell(caster, spellId, true); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_ulduar_rubble_summonSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; - arm->EnterVehicle(vehicle); - arm->CastSpell(arm, SPELL_ARM_ENTER_VISUAL, true); + SpellScript* GetSpellScript() const + { + return new spell_ulduar_rubble_summonSpellScript(); } - }; }; -class spell_ulduar_rubble_summon : public SpellScriptLoader +// predicate function to select non main tank target +class StoneGripTargetSelector : public std::unary_function<Unit *, bool> { -public: - spell_ulduar_rubble_summon() : SpellScriptLoader("spell_ulduar_rubble_summon") { } + public: + StoneGripTargetSelector(Creature* me, const Unit* victim) : _me(me), _victim(victim) {} - class spell_ulduar_rubble_summonSpellScript : public SpellScript - { - PrepareSpellScript(spell_ulduar_rubble_summonSpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) + bool operator() (Unit* pTarget) { - Unit* caster = GetCaster(); - if (!caster) - return; + if (pTarget == _victim && _me->getThreatManager().getThreatList().size() > 1) + return true; + + if (pTarget->GetTypeId() != TYPEID_PLAYER) + return true; - uint32 spellId = GetEffectValue(); - for (uint8 i = 0; i < 5; ++i) - caster->CastSpell(caster, spellId, true); + return false; } - void Register() + Creature* _me; + Unit const* _victim; +}; + +class spell_ulduar_stone_grip_cast_target : public SpellScriptLoader +{ + public: + spell_ulduar_stone_grip_cast_target() : SpellScriptLoader("spell_ulduar_stone_grip_cast_target") { } + + class spell_ulduar_stone_grip_cast_target_SpellScript : public SpellScript { - OnEffect += SpellEffectFn(spell_ulduar_rubble_summonSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); - } - }; + PrepareSpellScript(spell_ulduar_stone_grip_cast_target_SpellScript); - SpellScript* GetSpellScript() const - { - return new spell_ulduar_rubble_summonSpellScript(); - } + bool Load() + { + if (GetCaster()->GetTypeId() != TYPEID_UNIT) + return false; + return true; + } + + void FilterTargetsInitial(std::list<Unit*>& unitList) + { + // Remove "main tank" and non-player targets + unitList.remove_if(StoneGripTargetSelector(GetCaster()->ToCreature(), GetCaster()->getVictim())); + // Maximum affected targets per difficulty mode + uint32 maxTargets = 1; + if (GetSpellInfo()->Id == 63981) + maxTargets = 3; + + // Return a random amount of targets based on maxTargets + while (maxTargets < unitList.size()) + { + std::list<Unit*>::iterator itr = unitList.begin(); + advance(itr, urand(0, unitList.size()-1)); + unitList.erase(itr); + } + + // For subsequent effects + m_unitList = unitList; + } + + void FillTargetsSubsequential(std::list<Unit*>& unitList) + { + unitList = m_unitList; + } + + void HandleForceCast(SpellEffIndex i) + { + ASSERT (GetCaster()->ToCreature()) + Player * plr = GetHitPlayer(); + ASSERT (plr) + plr->CastSpell(GetTargetUnit(), GetSpellInfo()->EffectTriggerSpell[i], true); // Don't send m_originalCasterGUID param here or underlying + PreventHitEffect(i); // AureEffect::HandleAuraControlVehicle will fail on caster == target + } + + void Register() + { + OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FilterTargetsInitial, EFFECT_0, TARGET_UNIT_AREA_ENEMY_SRC); + OnEffect += SpellEffectFn(spell_ulduar_stone_grip_cast_target_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_1, TARGET_UNIT_AREA_ENEMY_SRC); + OnUnitTargetSelect += SpellUnitTargetFn(spell_ulduar_stone_grip_cast_target_SpellScript::FillTargetsSubsequential, EFFECT_2, TARGET_UNIT_AREA_ENEMY_SRC); + } + + // Shared between effects + std::list<Unit*> m_unitList; + }; + + SpellScript* GetSpellScript() const + { + return new spell_ulduar_stone_grip_cast_target_SpellScript(); + } }; class spell_ulduar_cancel_stone_grip : public SpellScriptLoader { -public: - spell_ulduar_cancel_stone_grip() : SpellScriptLoader("spell_ulduar_cancel_stone_grip") { } + public: + spell_ulduar_cancel_stone_grip() : SpellScriptLoader("spell_ulduar_cancel_stone_grip") { } - class spell_ulduar_cancel_stone_gripSpellScript : public SpellScript - { - PrepareSpellScript(spell_ulduar_cancel_stone_gripSpellScript); - - void HandleScript(SpellEffIndex /*effIndex*/) + class spell_ulduar_cancel_stone_gripSpellScript : public SpellScript { - Unit* target = this->GetHitPlayer(); - if (!target) - return; + PrepareSpellScript(spell_ulduar_cancel_stone_gripSpellScript); - switch (target->GetMap()->GetDifficulty()) + void HandleScript(SpellEffIndex /*effIndex*/) { - case RAID_DIFFICULTY_10MAN_NORMAL: - target->RemoveAura(SpellMgr::CalculateSpellEffectAmount(GetSpellInfo(), EFFECT_0)); - break; - case RAID_DIFFICULTY_25MAN_NORMAL: - target->RemoveAura(SpellMgr::CalculateSpellEffectAmount(GetSpellInfo(), EFFECT_1)); - break; + Unit* target = this->GetHitPlayer(); + if (!target) + return; + + if (!target->GetVehicle()) + return; + + switch (target->GetMap()->GetDifficulty()) + { + case RAID_DIFFICULTY_10MAN_NORMAL: + target->RemoveAura(SpellMgr::CalculateSpellEffectAmount(GetSpellInfo(), EFFECT_0)); + break; + case RAID_DIFFICULTY_25MAN_NORMAL: + target->RemoveAura(SpellMgr::CalculateSpellEffectAmount(GetSpellInfo(), EFFECT_1)); + break; + } } - } - void Register() + void Register() + { + OnEffect += SpellEffectFn(spell_ulduar_cancel_stone_gripSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } + }; + + SpellScript* GetSpellScript() const { - OnEffect += SpellEffectFn(spell_ulduar_cancel_stone_gripSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + return new spell_ulduar_cancel_stone_gripSpellScript(); } - }; - - SpellScript* GetSpellScript() const - { - return new spell_ulduar_cancel_stone_gripSpellScript(); - } }; class spell_ulduar_stone_grip_absorb : public SpellScriptLoader { -public: - spell_ulduar_stone_grip_absorb() : SpellScriptLoader("spell_ulduar_stone_grip_absorb") { } + public: + spell_ulduar_stone_grip_absorb() : SpellScriptLoader("spell_ulduar_stone_grip_absorb") { } - class spell_ulduar_stone_grip_absorb_AuraScript : public AuraScript - { - PrepareAuraScript(spell_ulduar_stone_grip_absorb_AuraScript); - - //! This will be called when Right Arm (vehicle) has sustained a specific amount of damage depending on instance mode - //! What we do here is remove all harmful aura's related and teleport to safe spot. - void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes /*mode*/) + class spell_ulduar_stone_grip_absorb_AuraScript : public AuraScript { - if (!GetOwner()->ToCreature()) - return; + PrepareAuraScript(spell_ulduar_stone_grip_absorb_AuraScript); - uint32 rubbleStalkerEntry = (GetOwner()->GetMap()->GetDifficulty() == DUNGEON_DIFFICULTY_NORMAL ? 33809 : 33942); - Creature* rubbleStalker = GetOwner()->FindNearestCreature(rubbleStalkerEntry, 200.0f, true); - if (rubbleStalker) - rubbleStalker->CastSpell(rubbleStalker, SPELL_STONE_GRIP_CANCEL, true); - } + //! This will be called when Right Arm (vehicle) has sustained a specific amount of damage depending on instance mode + //! What we do here is remove all harmful aura's related and teleport to safe spot. + void OnRemove(AuraEffect const* aurEff, AuraEffectHandleModes mode) + { + if (!(mode & AURA_EFFECT_HANDLE_REAL)) + return; + + if (GetTargetApplication()->GetRemoveMode() != AURA_REMOVE_BY_ENEMY_SPELL) + return; + + if (!GetOwner()->ToCreature()) + return; + + uint32 rubbleStalkerEntry = (GetOwner()->GetMap()->GetDifficulty() == DUNGEON_DIFFICULTY_NORMAL ? 33809 : 33942); + Creature* rubbleStalker = GetOwner()->FindNearestCreature(rubbleStalkerEntry, 200.0f, true); + if (rubbleStalker) + rubbleStalker->CastSpell(rubbleStalker, SPELL_STONE_GRIP_CANCEL, true); + } + + void Register() + { + OnEffectRemove += AuraEffectRemoveFn(spell_ulduar_stone_grip_absorb_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL); + } + }; - void Register() + AuraScript* GetAuraScript() const { - OnEffectRemove += AuraEffectRemoveFn(spell_ulduar_stone_grip_absorb_AuraScript::OnRemove, EFFECT_0, SPELL_AURA_SCHOOL_ABSORB, AURA_EFFECT_HANDLE_REAL); + return new spell_ulduar_stone_grip_absorb_AuraScript(); } - }; - - AuraScript* GetAuraScript() const - { - return new spell_ulduar_stone_grip_absorb_AuraScript(); - } }; class spell_ulduar_stone_grip : public SpellScriptLoader { -public: - spell_ulduar_stone_grip() : SpellScriptLoader("spell_ulduar_stone_grip") { } - - class spell_ulduar_stone_grip_AuraScript : public AuraScript - { - PrepareAuraScript(spell_ulduar_stone_grip_AuraScript); + public: + spell_ulduar_stone_grip() : SpellScriptLoader("spell_ulduar_stone_grip") { } - void OnRemoveStun(AuraEffect const* aurEff, AuraEffectHandleModes mode) + class spell_ulduar_stone_grip_AuraScript : public AuraScript { - GetOwner()->ToUnit()->RemoveAurasDueToSpell(SpellMgr::CalculateSpellEffectAmount(GetSpellProto(), EFFECT_2)); - // Spellsystem doesn't recognize EFFECT_0 as actionable effect on dispel for some reason, manually do it here - GetOwner()->ToUnit()->ExitVehicle(); - GetOwner()->ToUnit()->NearTeleportTo(1756.25f + irand(-3, 3), -8.3f + irand(-3, 3), 448.8f, 3.62f); - } + PrepareAuraScript(spell_ulduar_stone_grip_AuraScript); + + void OnRemoveStun(AuraEffect const* aurEff, AuraEffectHandleModes mode) + { + if (!(mode & AURA_EFFECT_HANDLE_REAL)) + return; + + if (Player* pOwner = GetOwner()->ToPlayer()) + pOwner->RemoveAurasDueToSpell(aurEff->GetAmount()); + } + + void OnRemoveVehicle(AuraEffect const* aurEff, AuraEffectHandleModes mode) + { + if (!(mode & AURA_EFFECT_HANDLE_REAL)) + return; - void Register() + Creature* cOwner = GetOwner()->ToCreature(); + if (!cOwner) + return; + + Player* pCaster = GetCaster() ? GetCaster()->ToPlayer() : NULL; + if (!pCaster || !pCaster->IsOnVehicle(cOwner)) + return; + + pCaster->RemoveAurasDueToSpell(GetId()); + pCaster->ExitVehicle(); + pCaster->GetMotionMaster()->MoveJump(1756.25f + irand(-3, 3), -8.3f + irand(-3, 3), 448.8f, 5.0f, 5.0f); + PreventDefaultAction(); + + //GetOwner()->ToUnit()->NearTeleportTo(1756.25f + irand(-3, 3), -8.3f + irand(-3, 3), 448.8f, 3.62f); + } + + void Register() + { + OnEffectRemove += AuraEffectRemoveFn(spell_ulduar_stone_grip_AuraScript::OnRemoveVehicle, EFFECT_0, SPELL_AURA_CONTROL_VEHICLE, AURA_EFFECT_HANDLE_REAL); + OnEffectRemove += AuraEffectRemoveFn(spell_ulduar_stone_grip_AuraScript::OnRemoveStun, EFFECT_2, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + } + }; + + AuraScript* GetAuraScript() const { - OnEffectRemove += AuraEffectRemoveFn(spell_ulduar_stone_grip_AuraScript::OnRemoveStun, EFFECT_2, SPELL_AURA_MOD_STUN, AURA_EFFECT_HANDLE_REAL); + return new spell_ulduar_stone_grip_AuraScript(); } - }; - - AuraScript* GetAuraScript() const - { - return new spell_ulduar_stone_grip_AuraScript(); - } }; void AddSC_boss_kologarn() @@ -471,6 +582,7 @@ void AddSC_boss_kologarn() new boss_kologarn(); new spell_ulduar_rubble_summon(); new spell_ulduar_cancel_stone_grip(); + new spell_ulduar_stone_grip_cast_target(); new spell_ulduar_stone_grip_absorb(); new spell_ulduar_stone_grip(); } diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp index 3dd37899429..9f94dfb1a86 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp @@ -79,6 +79,8 @@ public: uint64 uiHodirChestGUID; uint64 uiFreyaChestGUID; + std::set<uint64> mRubbleSpawns; + void Initialize() { SetBossNumber(MAX_ENCOUNTER); @@ -154,9 +156,14 @@ public: uiAssemblyGUIDs[2] = creature->GetGUID(); break; + // Kologarn case NPC_KOLOGARN: uiKologarnGUID = creature->GetGUID(); break; + case NPC_RUBBLE: + mRubbleSpawns.insert(creature->GetGUID()); + break; + case NPC_AURIAYA: uiAuriayaGUID = creature->GetGUID(); break; @@ -275,8 +282,28 @@ public: break; case TYPE_KOLOGARN: if (state == DONE) + { if (GameObject* go = instance->GetGameObject(uiKologarnChestGUID)) go->SetRespawnTime(go->GetRespawnDelay()); + } + if (state != IN_PROGRESS) + { + std::set<uint64>::const_iterator itr; + for (itr = mRubbleSpawns.begin(); itr != mRubbleSpawns.end(); ) + { + if (Creature* rubble = instance->GetCreature((*itr))) + { + if (rubble->isSummon()) + { + rubble->DestroyForNearbyPlayers(); + rubble->ToTempSummon()->UnSummon(); + } + else + rubble->DisappearAndDie(); + } + mRubbleSpawns.erase(itr++); + } + } break; case TYPE_HODIR: if (state == DONE) diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h index 9d27aefb52d..dd400b060d1 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h @@ -65,6 +65,7 @@ enum eNPCs NPC_FOCUSED_EYEBEAM_RIGHT = 33802, NPC_LEFT_ARM = 32933, NPC_RIGHT_ARM = 32934, + NPC_RUBBLE = 33768, NPC_AURIAYA = 33515, NPC_MIMIRON = 33350, NPC_HODIR = 32845, |
