Scripts/Kologarn:
- Correct target limitation for Focused Eyebeam - Correct target selection and limitation for Stone Grip ** Fixes random teleports to the "safe spot" caused by aura unapply when that player wasn't intended as target. ** Stone Grip will only target the main tank if there's no one else in range. - Despawn Rubbles on encounter reset/complete - Use elegant MotionMaster::MoveJump instead of NearTeleportTo when releasing Stone Grip target DB/NPC Templates: - Add civilian flag for Armsweep Stalker and Rubble Stalker Other: - Fix 2011_02_23_2_world_conditions.sql to comply to standards - Cleanup affected code
This commit is contained in:
@@ -85,385 +85,496 @@ enum
|
||||
|
||||
class boss_kologarn : public CreatureScript
|
||||
{
|
||||
public:
|
||||
boss_kologarn() : CreatureScript("boss_kologarn") { }
|
||||
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)
|
||||
CreatureAI* GetAI(Creature* pCreature) const
|
||||
{
|
||||
ASSERT(vehicle);
|
||||
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
|
||||
SetCombatMovement(false);
|
||||
Reset();
|
||||
return new boss_kologarnAI (pCreature);
|
||||
}
|
||||
|
||||
Vehicle *vehicle;
|
||||
bool left, right;
|
||||
uint64 eyebeamTarget;
|
||||
|
||||
void EnterCombat(Unit * who)
|
||||
struct boss_kologarnAI : public BossAI
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, me);
|
||||
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();
|
||||
}
|
||||
|
||||
Vehicle *vehicle;
|
||||
bool left, right;
|
||||
uint64 eyebeamTarget;
|
||||
|
||||
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);
|
||||
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);
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
if (Unit* arm = vehicle->GetPassenger(i))
|
||||
arm->ToCreature()->SetInCombatWithZone();
|
||||
|
||||
_EnterCombat();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
|
||||
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*/)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*who*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit *who, int8 /*seatId*/, bool apply)
|
||||
{
|
||||
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());
|
||||
_EnterCombat();
|
||||
}
|
||||
|
||||
else if (who->GetEntry() == NPC_RIGHT_ARM)
|
||||
void Reset()
|
||||
{
|
||||
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());
|
||||
_Reset();
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (!apply)
|
||||
void JustDied(Unit * /*victim*/)
|
||||
{
|
||||
who->CastSpell(me, SPELL_ARM_DEAD_DAMAGE, true);
|
||||
who->GetMotionMaster()->MoveTargetedHome();
|
||||
DoScriptText(SAY_DEATH, me);
|
||||
_JustDied();
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* /*who*/)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2), me);
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit *who, int8 /*seatId*/, bool apply)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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());
|
||||
}
|
||||
|
||||
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)
|
||||
if (Creature* rubbleStalker = me->FindNearestCreature(NPC_RUBBLE_STALKER, 20.0f))
|
||||
{
|
||||
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);
|
||||
}
|
||||
else
|
||||
events.CancelEvent(EVENT_STONE_SHOUT);
|
||||
}
|
||||
|
||||
void JustSummoned(Creature *summon)
|
||||
{
|
||||
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);
|
||||
|
||||
// Victim gets 67351
|
||||
if (eyebeamTarget)
|
||||
{
|
||||
if (Unit* target = Unit::GetUnit(*summon, eyebeamTarget))
|
||||
{
|
||||
summon->Attack(target, false);
|
||||
summon->GetMotionMaster()->MoveChase(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
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:
|
||||
{
|
||||
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)
|
||||
{
|
||||
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 (rubbleStalker)
|
||||
{
|
||||
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
|
||||
rubbleStalker->CastSpell(rubbleStalker, SPELL_FALLING_RUBBLE, true);
|
||||
rubbleStalker->CastSpell(rubbleStalker, SPELL_SUMMON_RUBBLE, true);
|
||||
}
|
||||
DoScriptText(SAY_GRAB_PLAYER, me);
|
||||
}
|
||||
events.RepeatEvent(25000);
|
||||
}
|
||||
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;
|
||||
if (!right && !left)
|
||||
events.ScheduleEvent(EVENT_STONE_SHOUT, 5000);
|
||||
|
||||
if (instance)
|
||||
instance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, ACHIEV_DISARMED_START_EVENT);
|
||||
}
|
||||
else
|
||||
{
|
||||
events.CancelEvent(EVENT_STONE_SHOUT);
|
||||
who->ToCreature()->SetInCombatWithZone();
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
void JustSummoned(Creature *summon)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void RespawnArm(Creature* arm)
|
||||
{
|
||||
if (!arm->isAlive())
|
||||
arm->Respawn();
|
||||
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);
|
||||
|
||||
arm->EnterVehicle(vehicle);
|
||||
arm->CastSpell(arm, SPELL_ARM_ENTER_VISUAL, true);
|
||||
}
|
||||
};
|
||||
// Victim gets 67351
|
||||
if (eyebeamTarget)
|
||||
{
|
||||
if (Unit* target = Unit::GetUnit(*summon, eyebeamTarget))
|
||||
{
|
||||
summon->Attack(target, false);
|
||||
summon->GetMotionMaster()->MoveChase(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
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:
|
||||
{
|
||||
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)
|
||||
{
|
||||
DoCast(SPELL_STONE_GRIP);
|
||||
DoScriptText(SAY_GRAB_PLAYER, me);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void RespawnArm(Creature* arm)
|
||||
{
|
||||
if (!arm->isAlive())
|
||||
arm->Respawn();
|
||||
|
||||
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") { }
|
||||
public:
|
||||
spell_ulduar_rubble_summon() : SpellScriptLoader("spell_ulduar_rubble_summon") { }
|
||||
|
||||
class spell_ulduar_rubble_summonSpellScript : public SpellScript
|
||||
{
|
||||
PrepareSpellScript(spell_ulduar_rubble_summonSpellScript);
|
||||
|
||||
void HandleScript(SpellEffIndex /*effIndex*/)
|
||||
class spell_ulduar_rubble_summonSpellScript : public SpellScript
|
||||
{
|
||||
Unit* caster = GetCaster();
|
||||
if (!caster)
|
||||
return;
|
||||
PrepareSpellScript(spell_ulduar_rubble_summonSpellScript);
|
||||
|
||||
uint32 spellId = GetEffectValue();
|
||||
for (uint8 i = 0; i < 5; ++i)
|
||||
caster->CastSpell(caster, spellId, true);
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_ulduar_rubble_summonSpellScript();
|
||||
}
|
||||
};
|
||||
|
||||
// predicate function to select non main tank target
|
||||
class StoneGripTargetSelector : public std::unary_function<Unit *, bool>
|
||||
{
|
||||
public:
|
||||
StoneGripTargetSelector(Creature* me, const Unit* victim) : _me(me), _victim(victim) {}
|
||||
|
||||
bool operator() (Unit* pTarget)
|
||||
{
|
||||
if (pTarget == _victim && _me->getThreatManager().getThreatList().size() > 1)
|
||||
return true;
|
||||
|
||||
if (pTarget->GetTypeId() != TYPEID_PLAYER)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void Register()
|
||||
{
|
||||
OnEffect += SpellEffectFn(spell_ulduar_rubble_summonSpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
Creature* _me;
|
||||
Unit const* _victim;
|
||||
};
|
||||
|
||||
SpellScript* GetSpellScript() const
|
||||
{
|
||||
return new spell_ulduar_rubble_summonSpellScript();
|
||||
}
|
||||
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
|
||||
{
|
||||
PrepareSpellScript(spell_ulduar_stone_grip_cast_target_SpellScript);
|
||||
|
||||
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;
|
||||
|
||||
void Register()
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
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") { }
|
||||
public:
|
||||
spell_ulduar_stone_grip() : SpellScriptLoader("spell_ulduar_stone_grip") { }
|
||||
|
||||
class spell_ulduar_stone_grip_AuraScript : public AuraScript
|
||||
{
|
||||
PrepareAuraScript(spell_ulduar_stone_grip_AuraScript);
|
||||
|
||||
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 Register()
|
||||
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;
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user