Scripts/Icecrown Citadel: Fixed possible exploits with Deathbringer Saurfang

This commit is contained in:
Shauren
2011-02-18 19:50:34 +01:00
parent 0f34df6e1a
commit aefbf30e4a
@@ -193,6 +193,7 @@ enum Actions
ACTION_CHARGE = -3781302, ACTION_CHARGE = -3781302,
ACTION_START_OUTRO = -3781303, ACTION_START_OUTRO = -3781303,
ACTION_DESPAWN = -3781304, ACTION_DESPAWN = -3781304,
ACTION_INTERRUPT_INTRO = -3781305,
ACTION_MARK_OF_THE_FALLEN_CHAMPION = -72293, ACTION_MARK_OF_THE_FALLEN_CHAMPION = -72293,
}; };
@@ -284,8 +285,15 @@ class boss_deathbringer_saurfang : public CreatureScript
me->setActive(true); me->setActive(true);
DoZoneInCombat(); DoZoneInCombat();
events.Reset();
events.SetPhase(PHASE_COMBAT); events.SetPhase(PHASE_COMBAT);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE);
if (!introDone)
{
DoCast(me, SPELL_GRIP_OF_AGONY);
if (Creature* creature = ObjectAccessor::GetCreature(*me, instance->GetData64(DATA_SAURFANG_EVENT_NPC)))
creature->AI()->DoAction(ACTION_INTERRUPT_INTRO);
}
introDone = true; introDone = true;
Talk(SAY_AGGRO); Talk(SAY_AGGRO);
@@ -510,6 +518,8 @@ class boss_deathbringer_saurfang : public CreatureScript
events.ScheduleEvent(EVENT_INTRO_HORDE_2, 5000, 0, PHASE_INTRO_H); events.ScheduleEvent(EVENT_INTRO_HORDE_2, 5000, 0, PHASE_INTRO_H);
break; break;
case ACTION_CONTINUE_INTRO: case ACTION_CONTINUE_INTRO:
if (introDone)
return;
events.ScheduleEvent(EVENT_INTRO_ALLIANCE_6, 6500+500, 0, PHASE_INTRO_A); events.ScheduleEvent(EVENT_INTRO_ALLIANCE_6, 6500+500, 0, PHASE_INTRO_A);
events.ScheduleEvent(EVENT_INTRO_FINISH, 8000, 0, PHASE_INTRO_A); events.ScheduleEvent(EVENT_INTRO_FINISH, 8000, 0, PHASE_INTRO_A);
@@ -564,44 +574,56 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
void DoAction(const int32 action) void DoAction(const int32 action)
{ {
if (action == ACTION_START_EVENT) switch (action)
{ {
// Prevent crashes case ACTION_START_EVENT:
if (events.GetPhaseMask() & PHASE_INTRO_MASK)
return;
GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_KOR_KRON_REAVER, 20.0f);
guardList.sort(Trinity::ObjectDistanceOrderPred(me));
uint32 x = 1;
for (std::list<Creature*>::iterator itr = guardList.begin(); itr != guardList.end(); ++x, ++itr)
(*itr)->AI()->SetData(0, x);
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
Talk(SAY_INTRO_HORDE_1);
events.SetPhase(PHASE_INTRO_H);
events.ScheduleEvent(EVENT_INTRO_HORDE_3, 18500, 0, PHASE_INTRO_H);
if (instance)
{ {
deathbringerSaurfangGUID = instance->GetData64(DATA_DEATHBRINGER_SAURFANG); // Prevent crashes
instance->HandleGameObject(instance->GetData64(GO_SAURFANG_S_DOOR), true); if (events.GetPhaseMask() & PHASE_INTRO_MASK)
return;
GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_KOR_KRON_REAVER, 20.0f);
guardList.sort(Trinity::ObjectDistanceOrderPred(me));
uint32 x = 1;
for (std::list<Creature*>::iterator itr = guardList.begin(); itr != guardList.end(); ++x, ++itr)
(*itr)->AI()->SetData(0, x);
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
Talk(SAY_INTRO_HORDE_1);
events.SetPhase(PHASE_INTRO_H);
events.ScheduleEvent(EVENT_INTRO_HORDE_3, 18500, 0, PHASE_INTRO_H);
if (instance)
{
deathbringerSaurfangGUID = instance->GetData64(DATA_DEATHBRINGER_SAURFANG);
instance->HandleGameObject(instance->GetData64(GO_SAURFANG_S_DOOR), true);
}
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, deathbringerSaurfangGUID))
deathbringer->AI()->DoAction(PHASE_INTRO_H);
break;
} }
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, deathbringerSaurfangGUID)) case ACTION_START_OUTRO:
deathbringer->AI()->DoAction(PHASE_INTRO_H); {
} me->RemoveAurasDueToSpell(SPELL_GRIP_OF_AGONY);
else if (action == ACTION_START_OUTRO) Talk(SAY_OUTRO_HORDE_1);
{ events.ScheduleEvent(EVENT_OUTRO_HORDE_2, 10000); // say
me->RemoveAurasDueToSpell(SPELL_GRIP_OF_AGONY); events.ScheduleEvent(EVENT_OUTRO_HORDE_3, 18000); // say
Talk(SAY_OUTRO_HORDE_1); events.ScheduleEvent(EVENT_OUTRO_HORDE_4, 24000); // cast
events.ScheduleEvent(EVENT_OUTRO_HORDE_2, 10000); // say events.ScheduleEvent(EVENT_OUTRO_HORDE_5, 30000); // move
events.ScheduleEvent(EVENT_OUTRO_HORDE_3, 18000); // say me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
events.ScheduleEvent(EVENT_OUTRO_HORDE_4, 24000); // cast me->SendMovementFlagUpdate();
events.ScheduleEvent(EVENT_OUTRO_HORDE_5, 30000); // move me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); me->SendMonsterMove(me->GetPositionX(), me->GetPositionY(), 539.2917f, SPLINEFLAG_FALLING, 0, 0.0f);
me->SendMovementFlagUpdate(); for (std::list<Creature*>::iterator itr = guardList.begin(); itr != guardList.end(); ++itr)
me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f); (*itr)->AI()->DoAction(ACTION_DESPAWN);
me->SendMonsterMove(me->GetPositionX(), me->GetPositionY(), 539.2917f, SPLINEFLAG_FALLING, 0, 0.0f); break;
for (std::list<Creature*>::iterator itr = guardList.begin(); itr != guardList.end(); ++itr) }
(*itr)->AI()->DoAction(ACTION_DESPAWN); case ACTION_INTERRUPT_INTRO:
events.Reset();
for (std::list<Creature*>::iterator itr = guardList.begin(); itr != guardList.end(); ++itr)
(*itr)->AI()->DoAction(ACTION_DESPAWN);
break;
default:
break;
} }
} }
@@ -619,34 +641,36 @@ class npc_high_overlord_saurfang_icc : public CreatureScript
if (type != POINT_MOTION_TYPE) if (type != POINT_MOTION_TYPE)
return; return;
if (id == POINT_FIRST_STEP) switch (id)
{ {
me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING); case POINT_FIRST_STEP:
Talk(SAY_INTRO_HORDE_3); me->RemoveUnitMovementFlag(MOVEMENTFLAG_WALKING);
events.ScheduleEvent(EVENT_INTRO_HORDE_5, 15500, 0, PHASE_INTRO_H); Talk(SAY_INTRO_HORDE_3);
events.ScheduleEvent(EVENT_INTRO_HORDE_6, 29500, 0, PHASE_INTRO_H); events.ScheduleEvent(EVENT_INTRO_HORDE_5, 15500, 0, PHASE_INTRO_H);
events.ScheduleEvent(EVENT_INTRO_HORDE_7, 43800, 0, PHASE_INTRO_H); events.ScheduleEvent(EVENT_INTRO_HORDE_6, 29500, 0, PHASE_INTRO_H);
events.ScheduleEvent(EVENT_INTRO_HORDE_8, 47000, 0, PHASE_INTRO_H); events.ScheduleEvent(EVENT_INTRO_HORDE_7, 43800, 0, PHASE_INTRO_H);
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, deathbringerSaurfangGUID)) events.ScheduleEvent(EVENT_INTRO_HORDE_8, 47000, 0, PHASE_INTRO_H);
deathbringer->AI()->DoAction(ACTION_CONTINUE_INTRO); if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, deathbringerSaurfangGUID))
} deathbringer->AI()->DoAction(ACTION_CONTINUE_INTRO);
else if (id == POINT_CORPSE) break;
{ case POINT_CORPSE:
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, deathbringerSaurfangGUID)) if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, deathbringerSaurfangGUID))
{ {
deathbringer->CastSpell(me, SPELL_RIDE_VEHICLE, true); // for the packet logs. deathbringer->CastSpell(me, SPELL_RIDE_VEHICLE, true); // for the packet logs.
deathbringer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); deathbringer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
deathbringer->setDeathState(ALIVE); deathbringer->setDeathState(ALIVE);
deathbringer->EnterVehicle(vehicle, 0); deathbringer->EnterVehicle(vehicle, 0);
} }
events.ScheduleEvent(EVENT_OUTRO_HORDE_5, 1000); // move events.ScheduleEvent(EVENT_OUTRO_HORDE_5, 1000); // move
events.ScheduleEvent(EVENT_OUTRO_HORDE_6, 4000); // say events.ScheduleEvent(EVENT_OUTRO_HORDE_6, 4000); // say
} break;
else if (id == POINT_FINAL) case POINT_FINAL:
{ if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, deathbringerSaurfangGUID))
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, deathbringerSaurfangGUID)) deathbringer->DespawnOrUnsummon();
deathbringer->DespawnOrUnsummon(); me->DespawnOrUnsummon();
me->DespawnOrUnsummon(); break;
default:
break;
} }
} }
@@ -761,40 +785,50 @@ class npc_muradin_bronzebeard_icc : public CreatureScript
void DoAction(const int32 action) void DoAction(const int32 action)
{ {
if (action == ACTION_START_EVENT) switch (action)
{ {
// Prevent crashes case ACTION_START_EVENT:
if (events.GetPhaseMask() & PHASE_INTRO_MASK)
return;
events.SetPhase(PHASE_INTRO_A);
GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_SKYBREAKER_MARINE, 20.0f);
guardList.sort(Trinity::ObjectDistanceOrderPred(me));
uint32 x = 1;
for (std::list<Creature*>::iterator itr = guardList.begin(); itr != guardList.end(); ++x, ++itr)
(*itr)->AI()->SetData(0, x);
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
Talk(SAY_INTRO_ALLIANCE_1);
events.ScheduleEvent(EVENT_INTRO_ALLIANCE_4, 2500+17500+9500, 0, PHASE_INTRO_A);
if (instance)
{ {
deathbringerSaurfangGUID = instance->GetData64(DATA_DEATHBRINGER_SAURFANG); // Prevent crashes
instance->HandleGameObject(instance->GetData64(GO_SAURFANG_S_DOOR), true); if (events.GetPhaseMask() & PHASE_INTRO_MASK)
return;
events.SetPhase(PHASE_INTRO_A);
GetCreatureListWithEntryInGrid(guardList, me, NPC_SE_SKYBREAKER_MARINE, 20.0f);
guardList.sort(Trinity::ObjectDistanceOrderPred(me));
uint32 x = 1;
for (std::list<Creature*>::iterator itr = guardList.begin(); itr != guardList.end(); ++x, ++itr)
(*itr)->AI()->SetData(0, x);
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
Talk(SAY_INTRO_ALLIANCE_1);
events.ScheduleEvent(EVENT_INTRO_ALLIANCE_4, 2500+17500+9500, 0, PHASE_INTRO_A);
if (instance)
{
deathbringerSaurfangGUID = instance->GetData64(DATA_DEATHBRINGER_SAURFANG);
instance->HandleGameObject(instance->GetData64(GO_SAURFANG_S_DOOR), true);
}
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, deathbringerSaurfangGUID))
deathbringer->AI()->DoAction(PHASE_INTRO_A);
break;
} }
if (Creature* deathbringer = ObjectAccessor::GetCreature(*me, deathbringerSaurfangGUID)) case ACTION_START_OUTRO:
deathbringer->AI()->DoAction(PHASE_INTRO_A); {
} me->RemoveAurasDueToSpell(SPELL_GRIP_OF_AGONY);
else if (action == ACTION_START_OUTRO) Talk(SAY_OUTRO_ALLIANCE_1);
{ me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->RemoveAurasDueToSpell(SPELL_GRIP_OF_AGONY); me->SendMovementFlagUpdate();
Talk(SAY_OUTRO_ALLIANCE_1); me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f);
me->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING); me->SendMonsterMove(me->GetPositionX(), me->GetPositionY(), 539.2917f, SPLINEFLAG_FALLING, 0, 0.0f);
me->SendMovementFlagUpdate(); for (std::list<Creature*>::iterator itr = guardList.begin(); itr != guardList.end(); ++itr)
me->Relocate(me->GetPositionX(), me->GetPositionY(), 539.2917f); (*itr)->AI()->DoAction(ACTION_DESPAWN);
me->SendMonsterMove(me->GetPositionX(), me->GetPositionY(), 539.2917f, SPLINEFLAG_FALLING, 0, 0.0f); break;
for (std::list<Creature*>::iterator itr = guardList.begin(); itr != guardList.end(); ++itr) }
(*itr)->AI()->DoAction(ACTION_DESPAWN); case ACTION_INTERRUPT_INTRO:
events.Reset();
for (std::list<Creature*>::iterator itr = guardList.begin(); itr != guardList.end(); ++itr)
(*itr)->AI()->DoAction(ACTION_DESPAWN);
break;
} }
} }
@@ -887,13 +921,13 @@ class npc_saurfang_event : public CreatureScript
{ {
npc_saurfang_eventAI(Creature* creature) : ScriptedAI(creature) npc_saurfang_eventAI(Creature* creature) : ScriptedAI(creature)
{ {
uiNPCindex = 0; npcIndex = 0;
} }
void SetData(uint32 type, uint32 data) void SetData(uint32 type, uint32 data)
{ {
ASSERT(!type && data && data < 6); ASSERT(!type && data && data < 6);
uiNPCindex = data; npcIndex = data;
} }
void SpellHit(Unit* /*caster*/, SpellEntry const* spell) void SpellHit(Unit* /*caster*/, SpellEntry const* spell)
@@ -901,21 +935,20 @@ class npc_saurfang_event : public CreatureScript
if (spell->Id == SPELL_GRIP_OF_AGONY) if (spell->Id == SPELL_GRIP_OF_AGONY)
{ {
me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING); me->AddUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[uiNPCindex]); me->GetMotionMaster()->MovePoint(POINT_CHOKE, chokePos[npcIndex]);
} }
} }
void DoAction(const int32 action) void DoAction(const int32 action)
{ {
if (action == ACTION_CHARGE && uiNPCindex) if (action == ACTION_CHARGE && npcIndex)
me->GetMotionMaster()->MoveCharge(chargePos[uiNPCindex].GetPositionX(), chargePos[uiNPCindex].GetPositionY(), chargePos[uiNPCindex].GetPositionZ(), 13.0f, POINT_CHARGE); me->GetMotionMaster()->MoveCharge(chargePos[npcIndex].GetPositionX(), chargePos[npcIndex].GetPositionY(), chargePos[npcIndex].GetPositionZ(), 13.0f, POINT_CHARGE);
else if (action == ACTION_DESPAWN) else if (action == ACTION_DESPAWN)
me->DespawnOrUnsummon(); me->DespawnOrUnsummon();
} }
private: private:
EventMap events; uint32 npcIndex;
uint32 uiNPCindex;
}; };
CreatureAI* GetAI(Creature* creature) const CreatureAI* GetAI(Creature* creature) const