*Fix a bug that shade of Akama causes crash.

--HG--
branch : trunk
This commit is contained in:
megamage
2008-12-14 11:55:32 -06:00
parent 29f92cbd90
commit 1d2179a529
@@ -1,4 +1,4 @@
/* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/> /* Copyright (C) 2006 - 2008 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
@@ -188,48 +188,53 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
bool IsBanished; bool IsBanished;
bool HasKilledAkama; bool HasKilledAkama;
bool reseting;
void Reset() void Reset()
{ {
reseting = true;
m_creature->setActive(true); // TODO: setActive(true, time); m_creature->setActive(true); // TODO: setActive(true, time);
FindChannelers(); FindChannelers();
if(!Channelers.empty()) if(!Channelers.empty())
{
for(std::list<uint64>::iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr)
{ {
Creature* Channeler = NULL; for(std::list<uint64>::iterator itr = Channelers.begin(); itr != Channelers.end(); ++itr)
Channeler = ((Creature*)Unit::GetUnit(*m_creature, *itr));
if(Channeler)
{ {
if(Channeler->isDead()) Creature* Channeler = NULL;
Channeler = ((Creature*)Unit::GetUnit(*m_creature, *itr));
if(Channeler)
{ {
Channeler->RemoveCorpse(); if(Channeler->isDead())
Channeler->Respawn(); {
} Channeler->RemoveCorpse();
if(m_creature->isAlive()) Channeler->Respawn();
{ }
Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL, true); if(m_creature->isAlive())
Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL_2, true); {
Channeler->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL, true);
} Channeler->CastSpell(m_creature, SPELL_SHADE_SOUL_CHANNEL_2, true);
}else error_log("SD2 ERROR: No Channelers are stored in the list. This encounter will not work properly"); Channeler->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
} }
}else error_log("SD2 ERROR: No Channelers are stored in the list. This encounter will not work properly");
}
} }
if(!Sorcerers.empty()) if(!Sorcerers.empty())
{ {
for(std::list<uint64>::iterator itr = Sorcerers.begin(); itr != Sorcerers.end(); ++itr) for(std::list<uint64>::iterator itr = Sorcerers.begin(); itr != Sorcerers.end(); ++itr)
{
if(Creature* Sorcerer = ((Creature*)Unit::GetUnit(*m_creature, *itr))) if(Creature* Sorcerer = ((Creature*)Unit::GetUnit(*m_creature, *itr)))
if(Sorcerer->isAlive()) if(Sorcerer->isAlive())
{ {
Sorcerer->SetVisibility(VISIBILITY_OFF); Sorcerer->SetVisibility(VISIBILITY_OFF);
Sorcerer->DealDamage(Sorcerer, Sorcerer->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); Sorcerer->Kill(Sorcerer);
} }
}
Sorcerers.clear();
}
Sorcerers.clear();
}
if(Unit* Akama = Unit::GetUnit(*m_creature, AkamaGUID)) if(Unit* Akama = Unit::GetUnit(*m_creature, AkamaGUID))
Akama->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); Akama->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
@@ -253,6 +258,8 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
if(pInstance && m_creature->isAlive()) if(pInstance && m_creature->isAlive())
pInstance->SetData(DATA_SHADEOFAKAMAEVENT, NOT_STARTED); pInstance->SetData(DATA_SHADEOFAKAMAEVENT, NOT_STARTED);
reseting = false;
} }
void Aggro(Unit* who) { } void Aggro(Unit* who) { }
@@ -274,6 +281,9 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
void IncrementDeathCount(uint64 guid = 0) // If guid is set, will remove it from list of sorcerer void IncrementDeathCount(uint64 guid = 0) // If guid is set, will remove it from list of sorcerer
{ {
if(reseting)
return;
debug_log("SD2: Increasing Death Count for Shade of Akama encounter"); debug_log("SD2: Increasing Death Count for Shade of Akama encounter");
++DeathCount; ++DeathCount;
m_creature->RemoveSingleAuraFromStack(SPELL_SHADE_SOUL_CHANNEL_2, 0); m_creature->RemoveSingleAuraFromStack(SPELL_SHADE_SOUL_CHANNEL_2, 0);
@@ -290,7 +300,7 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
uint32 random = rand()%2; uint32 random = rand()%2;
float X = SpawnLocations[random].x; float X = SpawnLocations[random].x;
float Y = SpawnLocations[random].y; float Y = SpawnLocations[random].y;
// max of 6 sorcerers can be summoned // max of 6 sorcerers can be summoned
if((rand()%3 == 0) && (DeathCount > 0) && (SorcererCount < 7)) if((rand()%3 == 0) && (DeathCount > 0) && (SorcererCount < 7))
{ {
Creature* Sorcerer = m_creature->SummonCreature(CREATURE_SORCERER, X, Y, Z_SPAWN, 0, TEMPSUMMON_DEAD_DESPAWN, 0); Creature* Sorcerer = m_creature->SummonCreature(CREATURE_SORCERER, X, Y, Z_SPAWN, 0, TEMPSUMMON_DEAD_DESPAWN, 0);
@@ -388,9 +398,9 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
{ {
float x, y, z; float x, y, z;
Akama->GetPosition(x,y,z); Akama->GetPosition(x,y,z);
// They move towards AKama // They move towards AKama
Defender->GetMotionMaster()->MovePoint(0, x, y, z); Defender->GetMotionMaster()->MovePoint(0, x, y, z);
Defender->AI()->AttackStart(Akama); Defender->AI()->AttackStart(Akama);
}else move = false; }else move = false;
}else move = false; }else move = false;
if(!move) if(!move)
@@ -416,10 +426,10 @@ struct TRINITY_DLL_DECL boss_shade_of_akamaAI : public ScriptedAI
m_creature->GetMotionMaster()->Clear(false); m_creature->GetMotionMaster()->Clear(false);
m_creature->GetMotionMaster()->MoveChase(Akama); m_creature->GetMotionMaster()->MoveChase(Akama);
Akama->GetMotionMaster()->Clear(); Akama->GetMotionMaster()->Clear();
// Shade should move to Akama, not the other way around // Shade should move to Akama, not the other way around
Akama->GetMotionMaster()->MoveIdle(); Akama->GetMotionMaster()->MoveIdle();
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
// Crazy amount of threat // Crazy amount of threat
m_creature->AddThreat(Akama, 10000000.0f); m_creature->AddThreat(Akama, 10000000.0f);
Akama->AddThreat(m_creature, 10000000.0f); Akama->AddThreat(m_creature, 10000000.0f);
m_creature->Attack(Akama, true); m_creature->Attack(Akama, true);
@@ -551,7 +561,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
if(Shade) if(Shade)
{ {
pInstance->SetData(DATA_SHADEOFAKAMAEVENT, IN_PROGRESS); pInstance->SetData(DATA_SHADEOFAKAMAEVENT, IN_PROGRESS);
// Prevent players from trying to restart event // Prevent players from trying to restart event
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
((boss_shade_of_akamaAI*)Shade->AI())->SetAkamaGUID(m_creature->GetGUID()); ((boss_shade_of_akamaAI*)Shade->AI())->SetAkamaGUID(m_creature->GetGUID());
((boss_shade_of_akamaAI*)Shade->AI())->SetSelectableChannelers(); ((boss_shade_of_akamaAI*)Shade->AI())->SetSelectableChannelers();
@@ -572,17 +582,17 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
switch(id) switch(id)
{ {
case 0: ++WayPointId; break; case 0: ++WayPointId; break;
case 1: case 1:
if(Unit* Shade = Unit::GetUnit(*m_creature, ShadeGUID)) if(Unit* Shade = Unit::GetUnit(*m_creature, ShadeGUID))
{ {
m_creature->SetUInt64Value(UNIT_FIELD_TARGET, ShadeGUID); m_creature->SetUInt64Value(UNIT_FIELD_TARGET, ShadeGUID);
DoCast(Shade, SPELL_AKAMA_SOUL_RETRIEVE); DoCast(Shade, SPELL_AKAMA_SOUL_RETRIEVE);
EndingTalkCount = 0; EndingTalkCount = 0;
SoulRetrieveTimer = 16000; SoulRetrieveTimer = 16000;
} }
break; break;
} }
} }
@@ -598,7 +608,7 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 15 && !HasYelledOnce) if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 15 && !HasYelledOnce)
{ {
DoScriptText(SAY_LOW_HEALTH, m_creature); DoScriptText(SAY_LOW_HEALTH, m_creature);
HasYelledOnce = true; HasYelledOnce = true;
} }
@@ -650,44 +660,44 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
} }
if(SummonBrokenTimer && BrokenSummonIndex < 4) if(SummonBrokenTimer && BrokenSummonIndex < 4)
{
if(SummonBrokenTimer <= diff)
{ {
for(uint8 i = 0; i < 4; ++i) if(SummonBrokenTimer <= diff)
{ {
float x = BrokenCoords[BrokenSummonIndex].x + (i*5); for(uint8 i = 0; i < 4; ++i)
float y = BrokenCoords[BrokenSummonIndex].y + (1*5);
float z = BrokenCoords[BrokenSummonIndex].z;
float o = BrokenCoords[BrokenSummonIndex].o;
Creature* Broken = m_creature->SummonCreature(CREATURE_BROKEN, x, y, z, o, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000);
if(Broken)
{ {
float wx = BrokenWP[BrokenSummonIndex].x + (i*5); float x = BrokenCoords[BrokenSummonIndex].x + (i*5);
float wy = BrokenWP[BrokenSummonIndex].y + (i*5); float y = BrokenCoords[BrokenSummonIndex].y + (1*5);
float wz = BrokenWP[BrokenSummonIndex].z; float z = BrokenCoords[BrokenSummonIndex].z;
Broken->GetMotionMaster()->MovePoint(0, wx, wy, wz); float o = BrokenCoords[BrokenSummonIndex].o;
Broken->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); Creature* Broken = m_creature->SummonCreature(CREATURE_BROKEN, x, y, z, o, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 360000);
BrokenList.push_back(Broken->GetGUID()); if(Broken)
{
float wx = BrokenWP[BrokenSummonIndex].x + (i*5);
float wy = BrokenWP[BrokenSummonIndex].y + (i*5);
float wz = BrokenWP[BrokenSummonIndex].z;
Broken->GetMotionMaster()->MovePoint(0, wx, wy, wz);
Broken->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
BrokenList.push_back(Broken->GetGUID());
}
} }
} ++BrokenSummonIndex;
++BrokenSummonIndex; SummonBrokenTimer = 1000;
SummonBrokenTimer = 1000; }else SummonBrokenTimer -= diff;
}else SummonBrokenTimer -= diff; }
}
if(SoulRetrieveTimer) if(SoulRetrieveTimer)
if(SoulRetrieveTimer <= diff) if(SoulRetrieveTimer <= diff)
{
switch(EndingTalkCount)
{ {
switch(EndingTalkCount)
{
case 0: case 0:
m_creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR); m_creature->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
++EndingTalkCount; ++EndingTalkCount;
SoulRetrieveTimer = 2000; SoulRetrieveTimer = 2000;
SummonBrokenTimer = 1; SummonBrokenTimer = 1;
break; break;
case 1: case 1:
DoScriptText(SAY_FREE, m_creature); DoScriptText(SAY_FREE, m_creature);
++EndingTalkCount; ++EndingTalkCount;
SoulRetrieveTimer = 25000; SoulRetrieveTimer = 25000;
break; break;
@@ -697,40 +707,40 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
bool Yelled = false; bool Yelled = false;
for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr)
if(Unit* pUnit = Unit::GetUnit(*m_creature, *itr)) if(Unit* pUnit = Unit::GetUnit(*m_creature, *itr))
{
if(!Yelled)
{ {
DoScriptText(SAY_BROKEN_FREE_01, pUnit); if(!Yelled)
Yelled = true; {
DoScriptText(SAY_BROKEN_FREE_01, pUnit);
Yelled = true;
}
pUnit->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
} }
pUnit->HandleEmoteCommand(EMOTE_ONESHOT_KNEEL);
}
} }
++EndingTalkCount; ++EndingTalkCount;
SoulRetrieveTimer = 1500; SoulRetrieveTimer = 1500;
break; break;
case 3: case 3:
if(!BrokenList.empty()) if(!BrokenList.empty())
{ {
for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr)
if(Unit* pUnit = Unit::GetUnit(*m_creature, *itr)) if(Unit* pUnit = Unit::GetUnit(*m_creature, *itr))
// This is the incorrect spell, but can't seem to find the right one. // This is the incorrect spell, but can't seem to find the right one.
pUnit->CastSpell(pUnit, 39656, true); pUnit->CastSpell(pUnit, 39656, true);
} }
++EndingTalkCount; ++EndingTalkCount;
SoulRetrieveTimer = 5000; SoulRetrieveTimer = 5000;
break; break;
case 4: case 4:
if(!BrokenList.empty()) if(!BrokenList.empty())
{ {
for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr) for(std::list<uint64>::iterator itr = BrokenList.begin(); itr != BrokenList.end(); ++itr)
if(Unit* pUnit = Unit::GetUnit((*m_creature), *itr)) if(Unit* pUnit = Unit::GetUnit((*m_creature), *itr))
pUnit->MonsterYell(SAY_BROKEN_FREE_02, LANG_UNIVERSAL, 0); pUnit->MonsterYell(SAY_BROKEN_FREE_02, LANG_UNIVERSAL, 0);
} }
SoulRetrieveTimer = 0; SoulRetrieveTimer = 0;
break; break;
} }
}else SoulRetrieveTimer -= diff; }else SoulRetrieveTimer -= diff;
if(!m_creature->getVictim() || !m_creature->SelectHostilTarget()) if(!m_creature->getVictim() || !m_creature->SelectHostilTarget())
return; return;
@@ -738,8 +748,8 @@ struct TRINITY_DLL_DECL npc_akamaAI : public ScriptedAI
if(DestructivePoisonTimer < diff) if(DestructivePoisonTimer < diff)
{ {
Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID); Unit* Shade = Unit::GetUnit((*m_creature), ShadeGUID);
if (Shade && Shade->isAlive()) if (Shade && Shade->isAlive())
DoCast(Shade, SPELL_DESTRUCTIVE_POISON); DoCast(Shade, SPELL_DESTRUCTIVE_POISON);
DestructivePoisonTimer = 15000; DestructivePoisonTimer = 15000;
}else DestructivePoisonTimer -= diff; }else DestructivePoisonTimer -= diff;