Scripts/Icecrown Citadel: Fixed Sindragosa, Spinestalker and Rimefang flying in after related trash packs are dead - this solution is resistant to grid unload.

This commit is contained in:
Shauren
2012-06-05 14:53:18 +02:00
parent 7e71488a1e
commit 295b1a00c8
2 changed files with 108 additions and 101 deletions
@@ -651,7 +651,7 @@ class npc_spinestalker : public CreatureScript
// Increase add count // Increase add count
if (!me->isDead()) if (!me->isDead())
{ {
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade _instance->SetData64(DATA_SINDRAGOSA_FROSTWYRMS, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
Reset(); Reset();
} }
} }
@@ -674,13 +674,12 @@ class npc_spinestalker : public CreatureScript
void JustRespawned() void JustRespawned()
{ {
ScriptedAI::JustRespawned(); ScriptedAI::JustRespawned();
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade _instance->SetData64(DATA_SINDRAGOSA_FROSTWYRMS, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
} }
void JustDied(Unit* /*killer*/) void JustDied(Unit* /*killer*/)
{ {
_events.Reset(); _events.Reset();
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 0);
} }
void DoAction(int32 const action) void DoAction(int32 const action)
@@ -778,7 +777,7 @@ class npc_rimefang : public CreatureScript
// Increase add count // Increase add count
if (!me->isDead()) if (!me->isDead())
{ {
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade _instance->SetData64(DATA_SINDRAGOSA_FROSTWYRMS, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
Reset(); Reset();
} }
} }
@@ -801,13 +800,12 @@ class npc_rimefang : public CreatureScript
void JustRespawned() void JustRespawned()
{ {
ScriptedAI::JustRespawned(); ScriptedAI::JustRespawned();
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 1); // this cannot be in Reset because reset also happens on evade _instance->SetData64(DATA_SINDRAGOSA_FROSTWYRMS, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
} }
void JustDied(Unit* /*killer*/) void JustDied(Unit* /*killer*/)
{ {
_events.Reset(); _events.Reset();
_instance->SetData(DATA_SINDRAGOSA_FROSTWYRMS, 0);
} }
void DoAction(int32 const action) void DoAction(int32 const action)
@@ -934,7 +932,8 @@ class npc_sindragosa_trash : public CreatureScript
// Increase add count // Increase add count
if (!me->isDead()) if (!me->isDead())
{ {
_instance->SetData(_frostwyrmId, 1); // this cannot be in Reset because reset also happens on evade if (me->GetEntry() == NPC_FROSTWING_WHELP)
_instance->SetData64(_frostwyrmId, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
Reset(); Reset();
} }
} }
@@ -956,13 +955,8 @@ class npc_sindragosa_trash : public CreatureScript
ScriptedAI::JustRespawned(); ScriptedAI::JustRespawned();
// Increase add count // Increase add count
_instance->SetData(_frostwyrmId, 1); // this cannot be in Reset because reset also happens on evade if (me->GetEntry() == NPC_FROSTWING_WHELP)
} _instance->SetData64(_frostwyrmId, me->GetGUID()); // this cannot be in Reset because reset also happens on evade
void JustDied(Unit* /*killer*/)
{
// Decrease add count
_instance->SetData(_frostwyrmId, 0);
} }
void SetData(uint32 type, uint32 data) void SetData(uint32 type, uint32 data)
@@ -89,6 +89,13 @@ WeeklyQuest const WeeklyQuestData[WeeklyNPCs] =
{NPC_VALITHRIA_DREAMWALKER_QUEST, {QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_10, QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_25}}, // Respite for a Tormented Soul {NPC_VALITHRIA_DREAMWALKER_QUEST, {QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_10, QUEST_RESPITE_FOR_A_TORNMENTED_SOUL_25}}, // Respite for a Tormented Soul
}; };
enum FrostwyrmFlags
{
FLAG_SPINESTALKER_SUMMONED = 0x01,
FLAG_RIMEFANG_SUMMONED = 0x02,
FLAG_SINDRAGOSA_SUMMONED = 0x04,
};
class instance_icecrown_citadel : public InstanceMapScript class instance_icecrown_citadel : public InstanceMapScript
{ {
public: public:
@@ -138,9 +145,6 @@ class instance_icecrown_citadel : public InstanceMapScript
FrozenThroneEdgeGUID = 0; FrozenThroneEdgeGUID = 0;
FrozenThroneWindGUID = 0; FrozenThroneWindGUID = 0;
FrozenThroneWarningGUID = 0; FrozenThroneWarningGUID = 0;
FrostwyrmCount = 0;
SpinestalkerTrashCount = 0;
RimefangTrashCount = 0;
IsBonedEligible = true; IsBonedEligible = true;
IsOozeDanceEligible = true; IsOozeDanceEligible = true;
IsNauseaEligible = true; IsNauseaEligible = true;
@@ -148,6 +152,7 @@ class instance_icecrown_citadel : public InstanceMapScript
ColdflameJetsState = NOT_STARTED; ColdflameJetsState = NOT_STARTED;
BloodQuickeningState = NOT_STARTED; BloodQuickeningState = NOT_STARTED;
BloodQuickeningMinutes = 0; BloodQuickeningMinutes = 0;
FrostwyrmFlags = 0;
} }
void FillInitialWorldStates(WorldPacket& data) void FillInitialWorldStates(WorldPacket& data)
@@ -279,9 +284,13 @@ class instance_icecrown_citadel : public InstanceMapScript
break; break;
case NPC_SPINESTALKER: case NPC_SPINESTALKER:
SpinestalkerGUID = creature->GetGUID(); SpinestalkerGUID = creature->GetGUID();
if (!creature->isAlive())
FrostwyrmFlags |= FLAG_SPINESTALKER_SUMMONED;
break; break;
case NPC_RIMEFANG: case NPC_RIMEFANG:
RimefangGUID = creature->GetGUID(); RimefangGUID = creature->GetGUID();
if (!creature->isAlive())
FrostwyrmFlags |= FLAG_RIMEFANG_SUMMONED;
break; break;
case NPC_THE_LICH_KING: case NPC_THE_LICH_KING:
TheLichKingGUID = creature->GetGUID(); TheLichKingGUID = creature->GetGUID();
@@ -347,6 +356,56 @@ class instance_icecrown_citadel : public InstanceMapScript
if (Creature* crok = instance->GetCreature(CrokScourgebaneGUID)) if (Creature* crok = instance->GetCreature(CrokScourgebaneGUID))
crok->AI()->SetGUID(creature->GetGUID(), ACTION_VRYKUL_DEATH); crok->AI()->SetGUID(creature->GetGUID(), ACTION_VRYKUL_DEATH);
break; break;
case NPC_FROSTWING_WHELP:
if (creature->AI()->GetData(1/*DATA_FROSTWYRM_OWNER*/) == DATA_SPINESTALKER)
{
if (FrostwyrmFlags & FLAG_SPINESTALKER_SUMMONED)
return;
SpinestalkerTrash.erase(creature->GetGUID());
if (SpinestalkerTrash.empty())
{
FrostwyrmFlags |= FLAG_SPINESTALKER_SUMMONED;
if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID))
spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
}
}
else
{
if (FrostwyrmFlags & FLAG_RIMEFANG_SUMMONED)
return;
RimefangTrash.erase(creature->GetGUID());
if (RimefangTrash.empty())
{
FrostwyrmFlags |= FLAG_RIMEFANG_SUMMONED;
if (Creature* spinestalk = instance->GetCreature(RimefangGUID))
spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
}
}
break;
case NPC_RIMEFANG:
case NPC_SPINESTALKER:
{
if (FrostwyrmFlags & FLAG_SINDRAGOSA_SUMMONED)
return;
if (instance->IsHeroic() && !HeroicAttempts)
return;
if (GetBossState(DATA_SINDRAGOSA) == DONE)
return;
FrostwyrmGUIDs.erase(creature->GetGUID());
if (FrostwyrmGUIDs.empty())
{
FrostwyrmFlags |= FLAG_SINDRAGOSA_SUMMONED;
instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY());
if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
boss->AI()->DoAction(ACTION_START_FROSTWYRM);
}
break;
}
default: default:
break; break;
} }
@@ -538,11 +597,17 @@ class instance_icecrown_citadel : public InstanceMapScript
switch (type) switch (type)
{ {
case DATA_SINDRAGOSA_FROSTWYRMS: case DATA_SINDRAGOSA_FROSTWYRMS:
return FrostwyrmCount; if (FrostwyrmFlags & FLAG_SINDRAGOSA_SUMMONED)
return 255;
return FrostwyrmGUIDs.size();
case DATA_SPINESTALKER: case DATA_SPINESTALKER:
return SpinestalkerTrashCount; if (FrostwyrmFlags & FLAG_SPINESTALKER_SUMMONED)
return 255;
return SpinestalkerTrash.size();
case DATA_RIMEFANG: case DATA_RIMEFANG:
return RimefangTrashCount; if (FrostwyrmFlags & FLAG_RIMEFANG_SUMMONED)
return 255;
return RimefangTrash.size();
case DATA_COLDFLAME_JETS: case DATA_COLDFLAME_JETS:
return ColdflameJetsState; return ColdflameJetsState;
case DATA_TEAM_IN_INSTANCE: case DATA_TEAM_IN_INSTANCE:
@@ -741,6 +806,9 @@ class instance_icecrown_citadel : public InstanceMapScript
sindra->DespawnOrUnsummon(); sindra->DespawnOrUnsummon();
} }
} }
// Reached when loading from DB
if (state == DONE)
FrostwyrmFlags |= FLAG_SINDRAGOSA_SUMMONED;
break; break;
case DATA_THE_LICH_KING: case DATA_THE_LICH_KING:
{ {
@@ -798,89 +866,17 @@ class instance_icecrown_citadel : public InstanceMapScript
IsOrbWhispererEligible = data ? true : false; IsOrbWhispererEligible = data ? true : false;
break; break;
case DATA_SINDRAGOSA_FROSTWYRMS: case DATA_SINDRAGOSA_FROSTWYRMS:
{ if (data == 255)
if (FrostwyrmCount == 255) FrostwyrmFlags |= FLAG_SINDRAGOSA_SUMMONED;
return;
if (instance->IsHeroic() && !HeroicAttempts)
return;
if (GetBossState(DATA_SINDRAGOSA) == DONE)
return;
switch (data)
{
case 0:
if (FrostwyrmCount)
{
--FrostwyrmCount;
if (!FrostwyrmCount)
{
instance->LoadGrid(SindragosaSpawnPos.GetPositionX(), SindragosaSpawnPos.GetPositionY());
if (Creature* boss = instance->SummonCreature(NPC_SINDRAGOSA, SindragosaSpawnPos))
boss->AI()->DoAction(ACTION_START_FROSTWYRM);
}
}
break; break;
case 1:
++FrostwyrmCount;
break;
default:
FrostwyrmCount = data;
break;
}
break;
}
case DATA_SPINESTALKER: case DATA_SPINESTALKER:
{ if (data == 255)
if (SpinestalkerTrashCount == 255) FrostwyrmFlags |= FLAG_SPINESTALKER_SUMMONED;
return;
switch (data)
{
case 0:
if (SpinestalkerTrashCount)
{
--SpinestalkerTrashCount;
if (!SpinestalkerTrashCount)
if (Creature* spinestalk = instance->GetCreature(SpinestalkerGUID))
spinestalk->AI()->DoAction(ACTION_START_FROSTWYRM);
}
break; break;
case 1:
++SpinestalkerTrashCount;
break;
default:
SpinestalkerTrashCount = data;
break;
}
break;
}
case DATA_RIMEFANG: case DATA_RIMEFANG:
{ if (data == 255)
if (RimefangTrashCount == 255) FrostwyrmFlags |= FLAG_RIMEFANG_SUMMONED;
return;
switch (data)
{
case 0:
if (RimefangTrashCount)
{
--RimefangTrashCount;
if (!RimefangTrashCount)
if (Creature* rime = instance->GetCreature(RimefangGUID))
rime->AI()->DoAction(ACTION_START_FROSTWYRM);
}
break; break;
case 1:
++RimefangTrashCount;
break;
default:
RimefangTrashCount = data;
break;
}
break;
}
case DATA_COLDFLAME_JETS: case DATA_COLDFLAME_JETS:
ColdflameJetsState = data; ColdflameJetsState = data;
if (ColdflameJetsState == DONE) if (ColdflameJetsState == DONE)
@@ -922,6 +918,22 @@ class instance_icecrown_citadel : public InstanceMapScript
} }
} }
void SetData64(uint32 id, uint64 data)
{
switch (id)
{
case DATA_SINDRAGOSA_FROSTWYRMS:
FrostwyrmGUIDs.insert(data);
break;
case DATA_SPINESTALKER:
SpinestalkerTrash.insert(data);
break;
case DATA_RIMEFANG:
RimefangTrash.insert(data);
break;
}
}
bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/) bool CheckAchievementCriteriaMeet(uint32 criteria_id, Player const* /*source*/, Unit const* /*target*/, uint32 /*miscvalue1*/)
{ {
switch (criteria_id) switch (criteria_id)
@@ -1289,12 +1301,13 @@ class instance_icecrown_citadel : public InstanceMapScript
uint64 PillarsUnchainedGUID; uint64 PillarsUnchainedGUID;
uint32 TeamInInstance; uint32 TeamInInstance;
uint32 ColdflameJetsState; uint32 ColdflameJetsState;
uint32 FrostwyrmCount; std::set<uint64> FrostwyrmGUIDs;
uint32 SpinestalkerTrashCount; std::set<uint64> SpinestalkerTrash;
uint32 RimefangTrashCount; std::set<uint64> RimefangTrash;
uint32 BloodQuickeningState; uint32 BloodQuickeningState;
uint32 HeroicAttempts; uint32 HeroicAttempts;
uint16 BloodQuickeningMinutes; uint16 BloodQuickeningMinutes;
uint16 FrostwyrmFlags;
bool IsBonedEligible; bool IsBonedEligible;
bool IsOozeDanceEligible; bool IsOozeDanceEligible;
bool IsNauseaEligible; bool IsNauseaEligible;