* Rename InstanceData to InstanceScript

* Rename *mgr to their new names in scripts project
* Mass convert all the scripts (NEEDS THOROUGH TESTING, because it was done automatically) Please, report bugs on issue tracker.

--HG--
branch : trunk
rename : src/server/game/Instances/InstanceData.cpp => src/server/game/Instances/InstanceScript.cpp
rename : src/server/game/Instances/InstanceData.h => src/server/game/Instances/InstanceScript.h
This commit is contained in:
azazel
2010-08-08 22:54:58 +06:00
parent 8a69e50d6a
commit 590199d8e1
482 changed files with 84476 additions and 82697 deletions
@@ -36,36 +36,36 @@ EndContentData */
#define SPELL_TELEPORT 41566 // s41566 - Teleport to Ashtongue NPC's
#define GOSSIP_OLUM1 "Teleport me to the other Ashtongue Deathsworn"
bool GossipHello_npc_spirit_of_olum(Player* pPlayer, Creature* pCreature)
␍class npc_spirit_of_olum : public CreatureScript
{
ScriptedInstance* pInstance = pCreature->GetInstanceData();
public:
npc_spirit_of_olum() : CreatureScript("npc_spirit_of_olum") { }
if (pInstance && (pInstance->GetData(DATA_SUPREMUSEVENT) >= DONE) && (pInstance->GetData(DATA_HIGHWARLORDNAJENTUSEVENT) >= DONE))
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_OLUM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
bool OnGossipSelect(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
{
if (uiAction == GOSSIP_ACTION_INFO_DEF + 1)
pPlayer->CLOSE_GOSSIP_MENU();
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
pPlayer->InterruptNonMeleeSpells(false);
pPlayer->CastSpell(pPlayer, SPELL_TELEPORT, false);
return true;
}
bool GossipSelect_npc_spirit_of_olum(Player* pPlayer, Creature* /*pCreature*/, uint32 /*uiSender*/, uint32 uiAction)
{
if (uiAction == GOSSIP_ACTION_INFO_DEF + 1)
pPlayer->CLOSE_GOSSIP_MENU();
bool OnGossipHello(Player* pPlayer, Creature* pCreature)
{
InstanceScript* pInstance = pCreature->GetInstanceScript();
if (pInstance && (pInstance->GetData(DATA_SUPREMUSEVENT) >= DONE) && (pInstance->GetData(DATA_HIGHWARLORDNAJENTUSEVENT) >= DONE))
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_OLUM1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1);
pPlayer->SEND_GOSSIP_MENU(pPlayer->GetGossipTextId(pCreature), pCreature->GetGUID());
return true;
}
};
pPlayer->InterruptNonMeleeSpells(false);
pPlayer->CastSpell(pPlayer, SPELL_TELEPORT, false);
return true;
}
void AddSC_black_temple()
{
Script *newscript;
newscript = new Script;
newscript->Name = "npc_spirit_of_olum";
newscript->pGossipHello = &GossipHello_npc_spirit_of_olum;
newscript->pGossipSelect = &GossipSelect_npc_spirit_of_olum;
newscript->RegisterSelf();
new npc_spirit_of_olum();
}
@@ -54,281 +54,283 @@ EndScriptData */
#define SPELL_BERSERK 45078
//This is used to sort the players by distance in preparation for the Bloodboil cast.
struct boss_gurtogg_bloodboilAI : public ScriptedAI
␍class boss_gurtogg_bloodboil : public CreatureScript
{
boss_gurtogg_bloodboilAI(Creature *c) : ScriptedAI(c)
public:
boss_gurtogg_bloodboil() : CreatureScript("boss_gurtogg_bloodboil") { }
CreatureAI* GetAI(Creature* pCreature) const
{
pInstance = c->GetInstanceData();
return new boss_gurtogg_bloodboilAI (pCreature);
}
ScriptedInstance* pInstance;
uint64 TargetGUID;
float TargetThreat;
uint32 BloodboilTimer;
uint32 BloodboilCount;
uint32 AcidGeyserTimer;
uint32 AcidicWoundTimer;
uint32 ArcingSmashTimer;
uint32 EnrageTimer;
uint32 FelAcidTimer;
uint32 EjectTimer;
uint32 BewilderingStrikeTimer;
uint32 PhaseChangeTimer;
bool Phase1;
void Reset()
struct boss_gurtogg_bloodboilAI : public ScriptedAI
{
if (pInstance)
pInstance->SetData(DATA_GURTOGGBLOODBOILEVENT, NOT_STARTED);
TargetGUID = 0;
TargetThreat = 0;
BloodboilTimer = 10000;
BloodboilCount = 0;
AcidGeyserTimer = 1000;
AcidicWoundTimer = 6000;
ArcingSmashTimer = 19000;
EnrageTimer = 600000;
FelAcidTimer = 25000;
EjectTimer = 10000;
BewilderingStrikeTimer = 15000;
PhaseChangeTimer = 60000;
Phase1 = true;
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
me->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false);
}
void EnterCombat(Unit * /*who*/)
{
DoZoneInCombat();
DoScriptText(SAY_AGGRO, me);
if (pInstance)
pInstance->SetData(DATA_GURTOGGBLOODBOILEVENT, IN_PROGRESS);
}
void KilledUnit(Unit * /*victim*/)
{
DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me);
}
void JustDied(Unit * /*victim*/)
{
if (pInstance)
pInstance->SetData(DATA_GURTOGGBLOODBOILEVENT, DONE);
DoScriptText(SAY_DEATH, me);
}
// Note: This seems like a very complicated fix. The fix needs to be handled by the core, as implementation of limited-target AoE spells are still not limited.
void CastBloodboil()
{
// Get the Threat List
std::list<HostileReference *> m_threatlist = me->getThreatManager().getThreatList();
if (!m_threatlist.size()) // He doesn't have anyone in his threatlist, useless to continue
return;
std::list<Unit *> targets;
std::list<HostileReference *>::const_iterator itr = m_threatlist.begin();
for (; itr!= m_threatlist.end(); ++itr) //store the threat list in a different container
boss_gurtogg_bloodboilAI(Creature *c) : ScriptedAI(c)
{
Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid());
//only on alive players
if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER)
targets.push_back(pTarget);
pInstance = c->GetInstanceScript();
}
//Sort the list of players
targets.sort(Trinity::ObjectDistanceOrderPred(me, false));
//Resize so we only get top 5
targets.resize(5);
InstanceScript* pInstance;
//Aura each player in the targets list with Bloodboil. Aura code copied+pasted from Aura command in Level3.cpp
/*SpellEntry const *spellInfo = GetSpellStore()->LookupEntry(SPELL_BLOODBOIL);
if (spellInfo)
uint64 TargetGUID;
float TargetThreat;
uint32 BloodboilTimer;
uint32 BloodboilCount;
uint32 AcidGeyserTimer;
uint32 AcidicWoundTimer;
uint32 ArcingSmashTimer;
uint32 EnrageTimer;
uint32 FelAcidTimer;
uint32 EjectTimer;
uint32 BewilderingStrikeTimer;
uint32 PhaseChangeTimer;
bool Phase1;
void Reset()
{
for (std::list<Unit *>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
{
Unit *pTarget = *itr;
if (!pTarget) return;
for (uint32 i = 0; i<3; ++i)
{
uint8 eff = spellInfo->Effect[i];
if (eff >= TOTAL_SPELL_EFFECTS)
continue;
if (pInstance)
pInstance->SetData(DATA_GURTOGGBLOODBOILEVENT, NOT_STARTED);
Aura *Aur = new Aura(spellInfo, i, pTarget, pTarget, pTarget);
pTarget->AddAura(Aur);
}
}
}*/
}
TargetGUID = 0;
void RevertThreatOnTarget(uint64 guid)
{
Unit* pUnit = NULL;
pUnit = Unit::GetUnit((*me), guid);
if (pUnit)
{
if (DoGetThreat(pUnit))
DoModifyThreatPercent(pUnit, -100);
if (TargetThreat)
me->AddThreat(pUnit, TargetThreat);
}
}
TargetThreat = 0;
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (ArcingSmashTimer <= diff)
{
DoCast(me->getVictim(), SPELL_ARCING_SMASH);
ArcingSmashTimer = 10000;
} else ArcingSmashTimer -= diff;
if (FelAcidTimer <= diff)
{
DoCast(me->getVictim(), SPELL_FEL_ACID);
BloodboilTimer = 10000;
BloodboilCount = 0;
AcidGeyserTimer = 1000;
AcidicWoundTimer = 6000;
ArcingSmashTimer = 19000;
EnrageTimer = 600000;
FelAcidTimer = 25000;
} else FelAcidTimer -= diff;
EjectTimer = 10000;
BewilderingStrikeTimer = 15000;
PhaseChangeTimer = 60000;
if (!me->HasAura(SPELL_BERSERK))
{
if (EnrageTimer <= diff)
{
DoCast(me, SPELL_BERSERK);
DoScriptText(RAND(SAY_ENRAGE1,SAY_ENRAGE2), me);
} else EnrageTimer -= diff;
Phase1 = true;
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
me->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false);
}
if (Phase1)
void EnterCombat(Unit * /*who*/)
{
if (BewilderingStrikeTimer <= diff)
{
DoCast(me->getVictim(), SPELL_BEWILDERING_STRIKE);
float mt_threat = DoGetThreat(me->getVictim());
if (Unit *pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 1))
me->AddThreat(pTarget, mt_threat);
BewilderingStrikeTimer = 20000;
} else BewilderingStrikeTimer -= diff;
DoZoneInCombat();
DoScriptText(SAY_AGGRO, me);
if (pInstance)
pInstance->SetData(DATA_GURTOGGBLOODBOILEVENT, IN_PROGRESS);
}
if (EjectTimer <= diff)
{
DoCast(me->getVictim(), SPELL_EJECT1);
DoModifyThreatPercent(me->getVictim(), -40);
EjectTimer = 15000;
} else EjectTimer -= diff;
void KilledUnit(Unit * /*victim*/)
{
DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me);
}
if (AcidicWoundTimer <= diff)
{
DoCast(me->getVictim(), SPELL_ACIDIC_WOUND);
AcidicWoundTimer = 10000;
} else AcidicWoundTimer -= diff;
void JustDied(Unit * /*victim*/)
{
if (pInstance)
pInstance->SetData(DATA_GURTOGGBLOODBOILEVENT, DONE);
if (BloodboilTimer <= diff)
DoScriptText(SAY_DEATH, me);
}
// Note: This seems like a very complicated fix. The fix needs to be handled by the core, as implementation of limited-target AoE spells are still not limited.
void CastBloodboil()
{
// Get the Threat List
std::list<HostileReference *> m_threatlist = me->getThreatManager().getThreatList();
if (!m_threatlist.size()) // He doesn't have anyone in his threatlist, useless to continue
return;
std::list<Unit *> targets;
std::list<HostileReference *>::const_iterator itr = m_threatlist.begin();
for (; itr!= m_threatlist.end(); ++itr) //store the threat list in a different container
{
if (BloodboilCount < 5) // Only cast it five times.
Unit *pTarget = Unit::GetUnit(*me, (*itr)->getUnitGuid());
//only on alive players
if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER)
targets.push_back(pTarget);
}
//Sort the list of players
targets.sort(Trinity::ObjectDistanceOrderPred(me, false));
//Resize so we only get top 5
targets.resize(5);
//Aura each player in the targets list with Bloodboil. Aura code copied+pasted from Aura command in Level3.cpp
/*SpellEntry const *spellInfo = GetSpellStore()->LookupEntry(SPELL_BLOODBOIL);
if (spellInfo)
{
for (std::list<Unit *>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
{
//CastBloodboil(); // Causes issues on windows, so is commented out.
DoCast(me->getVictim(), SPELL_BLOODBOIL);
++BloodboilCount;
BloodboilTimer = 10000*BloodboilCount;
Unit *pTarget = *itr;
if (!pTarget) return;
for (uint32 i = 0; i<3; ++i)
{
uint8 eff = spellInfo->Effect[i];
if (eff >= TOTAL_SPELL_EFFECTS)
continue;
Aura *Aur = new Aura(spellInfo, i, pTarget, pTarget, pTarget);
pTarget->AddAura(Aur);
}
}
} else BloodboilTimer -= diff;
}*/
}
if (!Phase1)
void RevertThreatOnTarget(uint64 guid)
{
if (AcidGeyserTimer <= diff)
Unit* pUnit = NULL;
pUnit = Unit::GetUnit((*me), guid);
if (pUnit)
{
DoCast(me->getVictim(), SPELL_ACID_GEYSER);
AcidGeyserTimer = 30000;
} else AcidGeyserTimer -= diff;
if (EjectTimer <= diff)
{
DoCast(me->getVictim(), SPELL_EJECT2);
EjectTimer = 15000;
} else EjectTimer -= diff;
if (DoGetThreat(pUnit))
DoModifyThreatPercent(pUnit, -100);
if (TargetThreat)
me->AddThreat(pUnit, TargetThreat);
}
}
if (PhaseChangeTimer <= diff)
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (ArcingSmashTimer <= diff)
{
DoCast(me->getVictim(), SPELL_ARCING_SMASH);
ArcingSmashTimer = 10000;
} else ArcingSmashTimer -= diff;
if (FelAcidTimer <= diff)
{
DoCast(me->getVictim(), SPELL_FEL_ACID);
FelAcidTimer = 25000;
} else FelAcidTimer -= diff;
if (!me->HasAura(SPELL_BERSERK))
{
if (EnrageTimer <= diff)
{
DoCast(me, SPELL_BERSERK);
DoScriptText(RAND(SAY_ENRAGE1,SAY_ENRAGE2), me);
} else EnrageTimer -= diff;
}
if (Phase1)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (pTarget && pTarget->isAlive())
if (BewilderingStrikeTimer <= diff)
{
Phase1 = false;
DoCast(me->getVictim(), SPELL_BEWILDERING_STRIKE);
float mt_threat = DoGetThreat(me->getVictim());
if (Unit *pTarget = SelectUnit(SELECT_TARGET_TOPAGGRO, 1))
me->AddThreat(pTarget, mt_threat);
BewilderingStrikeTimer = 20000;
} else BewilderingStrikeTimer -= diff;
TargetThreat = DoGetThreat(pTarget);
TargetGUID = pTarget->GetGUID();
pTarget->CastSpell(me, SPELL_TAUNT_GURTOGG, true);
if (DoGetThreat(pTarget))
DoModifyThreatPercent(pTarget, -100);
me->AddThreat(pTarget, 50000000.0f);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
// If VMaps are disabled, this spell can call the whole instance
DoCast(me, SPELL_INSIGNIFIGANCE, true);
DoCast(pTarget, SPELL_FEL_RAGE_TARGET, true);
DoCast(pTarget, SPELL_FEL_RAGE_2, true);
/* These spells do not work, comment them out for now.
DoCast(pTarget, SPELL_FEL_RAGE_2, true);
DoCast(pTarget, SPELL_FEL_RAGE_3, true);*/
if (EjectTimer <= diff)
{
DoCast(me->getVictim(), SPELL_EJECT1);
DoModifyThreatPercent(me->getVictim(), -40);
EjectTimer = 15000;
} else EjectTimer -= diff;
//Cast this without triggered so that it appears in combat logs and shows visual.
DoCast(me, SPELL_FEL_RAGE_SELF);
if (AcidicWoundTimer <= diff)
{
DoCast(me->getVictim(), SPELL_ACIDIC_WOUND);
AcidicWoundTimer = 10000;
} else AcidicWoundTimer -= diff;
DoScriptText(RAND(SAY_SPECIAL1,SAY_SPECIAL2), me);
AcidGeyserTimer = 1000;
PhaseChangeTimer = 30000;
}
} else // Encounter is a loop pretty much. Phase 1 -> Phase 2 -> Phase 1 -> Phase 2 till death or enrage
{
if (TargetGUID)
RevertThreatOnTarget(TargetGUID);
TargetGUID = 0;
Phase1 = true;
BloodboilTimer = 10000;
BloodboilCount = 0;
AcidicWoundTimer += 2000;
ArcingSmashTimer += 2000;
FelAcidTimer += 2000;
EjectTimer += 2000;
PhaseChangeTimer = 60000;
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
me->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false);
if (BloodboilTimer <= diff)
{
if (BloodboilCount < 5) // Only cast it five times.
{
//CastBloodboil(); // Causes issues on windows, so is commented out.
DoCast(me->getVictim(), SPELL_BLOODBOIL);
++BloodboilCount;
BloodboilTimer = 10000*BloodboilCount;
}
} else BloodboilTimer -= diff;
}
} else PhaseChangeTimer -= diff;
DoMeleeAttackIfReady();
}
if (!Phase1)
{
if (AcidGeyserTimer <= diff)
{
DoCast(me->getVictim(), SPELL_ACID_GEYSER);
AcidGeyserTimer = 30000;
} else AcidGeyserTimer -= diff;
if (EjectTimer <= diff)
{
DoCast(me->getVictim(), SPELL_EJECT2);
EjectTimer = 15000;
} else EjectTimer -= diff;
}
if (PhaseChangeTimer <= diff)
{
if (Phase1)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (pTarget && pTarget->isAlive())
{
Phase1 = false;
TargetThreat = DoGetThreat(pTarget);
TargetGUID = pTarget->GetGUID();
pTarget->CastSpell(me, SPELL_TAUNT_GURTOGG, true);
if (DoGetThreat(pTarget))
DoModifyThreatPercent(pTarget, -100);
me->AddThreat(pTarget, 50000000.0f);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
// If VMaps are disabled, this spell can call the whole instance
DoCast(me, SPELL_INSIGNIFIGANCE, true);
DoCast(pTarget, SPELL_FEL_RAGE_TARGET, true);
DoCast(pTarget, SPELL_FEL_RAGE_2, true);
/* These spells do not work, comment them out for now.
DoCast(pTarget, SPELL_FEL_RAGE_2, true);
DoCast(pTarget, SPELL_FEL_RAGE_3, true);*/
//Cast this without triggered so that it appears in combat logs and shows visual.
DoCast(me, SPELL_FEL_RAGE_SELF);
DoScriptText(RAND(SAY_SPECIAL1,SAY_SPECIAL2), me);
AcidGeyserTimer = 1000;
PhaseChangeTimer = 30000;
}
} else // Encounter is a loop pretty much. Phase 1 -> Phase 2 -> Phase 1 -> Phase 2 till death or enrage
{
if (TargetGUID)
RevertThreatOnTarget(TargetGUID);
TargetGUID = 0;
Phase1 = true;
BloodboilTimer = 10000;
BloodboilCount = 0;
AcidicWoundTimer += 2000;
ArcingSmashTimer += 2000;
FelAcidTimer += 2000;
EjectTimer += 2000;
PhaseChangeTimer = 60000;
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
me->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false);
}
} else PhaseChangeTimer -= diff;
DoMeleeAttackIfReady();
}
};
};
CreatureAI* GetAI_boss_gurtogg_bloodboil(Creature* pCreature)
{
return new boss_gurtogg_bloodboilAI (pCreature);
}
void AddSC_boss_gurtogg_bloodboil()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_gurtogg_bloodboil";
newscript->GetAI = &GetAI_boss_gurtogg_bloodboil;
newscript->RegisterSelf();
new boss_gurtogg_bloodboil();
}
File diff suppressed because it is too large Load Diff
@@ -77,228 +77,230 @@ static Locations TeleportPoint[]=
{930.548, 284.888, 193.367},
{965.997, 278.398, 195.777}
};
struct boss_shahrazAI : public ScriptedAI
␍class boss_mother_shahraz : public CreatureScript
{
boss_shahrazAI(Creature *c) : ScriptedAI(c)
public:
boss_mother_shahraz() : CreatureScript("boss_mother_shahraz") { }
CreatureAI* GetAI(Creature* pCreature) const
{
pInstance = c->GetInstanceData();
return new boss_shahrazAI (pCreature);
}
ScriptedInstance* pInstance;
uint64 TargetGUID[3];
uint32 BeamTimer;
uint32 BeamCount;
uint32 CurrentBeam;
uint32 PrismaticShieldTimer;
uint32 FatalAttractionTimer;
uint32 FatalAttractionExplodeTimer;
uint32 ShriekTimer;
uint32 SaberTimer;
uint32 RandomYellTimer;
uint32 EnrageTimer;
uint32 ExplosionCount;
bool Enraged;
void Reset()
struct boss_shahrazAI : public ScriptedAI
{
if (pInstance)
pInstance->SetData(DATA_MOTHERSHAHRAZEVENT, NOT_STARTED);
for (uint8 i = 0; i<3; ++i)
TargetGUID[i] = 0;
BeamTimer = 20000; // Timers may be incorrect
BeamCount = 0;
CurrentBeam = 0; // 0 - Sinister, 1 - Vile, 2 - Wicked, 3 - Sinful
PrismaticShieldTimer = 0;
FatalAttractionTimer = 60000;
FatalAttractionExplodeTimer = 70000;
ShriekTimer = 30000;
SaberTimer = 35000;
RandomYellTimer = 70000 + rand()%41 * 1000;
EnrageTimer = 600000;
ExplosionCount = 0;
Enraged = false;
}
void EnterCombat(Unit * /*who*/)
{
if (pInstance)
pInstance->SetData(DATA_MOTHERSHAHRAZEVENT, IN_PROGRESS);
DoZoneInCombat();
DoScriptText(SAY_AGGRO, me);
}
void KilledUnit(Unit * /*victim*/)
{
DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me);
}
void JustDied(Unit * /*victim*/)
{
if (pInstance)
pInstance->SetData(DATA_MOTHERSHAHRAZEVENT, DONE);
DoScriptText(SAY_DEATH, me);
}
void TeleportPlayers()
{
uint32 random = rand()%7;
float X = TeleportPoint[random].x;
float Y = TeleportPoint[random].y;
float Z = TeleportPoint[random].z;
for (uint8 i = 0; i < 3; ++i)
boss_shahrazAI(Creature *c) : ScriptedAI(c)
{
Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER))
{
TargetGUID[i] = pUnit->GetGUID();
pUnit->CastSpell(pUnit, SPELL_TELEPORT_VISUAL, true);
DoTeleportPlayer(pUnit, X, Y, Z, pUnit->GetOrientation());
}
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (((me->GetHealth()*100 / me->GetMaxHealth()) < 10) && !Enraged)
{
Enraged = true;
DoCast(me, SPELL_ENRAGE, true);
DoScriptText(SAY_ENRAGE, me);
pInstance = c->GetInstanceScript();
}
//Randomly cast one beam.
if (BeamTimer <= diff)
InstanceScript* pInstance;
uint64 TargetGUID[3];
uint32 BeamTimer;
uint32 BeamCount;
uint32 CurrentBeam;
uint32 PrismaticShieldTimer;
uint32 FatalAttractionTimer;
uint32 FatalAttractionExplodeTimer;
uint32 ShriekTimer;
uint32 SaberTimer;
uint32 RandomYellTimer;
uint32 EnrageTimer;
uint32 ExplosionCount;
bool Enraged;
void Reset()
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (!pTarget || !pTarget->isAlive())
return;
if (pInstance)
pInstance->SetData(DATA_MOTHERSHAHRAZEVENT, NOT_STARTED);
BeamTimer = 9000;
for (uint8 i = 0; i<3; ++i)
TargetGUID[i] = 0;
switch(CurrentBeam)
{
case 0:
DoCast(pTarget, SPELL_BEAM_SINISTER);
break;
case 1:
DoCast(pTarget, SPELL_BEAM_VILE);
break;
case 2:
DoCast(pTarget, SPELL_BEAM_WICKED);
break;
case 3:
DoCast(pTarget, SPELL_BEAM_SINFUL);
break;
}
++BeamCount;
uint32 Beam = CurrentBeam;
if (BeamCount > 3)
while (CurrentBeam == Beam)
CurrentBeam = rand()%3;
} else BeamTimer -= diff;
// Random Prismatic Shield every 15 seconds.
if (PrismaticShieldTimer <= diff)
{
uint32 random = rand()%6;
if (PrismaticAuras[random])
DoCast(me, PrismaticAuras[random]);
PrismaticShieldTimer = 15000;
} else PrismaticShieldTimer -= diff;
// Select 3 random targets (can select same target more than once), teleport to a random location then make them cast explosions until they get away from each other.
if (FatalAttractionTimer <= diff)
{
BeamTimer = 20000; // Timers may be incorrect
BeamCount = 0;
CurrentBeam = 0; // 0 - Sinister, 1 - Vile, 2 - Wicked, 3 - Sinful
PrismaticShieldTimer = 0;
FatalAttractionTimer = 60000;
FatalAttractionExplodeTimer = 70000;
ShriekTimer = 30000;
SaberTimer = 35000;
RandomYellTimer = 70000 + rand()%41 * 1000;
EnrageTimer = 600000;
ExplosionCount = 0;
TeleportPlayers();
Enraged = false;
}
DoScriptText(RAND(SAY_SPELL2,SAY_SPELL3), me);
FatalAttractionExplodeTimer = 2000;
FatalAttractionTimer = 40000 + rand()%31 * 1000;
} else FatalAttractionTimer -= diff;
if (FatalAttractionExplodeTimer <= diff)
void EnterCombat(Unit * /*who*/)
{
// Just make them explode three times... they're supposed to keep exploding while they are in range, but it'll take too much code. I'll try to think of an efficient way for it later.
if (ExplosionCount < 3)
if (pInstance)
pInstance->SetData(DATA_MOTHERSHAHRAZEVENT, IN_PROGRESS);
DoZoneInCombat();
DoScriptText(SAY_AGGRO, me);
}
void KilledUnit(Unit * /*victim*/)
{
DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me);
}
void JustDied(Unit * /*victim*/)
{
if (pInstance)
pInstance->SetData(DATA_MOTHERSHAHRAZEVENT, DONE);
DoScriptText(SAY_DEATH, me);
}
void TeleportPlayers()
{
uint32 random = rand()%7;
float X = TeleportPoint[random].x;
float Y = TeleportPoint[random].y;
float Z = TeleportPoint[random].z;
for (uint8 i = 0; i < 3; ++i)
{
for (uint8 i = 0; i < 3; ++i)
Unit* pUnit = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (pUnit && pUnit->isAlive() && (pUnit->GetTypeId() == TYPEID_PLAYER))
{
Unit* pUnit = NULL;
if (TargetGUID[i])
{
pUnit = Unit::GetUnit((*me), TargetGUID[i]);
if (pUnit)
pUnit->CastSpell(pUnit, SPELL_ATTRACTION, true);
TargetGUID[i] = 0;
}
TargetGUID[i] = pUnit->GetGUID();
pUnit->CastSpell(pUnit, SPELL_TELEPORT_VISUAL, true);
DoTeleportPlayer(pUnit, X, Y, Z, pUnit->GetOrientation());
}
++ExplosionCount;
FatalAttractionExplodeTimer = 1000;
}
else
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
if (((me->GetHealth()*100 / me->GetMaxHealth()) < 10) && !Enraged)
{
FatalAttractionExplodeTimer = FatalAttractionTimer + 2000;
ExplosionCount = 0;
Enraged = true;
DoCast(me, SPELL_ENRAGE, true);
DoScriptText(SAY_ENRAGE, me);
}
} else FatalAttractionExplodeTimer -= diff;
if (ShriekTimer <= diff)
{
DoCast(me->getVictim(), SPELL_SILENCING_SHRIEK);
ShriekTimer = 25000+rand()%10 * 1000;
} else ShriekTimer -= diff;
//Randomly cast one beam.
if (BeamTimer <= diff)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (!pTarget || !pTarget->isAlive())
return;
if (SaberTimer <= diff)
{
DoCast(me->getVictim(), SPELL_SABER_LASH);
SaberTimer = 25000+rand()%10 * 1000;
} else SaberTimer -= diff;
BeamTimer = 9000;
//Enrage
if (!me->HasAura(SPELL_BERSERK))
if (EnrageTimer <= diff)
{
DoCast(me, SPELL_BERSERK);
DoScriptText(SAY_ENRAGE, me);
} else EnrageTimer -= diff;
switch(CurrentBeam)
{
case 0:
DoCast(pTarget, SPELL_BEAM_SINISTER);
break;
case 1:
DoCast(pTarget, SPELL_BEAM_VILE);
break;
case 2:
DoCast(pTarget, SPELL_BEAM_WICKED);
break;
case 3:
DoCast(pTarget, SPELL_BEAM_SINFUL);
break;
}
++BeamCount;
uint32 Beam = CurrentBeam;
if (BeamCount > 3)
while (CurrentBeam == Beam)
CurrentBeam = rand()%3;
//Random taunts
if (RandomYellTimer <= diff)
{
DoScriptText(RAND(SAY_TAUNT1,SAY_TAUNT2,SAY_TAUNT3), me);
RandomYellTimer = 60000 + rand()%91 * 1000;
} else RandomYellTimer -= diff;
} else BeamTimer -= diff;
// Random Prismatic Shield every 15 seconds.
if (PrismaticShieldTimer <= diff)
{
uint32 random = rand()%6;
if (PrismaticAuras[random])
DoCast(me, PrismaticAuras[random]);
PrismaticShieldTimer = 15000;
} else PrismaticShieldTimer -= diff;
// Select 3 random targets (can select same target more than once), teleport to a random location then make them cast explosions until they get away from each other.
if (FatalAttractionTimer <= diff)
{
ExplosionCount = 0;
TeleportPlayers();
DoScriptText(RAND(SAY_SPELL2,SAY_SPELL3), me);
FatalAttractionExplodeTimer = 2000;
FatalAttractionTimer = 40000 + rand()%31 * 1000;
} else FatalAttractionTimer -= diff;
if (FatalAttractionExplodeTimer <= diff)
{
// Just make them explode three times... they're supposed to keep exploding while they are in range, but it'll take too much code. I'll try to think of an efficient way for it later.
if (ExplosionCount < 3)
{
for (uint8 i = 0; i < 3; ++i)
{
Unit* pUnit = NULL;
if (TargetGUID[i])
{
pUnit = Unit::GetUnit((*me), TargetGUID[i]);
if (pUnit)
pUnit->CastSpell(pUnit, SPELL_ATTRACTION, true);
TargetGUID[i] = 0;
}
}
++ExplosionCount;
FatalAttractionExplodeTimer = 1000;
}
else
{
FatalAttractionExplodeTimer = FatalAttractionTimer + 2000;
ExplosionCount = 0;
}
} else FatalAttractionExplodeTimer -= diff;
if (ShriekTimer <= diff)
{
DoCast(me->getVictim(), SPELL_SILENCING_SHRIEK);
ShriekTimer = 25000+rand()%10 * 1000;
} else ShriekTimer -= diff;
if (SaberTimer <= diff)
{
DoCast(me->getVictim(), SPELL_SABER_LASH);
SaberTimer = 25000+rand()%10 * 1000;
} else SaberTimer -= diff;
//Enrage
if (!me->HasAura(SPELL_BERSERK))
if (EnrageTimer <= diff)
{
DoCast(me, SPELL_BERSERK);
DoScriptText(SAY_ENRAGE, me);
} else EnrageTimer -= diff;
//Random taunts
if (RandomYellTimer <= diff)
{
DoScriptText(RAND(SAY_TAUNT1,SAY_TAUNT2,SAY_TAUNT3), me);
RandomYellTimer = 60000 + rand()%91 * 1000;
} else RandomYellTimer -= diff;
DoMeleeAttackIfReady();
}
};
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_shahraz(Creature* pCreature)
{
return new boss_shahrazAI (pCreature);
}
void AddSC_boss_mother_shahraz()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_mother_shahraz";
newscript->GetAI = &GetAI_boss_shahraz;
newscript->RegisterSelf();
new boss_mother_shahraz();
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -52,247 +52,255 @@ EndScriptData */
#define EVENT_HATEFUL_STRIKE 6
#define GCD_CAST 1
struct molten_flameAI : public NullCreatureAI
␍class molten_flame : public CreatureScript
{
molten_flameAI(Creature *c) : NullCreatureAI(c) {}
public:
molten_flame() : CreatureScript("molten_flame") { }
void InitializeAI()
CreatureAI* GetAI(Creature* pCreature) const
{
float x, y, z;
me->GetNearPoint(me, x, y, z, 1, 100, M_PI*2*rand_norm());
me->GetMotionMaster()->MovePoint(0, x, y, z);
me->SetVisibility(VISIBILITY_OFF);
me->CastSpell(me,SPELL_MOLTEN_FLAME,true);
return new molten_flameAI (pCreature);
}
struct molten_flameAI : public NullCreatureAI
{
molten_flameAI(Creature *c) : NullCreatureAI(c) {}
void InitializeAI()
{
float x, y, z;
me->GetNearPoint(me, x, y, z, 1, 100, M_PI*2*rand_norm());
me->GetMotionMaster()->MovePoint(0, x, y, z);
me->SetVisibility(VISIBILITY_OFF);
me->CastSpell(me,SPELL_MOLTEN_FLAME,true);
}
};
};
struct boss_supremusAI : public ScriptedAI
␍class boss_supremus : public CreatureScript
{
boss_supremusAI(Creature *c) : ScriptedAI(c), summons(me)
public:
boss_supremus() : CreatureScript("boss_supremus") { }
CreatureAI* GetAI(Creature* pCreature) const
{
pInstance = c->GetInstanceData();
return new boss_supremusAI (pCreature);
}
ScriptedInstance* pInstance;
EventMap events;
SummonList summons;
uint32 phase;
void Reset()
struct boss_supremusAI : public ScriptedAI
{
if (pInstance)
boss_supremusAI(Creature *c) : ScriptedAI(c), summons(me)
{
if (me->isAlive())
pInstance = c->GetInstanceScript();
}
InstanceScript* pInstance;
EventMap events;
SummonList summons;
uint32 phase;
void Reset()
{
if (pInstance)
{
pInstance->SetData(DATA_SUPREMUSEVENT, NOT_STARTED);
//ToggleDoors(true);
}
//else ToggleDoors(false);
}
phase = 0;
events.Reset();
summons.DespawnAll();
}
void EnterCombat(Unit * /*who*/)
{
if (pInstance)
pInstance->SetData(DATA_SUPREMUSEVENT, IN_PROGRESS);
ChangePhase();
events.ScheduleEvent(EVENT_BERSERK, 900000, GCD_CAST);
events.ScheduleEvent(EVENT_FLAME, 20000, GCD_CAST);
}
void ChangePhase()
{
if (!phase || phase == PHASE_CHASE)
{
phase = PHASE_STRIKE;
summons.DoAction(EVENT_VOLCANO, 0);
events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE);
me->SetSpeed(MOVE_RUN, 1.2f);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
me->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false);
}
else
{
phase = PHASE_CHASE;
events.ScheduleEvent(EVENT_VOLCANO, 5000, GCD_CAST, PHASE_CHASE);
events.ScheduleEvent(EVENT_SWITCH_TARGET, 10000, 0, PHASE_CHASE);
me->SetSpeed(MOVE_RUN, 0.9f);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
DoResetThreat();
DoZoneInCombat();
events.SetPhase(phase);
events.ScheduleEvent(EVENT_SWITCH_PHASE, 60000, GCD_CAST);
}
void JustDied(Unit * /*killer*/)
{
if (pInstance)
{
pInstance->SetData(DATA_SUPREMUSEVENT, DONE);
pInstance->HandleGameObject(pInstance->GetData64(DATA_GAMEOBJECT_SUPREMUS_DOORS), true);
}
summons.DespawnAll();
}
void JustSummoned(Creature *summon) {summons.Summon(summon);}
void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);}
Unit* CalculateHatefulStrikeTarget()
{
uint32 health = 0;
Unit *pTarget = NULL;
std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList();
std::list<HostileReference*>::const_iterator i = m_threatlist.begin();
for (i = m_threatlist.begin(); i!= m_threatlist.end(); ++i)
{
Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid());
if (pUnit && me->IsWithinMeleeRange(pUnit))
{
if (pUnit->GetHealth() > health)
if (me->isAlive())
{
health = pUnit->GetHealth();
pTarget = pUnit;
pInstance->SetData(DATA_SUPREMUSEVENT, NOT_STARTED);
//ToggleDoors(true);
}
//else ToggleDoors(false);
}
phase = 0;
events.Reset();
summons.DespawnAll();
}
void EnterCombat(Unit * /*who*/)
{
if (pInstance)
pInstance->SetData(DATA_SUPREMUSEVENT, IN_PROGRESS);
ChangePhase();
events.ScheduleEvent(EVENT_BERSERK, 900000, GCD_CAST);
events.ScheduleEvent(EVENT_FLAME, 20000, GCD_CAST);
}
void ChangePhase()
{
if (!phase || phase == PHASE_CHASE)
{
phase = PHASE_STRIKE;
summons.DoAction(EVENT_VOLCANO, 0);
events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE);
me->SetSpeed(MOVE_RUN, 1.2f);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, false);
me->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, false);
}
else
{
phase = PHASE_CHASE;
events.ScheduleEvent(EVENT_VOLCANO, 5000, GCD_CAST, PHASE_CHASE);
events.ScheduleEvent(EVENT_SWITCH_TARGET, 10000, 0, PHASE_CHASE);
me->SetSpeed(MOVE_RUN, 0.9f);
me->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
me->ApplySpellImmune(0, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
}
DoResetThreat();
DoZoneInCombat();
events.SetPhase(phase);
events.ScheduleEvent(EVENT_SWITCH_PHASE, 60000, GCD_CAST);
}
void JustDied(Unit * /*killer*/)
{
if (pInstance)
{
pInstance->SetData(DATA_SUPREMUSEVENT, DONE);
pInstance->HandleGameObject(pInstance->GetData64(DATA_GAMEOBJECT_SUPREMUS_DOORS), true);
}
summons.DespawnAll();
}
void JustSummoned(Creature *summon) {summons.Summon(summon);}
void SummonedCreatureDespawn(Creature *summon) {summons.Despawn(summon);}
Unit* CalculateHatefulStrikeTarget()
{
uint32 health = 0;
Unit *pTarget = NULL;
std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList();
std::list<HostileReference*>::const_iterator i = m_threatlist.begin();
for (i = m_threatlist.begin(); i!= m_threatlist.end(); ++i)
{
Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid());
if (pUnit && me->IsWithinMeleeRange(pUnit))
{
if (pUnit->GetHealth() > health)
{
health = pUnit->GetHealth();
pTarget = pUnit;
}
}
}
return pTarget;
}
return pTarget;
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
void UpdateAI(const uint32 diff)
{
switch(eventId)
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK, true);
break;
case EVENT_FLAME:
DoCast(me, SPELL_MOLTEN_PUNCH);
events.DelayEvents(1500, GCD_CAST);
events.ScheduleEvent(EVENT_FLAME, 20000, GCD_CAST);
break;
case EVENT_HATEFUL_STRIKE:
if (Unit *pTarget = CalculateHatefulStrikeTarget())
DoCast(pTarget, SPELL_HATEFUL_STRIKE);
events.DelayEvents(1000, GCD_CAST);
events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE);
break;
case EVENT_SWITCH_TARGET:
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true))
{
DoResetThreat();
me->AddThreat(pTarget, 5000000.0f);
DoScriptText(EMOTE_NEW_TARGET, me);
}
events.ScheduleEvent(EVENT_SWITCH_TARGET, 10000, 0, PHASE_CHASE);
break;
case EVENT_VOLCANO:
switch(eventId)
{
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 999, true);
if (!pTarget) pTarget = me->getVictim();
if (pTarget)
{
//DoCast(pTarget, SPELL_VOLCANIC_SUMMON);//movement bugged
me->SummonCreature(CREATURE_VOLCANO,pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,30000);
DoScriptText(EMOTE_GROUND_CRACK, me);
case EVENT_BERSERK:
DoCast(me, SPELL_BERSERK, true);
break;
case EVENT_FLAME:
DoCast(me, SPELL_MOLTEN_PUNCH);
events.DelayEvents(1500, GCD_CAST);
events.ScheduleEvent(EVENT_FLAME, 20000, GCD_CAST);
break;
case EVENT_HATEFUL_STRIKE:
if (Unit *pTarget = CalculateHatefulStrikeTarget())
DoCast(pTarget, SPELL_HATEFUL_STRIKE);
events.DelayEvents(1000, GCD_CAST);
events.ScheduleEvent(EVENT_HATEFUL_STRIKE, 5000, GCD_CAST, PHASE_STRIKE);
break;
case EVENT_SWITCH_TARGET:
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true))
{
DoResetThreat();
me->AddThreat(pTarget, 5000000.0f);
DoScriptText(EMOTE_NEW_TARGET, me);
}
events.ScheduleEvent(EVENT_SWITCH_TARGET, 10000, 0, PHASE_CHASE);
break;
case EVENT_VOLCANO:
{
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 999, true);
if (!pTarget) pTarget = me->getVictim();
if (pTarget)
{
//DoCast(pTarget, SPELL_VOLCANIC_SUMMON);//movement bugged
me->SummonCreature(CREATURE_VOLCANO,pTarget->GetPositionX(),pTarget->GetPositionY(),pTarget->GetPositionZ(),0,TEMPSUMMON_TIMED_DESPAWN,30000);
DoScriptText(EMOTE_GROUND_CRACK, me);
events.DelayEvents(1500, GCD_CAST);
}
events.ScheduleEvent(EVENT_VOLCANO, 10000, GCD_CAST, PHASE_CHASE);
return;
}
events.ScheduleEvent(EVENT_VOLCANO, 10000, GCD_CAST, PHASE_CHASE);
return;
case EVENT_SWITCH_PHASE:
ChangePhase();
break;
}
case EVENT_SWITCH_PHASE:
ChangePhase();
break;
}
DoMeleeAttackIfReady();
}
};
DoMeleeAttackIfReady();
}
};
struct npc_volcanoAI : public Scripted_NoMovementAI
␍class npc_volcano : public CreatureScript
{
npc_volcanoAI(Creature *c) : Scripted_NoMovementAI(c) {}
public:
npc_volcano() : CreatureScript("npc_volcano") { }
void Reset()
CreatureAI* GetAI(Creature* pCreature) const
{
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
//DoCast(me, SPELL_VOLCANIC_ERUPTION);
me->SetReactState(REACT_PASSIVE);
wait = 3000;
}
uint32 wait;
void EnterCombat(Unit * /*who*/) {}
void MoveInLineOfSight(Unit * /*who*/) {}
void DoAction(const uint32 /*info*/)
{
me->RemoveAura(SPELL_VOLCANIC_ERUPTION);
return new npc_volcanoAI (pCreature);
}
void UpdateAI(const uint32 diff)
struct npc_volcanoAI : public Scripted_NoMovementAI
{
if (wait <= diff)//wait 3secs before casting
npc_volcanoAI(Creature *c) : Scripted_NoMovementAI(c) {}
void Reset()
{
DoCast(me, SPELL_VOLCANIC_ERUPTION);
wait = 60000;
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
//DoCast(me, SPELL_VOLCANIC_ERUPTION);
me->SetReactState(REACT_PASSIVE);
wait = 3000;
}
else wait -= diff;
}
uint32 wait;
void EnterCombat(Unit * /*who*/) {}
void MoveInLineOfSight(Unit * /*who*/) {}
void DoAction(const uint32 /*info*/)
{
me->RemoveAura(SPELL_VOLCANIC_ERUPTION);
}
void UpdateAI(const uint32 diff)
{
if (wait <= diff)//wait 3secs before casting
{
DoCast(me, SPELL_VOLCANIC_ERUPTION);
wait = 60000;
}
else wait -= diff;
}
};
};
CreatureAI* GetAI_boss_supremus(Creature* pCreature)
{
return new boss_supremusAI (pCreature);
}
CreatureAI* GetAI_molten_flame(Creature* pCreature)
{
return new molten_flameAI (pCreature);
}
CreatureAI* GetAI_npc_volcano(Creature* pCreature)
{
return new npc_volcanoAI (pCreature);
}
void AddSC_boss_supremus()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_supremus";
newscript->GetAI = &GetAI_boss_supremus;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "molten_flame";
newscript->GetAI = &GetAI_molten_flame;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "npc_volcano";
newscript->GetAI = &GetAI_npc_volcano;
newscript->RegisterSelf();
new boss_supremus();
new molten_flame();
new npc_volcano();
}
@@ -50,461 +50,469 @@ EndScriptData */
#define CREATURE_DOOM_BLOSSOM 23123
#define CREATURE_SHADOWY_CONSTRUCT 23111
struct mob_doom_blossomAI : public ScriptedAI
␍class mob_doom_blossom : public CreatureScript
{
mob_doom_blossomAI(Creature *c) : ScriptedAI(c) {}
public:
mob_doom_blossom() : CreatureScript("mob_doom_blossom") { }
uint32 CheckTeronTimer;
uint32 ShadowBoltTimer;
uint64 TeronGUID;
void Reset()
CreatureAI* GetAI(Creature* pCreature) const
{
CheckTeronTimer = 5000;
ShadowBoltTimer = 12000;
TeronGUID = 0;
return new mob_doom_blossomAI(pCreature);
}
void EnterCombat(Unit * /*who*/) { }
void AttackStart(Unit* /*who*/) {}
void MoveInLineOfSight(Unit* /*who*/) {}
void Despawn()
struct mob_doom_blossomAI : public ScriptedAI
{
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
me->RemoveCorpse();
}
mob_doom_blossomAI(Creature *c) : ScriptedAI(c) {}
void UpdateAI(const uint32 diff)
{
if (CheckTeronTimer <= diff)
uint32 CheckTeronTimer;
uint32 ShadowBoltTimer;
uint64 TeronGUID;
void Reset()
{
if (TeronGUID)
{
DoZoneInCombat();
Creature* Teron = (Unit::GetCreature((*me), TeronGUID));
if ((Teron) && (!Teron->isAlive() || Teron->IsInEvadeMode()))
Despawn();
}
else
Despawn();
CheckTeronTimer = 5000;
} else CheckTeronTimer -= diff;
if (ShadowBoltTimer < diff && me->isInCombat())
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOWBOLT);
ShadowBoltTimer = 10000;
} else ShadowBoltTimer -= diff;
return;
}
void SetTeronGUID(uint64 guid){ TeronGUID = guid; }
};
struct mob_shadowy_constructAI : public ScriptedAI
{
mob_shadowy_constructAI(Creature* c) : ScriptedAI(c) {}
uint64 GhostGUID;
uint64 TeronGUID;
uint32 CheckPlayerTimer;
uint32 CheckTeronTimer;
void Reset()
{
GhostGUID = 0;
TeronGUID = 0;
CheckPlayerTimer = 2000;
CheckTeronTimer = 5000;
}
void EnterCombat(Unit* /*who*/) {}
void MoveInLineOfSight(Unit *who)
{
if (!who || (!who->isAlive()) || (who->GetGUID() == GhostGUID))
return;
ScriptedAI::MoveInLineOfSight(who);
}
/* Comment it out for now. NOTE TO FUTURE DEV: UNCOMMENT THIS OUT ONLY AFTER MIND CONTROL IS IMPLEMENTED
void DamageTaken(Unit* done_by, uint32 &damage)
{
if (done_by->GetGUID() != GhostGUID)
damage = 0; // Only the ghost can deal damage.
}
*/
void CheckPlayers()
{
std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList();
if (m_threatlist.empty())
return; // No threat list. Don't continue.
std::list<HostileReference*>::const_iterator itr = m_threatlist.begin();
std::list<Unit*> targets;
for (; itr != m_threatlist.end(); ++itr)
{
Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid());
if (pUnit && pUnit->isAlive())
targets.push_back(pUnit);
ShadowBoltTimer = 12000;
TeronGUID = 0;
}
targets.sort(Trinity::ObjectDistanceOrderPred(me));
Unit *pTarget = targets.front();
if (pTarget && me->IsWithinDistInMap(pTarget, me->GetAttackDistance(pTarget)))
void EnterCombat(Unit * /*who*/) { }
void AttackStart(Unit* /*who*/) {}
void MoveInLineOfSight(Unit* /*who*/) {}
void Despawn()
{
DoCast(pTarget, SPELL_ATROPHY);
me->AI()->AttackStart(pTarget);
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
me->RemoveCorpse();
}
}
void UpdateAI(const uint32 diff)
{
if (CheckPlayerTimer <= diff)
void UpdateAI(const uint32 diff)
{
CheckPlayers();
CheckPlayerTimer = 3000;
} else CheckPlayerTimer -= diff;
if (CheckTeronTimer <= diff)
{
Creature* Teron = (Unit::GetCreature((*me), TeronGUID));
if (!Teron || !Teron->isAlive() || Teron->IsInEvadeMode())
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
CheckTeronTimer = 5000;
} else CheckTeronTimer -= diff;
}
};
struct boss_teron_gorefiendAI : public ScriptedAI
{
boss_teron_gorefiendAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceData();
}
ScriptedInstance* pInstance;
uint32 IncinerateTimer;
uint32 SummonDoomBlossomTimer;
uint32 EnrageTimer;
uint32 CrushingShadowsTimer;
uint32 ShadowOfDeathTimer;
uint32 SummonShadowsTimer;
uint32 RandomYellTimer;
uint32 AggroTimer;
uint64 AggroTargetGUID;
uint64 GhostGUID; // Player that gets killed by Shadow of Death and gets turned into a ghost
bool Intro;
bool Done;
void Reset()
{
if (pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, NOT_STARTED);
IncinerateTimer = 20000 + rand()%11000;
SummonDoomBlossomTimer = 12000;
EnrageTimer = 600000;
CrushingShadowsTimer = 22000;
SummonShadowsTimer = 60000;
RandomYellTimer = 50000;
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
// Start off unattackable so that the intro is done properly
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
AggroTimer = 20000;
AggroTargetGUID = 0;
Intro = false;
Done = false;
}
void EnterCombat(Unit * /*who*/) {}
void MoveInLineOfSight(Unit* pWho)
{
if (!Intro && pWho->GetTypeId() == TYPEID_PLAYER && pWho->isTargetableForAttack() && me->IsHostileTo(pWho) && pWho->isInAccessiblePlaceFor(me))
{
if (me->IsWithinDistInMap(pWho, VISIBLE_RANGE) && me->IsWithinLOSInMap(pWho))
if (CheckTeronTimer <= diff)
{
if (pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, IN_PROGRESS);
me->GetMotionMaster()->Clear(false);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoScriptText(SAY_INTRO, me);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
AggroTargetGUID = pWho->GetGUID();
Intro = true;
}
}
if (Done)
ScriptedAI::MoveInLineOfSight(pWho);
}
void KilledUnit(Unit * /*victim*/)
{
DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me);
}
void JustDied(Unit * /*victim*/)
{
if (pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, DONE);
DoScriptText(SAY_DEATH, me);
}
float CalculateRandomLocation(float Loc, uint32 radius)
{
float coord = Loc;
switch (urand(0,1))
{
case 0:
coord += rand()%radius;
break;
case 1:
coord -= rand()%radius;
break;
}
return coord;
}
void SetThreatList(Creature* Blossom)
{
if (!Blossom) return;
std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList();
std::list<HostileReference*>::const_iterator i = m_threatlist.begin();
for (i = m_threatlist.begin(); i != m_threatlist.end(); ++i)
{
Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid());
if (pUnit && pUnit->isAlive())
{
float threat = DoGetThreat(pUnit);
Blossom->AddThreat(pUnit, threat);
}
}
}
void MindControlGhost()
{
/************************************************************************/
/** NOTE FOR FUTURE DEVELOPER: PROPERLY IMPLEMENT THE GHOST PORTION *****/
/** ONLY AFTER TrinIty FULLY IMPLEMENTS MIND CONTROL ABILITIES *****/
/** THE CURRENT CODE IN THIS FUNCTION IS ONLY THE BEGINNING OF *****/
/** WHAT IS FULLY NECESSARY FOR GOREFIEND TO BE 100% COMPLETE *****/
/************************************************************************/
Unit* Ghost = NULL;
if (GhostGUID)
Ghost = Unit::GetUnit((*me), GhostGUID);
if (Ghost && Ghost->isAlive() && Ghost->HasAura(SPELL_SHADOW_OF_DEATH))
{
/*float x,y,z;
Ghost->GetPosition(x,y,z);
Creature* control = me->SummonCreature(CREATURE_GHOST, x, y, z, 0, TEMPSUMMON_TIMED_DESAWN, 30000);
if (control)
{
CAST_PLR(Ghost)->Possess(control);
Ghost->DealDamage(Ghost, Ghost->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL,
false);
}*/
for (uint8 i = 0; i < 4; ++i)
{
Creature* Construct = NULL;
float X = CalculateRandomLocation(Ghost->GetPositionX(), 10);
float Y = CalculateRandomLocation(Ghost->GetPositionY(), 10);
Construct = me->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, Y, Ghost->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
if (Construct)
if (TeronGUID)
{
Construct->CastSpell(Construct, SPELL_PASSIVE_SHADOWFORM, true);
SetThreatList(Construct); // Use same function as Doom Blossom to set Threat List.
CAST_AI(mob_shadowy_constructAI, Construct->AI())->GhostGUID = GhostGUID;
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (!pTarget) // someone's trying to solo.
pTarget = me->getVictim();
if (pTarget)
Construct->GetMotionMaster()->MoveChase(pTarget);
}
}
}
}
void UpdateAI(const uint32 diff)
{
if (Intro && !Done)
{
if (AggroTimer <= diff)
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
DoScriptText(SAY_AGGRO, me);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
Done = true;
if (AggroTargetGUID)
{
Unit* pUnit = Unit::GetUnit((*me), AggroTargetGUID);
if (pUnit)
AttackStart(pUnit);
DoZoneInCombat();
Creature* Teron = (Unit::GetCreature((*me), TeronGUID));
if ((Teron) && (!Teron->isAlive() || Teron->IsInEvadeMode()))
Despawn();
}
else
{
EnterEvadeMode();
return;
}
} else AggroTimer -= diff;
}
Despawn();
if (!UpdateVictim() || !Done)
CheckTeronTimer = 5000;
} else CheckTeronTimer -= diff;
if (ShadowBoltTimer < diff && me->isInCombat())
{
DoCast(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_SHADOWBOLT);
ShadowBoltTimer = 10000;
} else ShadowBoltTimer -= diff;
return;
if (SummonShadowsTimer <= diff)
{
//MindControlGhost();
for (uint8 i = 0; i < 2; ++i)
{
Creature* Shadow = NULL;
float X = CalculateRandomLocation(me->GetPositionX(), 10);
Shadow = me->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 0);
if (Shadow)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (!pTarget)
pTarget = me->getVictim();
if (pTarget)
Shadow->AI()->AttackStart(pTarget);
}
}
SummonShadowsTimer = 60000;
} else SummonShadowsTimer -= diff;
if (SummonDoomBlossomTimer <= diff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
float X = CalculateRandomLocation(pTarget->GetPositionX(), 20);
float Y = CalculateRandomLocation(pTarget->GetPositionY(), 20);
float Z = pTarget->GetPositionZ();
Z = me->GetMap()->GetHeight(X, Y, Z);
Creature* DoomBlossom = me->SummonCreature(CREATURE_DOOM_BLOSSOM, X, Y, Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
if (DoomBlossom)
{
DoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoomBlossom->setFaction(me->getFaction());
DoomBlossom->AddThreat(pTarget, 1.0f);
CAST_AI(mob_doom_blossomAI, DoomBlossom->AI())->SetTeronGUID(me->GetGUID());
pTarget->CombatStart(DoomBlossom);
SetThreatList(DoomBlossom);
SummonDoomBlossomTimer = 35000;
}
}
} else SummonDoomBlossomTimer -= diff;
if (IncinerateTimer <= diff)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (!pTarget)
pTarget = me->getVictim();
if (pTarget)
{
DoScriptText(RAND(SAY_SPECIAL1,SAY_SPECIAL2), me);
DoCast(pTarget, SPELL_INCINERATE);
IncinerateTimer = 20000 + rand()%31 * 1000;
}
} else IncinerateTimer -= diff;
if (CrushingShadowsTimer <= diff)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (pTarget && pTarget->isAlive())
DoCast(pTarget, SPELL_CRUSHING_SHADOWS);
CrushingShadowsTimer = 10000 + rand()%16 * 1000;
} else CrushingShadowsTimer -= diff;
/*** NOTE FOR FUTURE DEV: UNCOMMENT BELOW ONLY IF MIND CONTROL IS FULLY IMPLEMENTED **/
/*if (ShadowOfDeathTimer <= diff)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (!pTarget)
pTarget = me->getVictim();
if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER)
{
DoCast(pTarget, SPELL_SHADOW_OF_DEATH);
GhostGUID = pTarget->GetGUID();
ShadowOfDeathTimer = 30000;
SummonShadowsTimer = 53000; // Make it VERY close but slightly less so that we can check if the aura is still on the player
}
} else ShadowOfDeathTimer -= diff;*/
if (RandomYellTimer <= diff)
{
DoScriptText(RAND(SAY_SPELL1,SAY_SPELL2), me);
RandomYellTimer = 50000 + rand()%51 * 1000;
} else RandomYellTimer -= diff;
if (!me->HasAura(SPELL_BERSERK))
{
if (EnrageTimer <= diff)
{
DoCast(me, SPELL_BERSERK);
DoScriptText(SAY_ENRAGE, me);
} else EnrageTimer -= diff;
}
DoMeleeAttackIfReady();
void SetTeronGUID(uint64 guid){ TeronGUID = guid; }
};
};
␍class mob_shadowy_construct : public CreatureScript
{
public:
mob_shadowy_construct() : CreatureScript("mob_shadowy_construct") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new mob_shadowy_constructAI(pCreature);
}
struct mob_shadowy_constructAI : public ScriptedAI
{
mob_shadowy_constructAI(Creature* c) : ScriptedAI(c) {}
uint64 GhostGUID;
uint64 TeronGUID;
uint32 CheckPlayerTimer;
uint32 CheckTeronTimer;
void Reset()
{
GhostGUID = 0;
TeronGUID = 0;
CheckPlayerTimer = 2000;
CheckTeronTimer = 5000;
}
void EnterCombat(Unit* /*who*/) {}
void MoveInLineOfSight(Unit *who)
{
if (!who || (!who->isAlive()) || (who->GetGUID() == GhostGUID))
return;
ScriptedAI::MoveInLineOfSight(who);
}
/* Comment it out for now. NOTE TO FUTURE DEV: UNCOMMENT THIS OUT ONLY AFTER MIND CONTROL IS IMPLEMENTED
void DamageTaken(Unit* done_by, uint32 &damage)
{
if (done_by->GetGUID() != GhostGUID)
damage = 0; // Only the ghost can deal damage.
}
*/
void CheckPlayers()
{
std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList();
if (m_threatlist.empty())
return; // No threat list. Don't continue.
std::list<HostileReference*>::const_iterator itr = m_threatlist.begin();
std::list<Unit*> targets;
for (; itr != m_threatlist.end(); ++itr)
{
Unit* pUnit = Unit::GetUnit((*me), (*itr)->getUnitGuid());
if (pUnit && pUnit->isAlive())
targets.push_back(pUnit);
}
targets.sort(Trinity::ObjectDistanceOrderPred(me));
Unit *pTarget = targets.front();
if (pTarget && me->IsWithinDistInMap(pTarget, me->GetAttackDistance(pTarget)))
{
DoCast(pTarget, SPELL_ATROPHY);
me->AI()->AttackStart(pTarget);
}
}
void UpdateAI(const uint32 diff)
{
if (CheckPlayerTimer <= diff)
{
CheckPlayers();
CheckPlayerTimer = 3000;
} else CheckPlayerTimer -= diff;
if (CheckTeronTimer <= diff)
{
Creature* Teron = (Unit::GetCreature((*me), TeronGUID));
if (!Teron || !Teron->isAlive() || Teron->IsInEvadeMode())
me->DealDamage(me, me->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
CheckTeronTimer = 5000;
} else CheckTeronTimer -= diff;
}
};
};
␍class boss_teron_gorefiend : public CreatureScript
{
public:
boss_teron_gorefiend() : CreatureScript("boss_teron_gorefiend") { }
CreatureAI* GetAI(Creature* pCreature) const
{
return new boss_teron_gorefiendAI (pCreature);
}
struct boss_teron_gorefiendAI : public ScriptedAI
{
boss_teron_gorefiendAI(Creature *c) : ScriptedAI(c)
{
pInstance = c->GetInstanceScript();
}
InstanceScript* pInstance;
uint32 IncinerateTimer;
uint32 SummonDoomBlossomTimer;
uint32 EnrageTimer;
uint32 CrushingShadowsTimer;
uint32 ShadowOfDeathTimer;
uint32 SummonShadowsTimer;
uint32 RandomYellTimer;
uint32 AggroTimer;
uint64 AggroTargetGUID;
uint64 GhostGUID; // Player that gets killed by Shadow of Death and gets turned into a ghost
bool Intro;
bool Done;
void Reset()
{
if (pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, NOT_STARTED);
IncinerateTimer = 20000 + rand()%11000;
SummonDoomBlossomTimer = 12000;
EnrageTimer = 600000;
CrushingShadowsTimer = 22000;
SummonShadowsTimer = 60000;
RandomYellTimer = 50000;
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
// Start off unattackable so that the intro is done properly
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
AggroTimer = 20000;
AggroTargetGUID = 0;
Intro = false;
Done = false;
}
void EnterCombat(Unit * /*who*/) {}
void MoveInLineOfSight(Unit* pWho)
{
if (!Intro && pWho->GetTypeId() == TYPEID_PLAYER && pWho->isTargetableForAttack() && me->IsHostileTo(pWho) && pWho->isInAccessiblePlaceFor(me))
{
if (me->IsWithinDistInMap(pWho, VISIBLE_RANGE) && me->IsWithinLOSInMap(pWho))
{
if (pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, IN_PROGRESS);
me->GetMotionMaster()->Clear(false);
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoScriptText(SAY_INTRO, me);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_TALK);
AggroTargetGUID = pWho->GetGUID();
Intro = true;
}
}
if (Done)
ScriptedAI::MoveInLineOfSight(pWho);
}
void KilledUnit(Unit * /*victim*/)
{
DoScriptText(RAND(SAY_SLAY1,SAY_SLAY2), me);
}
void JustDied(Unit * /*victim*/)
{
if (pInstance)
pInstance->SetData(DATA_TERONGOREFIENDEVENT, DONE);
DoScriptText(SAY_DEATH, me);
}
float CalculateRandomLocation(float Loc, uint32 radius)
{
float coord = Loc;
switch (urand(0,1))
{
case 0:
coord += rand()%radius;
break;
case 1:
coord -= rand()%radius;
break;
}
return coord;
}
void SetThreatList(Creature* Blossom)
{
if (!Blossom) return;
std::list<HostileReference*>& m_threatlist = me->getThreatManager().getThreatList();
std::list<HostileReference*>::const_iterator i = m_threatlist.begin();
for (i = m_threatlist.begin(); i != m_threatlist.end(); ++i)
{
Unit* pUnit = Unit::GetUnit((*me), (*i)->getUnitGuid());
if (pUnit && pUnit->isAlive())
{
float threat = DoGetThreat(pUnit);
Blossom->AddThreat(pUnit, threat);
}
}
}
void MindControlGhost()
{
/************************************************************************/
/** NOTE FOR FUTURE DEVELOPER: PROPERLY IMPLEMENT THE GHOST PORTION *****/
/** ONLY AFTER TrinIty FULLY IMPLEMENTS MIND CONTROL ABILITIES *****/
/** THE CURRENT CODE IN THIS FUNCTION IS ONLY THE BEGINNING OF *****/
/** WHAT IS FULLY NECESSARY FOR GOREFIEND TO BE 100% COMPLETE *****/
/************************************************************************/
Unit* Ghost = NULL;
if (GhostGUID)
Ghost = Unit::GetUnit((*me), GhostGUID);
if (Ghost && Ghost->isAlive() && Ghost->HasAura(SPELL_SHADOW_OF_DEATH))
{
/*float x,y,z;
Ghost->GetPosition(x,y,z);
Creature* control = me->SummonCreature(CREATURE_GHOST, x, y, z, 0, TEMPSUMMON_TIMED_DESAWN, 30000);
if (control)
{
CAST_PLR(Ghost)->Possess(control);
Ghost->DealDamage(Ghost, Ghost->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL,
false);
}*/
for (uint8 i = 0; i < 4; ++i)
{
Creature* Construct = NULL;
float X = CalculateRandomLocation(Ghost->GetPositionX(), 10);
float Y = CalculateRandomLocation(Ghost->GetPositionY(), 10);
Construct = me->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, Y, Ghost->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 45000);
if (Construct)
{
Construct->CastSpell(Construct, SPELL_PASSIVE_SHADOWFORM, true);
SetThreatList(Construct); // Use same function as Doom Blossom to set Threat List.
CAST_AI(mob_shadowy_construct::mob_shadowy_constructAI, Construct->AI())->GhostGUID = GhostGUID;
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (!pTarget) // someone's trying to solo.
pTarget = me->getVictim();
if (pTarget)
Construct->GetMotionMaster()->MoveChase(pTarget);
}
}
}
}
void UpdateAI(const uint32 diff)
{
if (Intro && !Done)
{
if (AggroTimer <= diff)
{
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
DoScriptText(SAY_AGGRO, me);
me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE);
Done = true;
if (AggroTargetGUID)
{
Unit* pUnit = Unit::GetUnit((*me), AggroTargetGUID);
if (pUnit)
AttackStart(pUnit);
DoZoneInCombat();
}
else
{
EnterEvadeMode();
return;
}
} else AggroTimer -= diff;
}
if (!UpdateVictim() || !Done)
return;
if (SummonShadowsTimer <= diff)
{
//MindControlGhost();
for (uint8 i = 0; i < 2; ++i)
{
Creature* Shadow = NULL;
float X = CalculateRandomLocation(me->GetPositionX(), 10);
Shadow = me->SummonCreature(CREATURE_SHADOWY_CONSTRUCT, X, me->GetPositionY(), me->GetPositionZ(), 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 0);
if (Shadow)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (!pTarget)
pTarget = me->getVictim();
if (pTarget)
Shadow->AI()->AttackStart(pTarget);
}
}
SummonShadowsTimer = 60000;
} else SummonShadowsTimer -= diff;
if (SummonDoomBlossomTimer <= diff)
{
if (Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
{
float X = CalculateRandomLocation(pTarget->GetPositionX(), 20);
float Y = CalculateRandomLocation(pTarget->GetPositionY(), 20);
float Z = pTarget->GetPositionZ();
Z = me->GetMap()->GetHeight(X, Y, Z);
Creature* DoomBlossom = me->SummonCreature(CREATURE_DOOM_BLOSSOM, X, Y, Z, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
if (DoomBlossom)
{
DoomBlossom->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
DoomBlossom->setFaction(me->getFaction());
DoomBlossom->AddThreat(pTarget, 1.0f);
CAST_AI(mob_doom_blossom::mob_doom_blossomAI, DoomBlossom->AI())->SetTeronGUID(me->GetGUID());
pTarget->CombatStart(DoomBlossom);
SetThreatList(DoomBlossom);
SummonDoomBlossomTimer = 35000;
}
}
} else SummonDoomBlossomTimer -= diff;
if (IncinerateTimer <= diff)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (!pTarget)
pTarget = me->getVictim();
if (pTarget)
{
DoScriptText(RAND(SAY_SPECIAL1,SAY_SPECIAL2), me);
DoCast(pTarget, SPELL_INCINERATE);
IncinerateTimer = 20000 + rand()%31 * 1000;
}
} else IncinerateTimer -= diff;
if (CrushingShadowsTimer <= diff)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
if (pTarget && pTarget->isAlive())
DoCast(pTarget, SPELL_CRUSHING_SHADOWS);
CrushingShadowsTimer = 10000 + rand()%16 * 1000;
} else CrushingShadowsTimer -= diff;
/*** NOTE FOR FUTURE DEV: UNCOMMENT BELOW ONLY IF MIND CONTROL IS FULLY IMPLEMENTED **/
/*if (ShadowOfDeathTimer <= diff)
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (!pTarget)
pTarget = me->getVictim();
if (pTarget && pTarget->isAlive() && pTarget->GetTypeId() == TYPEID_PLAYER)
{
DoCast(pTarget, SPELL_SHADOW_OF_DEATH);
GhostGUID = pTarget->GetGUID();
ShadowOfDeathTimer = 30000;
SummonShadowsTimer = 53000; // Make it VERY close but slightly less so that we can check if the aura is still on the player
}
} else ShadowOfDeathTimer -= diff;*/
if (RandomYellTimer <= diff)
{
DoScriptText(RAND(SAY_SPELL1,SAY_SPELL2), me);
RandomYellTimer = 50000 + rand()%51 * 1000;
} else RandomYellTimer -= diff;
if (!me->HasAura(SPELL_BERSERK))
{
if (EnrageTimer <= diff)
{
DoCast(me, SPELL_BERSERK);
DoScriptText(SAY_ENRAGE, me);
} else EnrageTimer -= diff;
}
DoMeleeAttackIfReady();
}
};
};
CreatureAI* GetAI_mob_doom_blossom(Creature* pCreature)
{
return new mob_doom_blossomAI(pCreature);
}
CreatureAI* GetAI_mob_shadowy_construct(Creature* pCreature)
{
return new mob_shadowy_constructAI(pCreature);
}
CreatureAI* GetAI_boss_teron_gorefiend(Creature* pCreature)
{
return new boss_teron_gorefiendAI (pCreature);
}
void AddSC_boss_teron_gorefiend()
{
Script *newscript;
newscript = new Script;
newscript->Name = "mob_doom_blossom";
newscript->GetAI = &GetAI_mob_doom_blossom;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "mob_shadowy_construct";
newscript->GetAI = &GetAI_mob_shadowy_construct;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_teron_gorefiend";
newscript->GetAI = &GetAI_boss_teron_gorefiend;
newscript->RegisterSelf();
new mob_doom_blossom();
new mob_shadowy_construct();
new boss_teron_gorefiend();
}
@@ -59,170 +59,174 @@ enum eEnums
GCD_CAST = 1,
GCD_YELL = 2
};
struct boss_najentusAI : public ScriptedAI
␍class boss_najentus : public CreatureScript
{
boss_najentusAI(Creature *c) : ScriptedAI(c)
public:
boss_najentus() : CreatureScript("boss_najentus") { }
CreatureAI* GetAI(Creature* pCreature) const
{
pInstance = c->GetInstanceData();
return new boss_najentusAI (pCreature);
}
ScriptedInstance* pInstance;
EventMap events;
uint64 SpineTargetGUID;
void Reset()
struct boss_najentusAI : public ScriptedAI
{
events.Reset();
SpineTargetGUID = 0;
if (pInstance)
pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, NOT_STARTED);
}
void KilledUnit(Unit * /*victim*/)
{
DoScriptText(rand()%2 ? SAY_SLAY1 : SAY_SLAY2, me);
events.DelayEvents(5000, GCD_YELL);
}
void JustDied(Unit * /*victim*/)
{
if (pInstance)
pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, DONE);
DoScriptText(SAY_DEATH, me);
}
void SpellHit(Unit * /*caster*/, const SpellEntry *spell)
{
if (spell->Id == SPELL_HURL_SPINE && me->HasAura(SPELL_TIDAL_SHIELD))
boss_najentusAI(Creature *c) : ScriptedAI(c)
{
me->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD);
DoCast(me, SPELL_TIDAL_BURST, true);
pInstance = c->GetInstanceScript();
}
InstanceScript* pInstance;
EventMap events;
uint64 SpineTargetGUID;
void Reset()
{
events.Reset();
SpineTargetGUID = 0;
if (pInstance)
pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, NOT_STARTED);
}
void KilledUnit(Unit * /*victim*/)
{
DoScriptText(rand()%2 ? SAY_SLAY1 : SAY_SLAY2, me);
events.DelayEvents(5000, GCD_YELL);
}
void JustDied(Unit * /*victim*/)
{
if (pInstance)
pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, DONE);
DoScriptText(SAY_DEATH, me);
}
void SpellHit(Unit * /*caster*/, const SpellEntry *spell)
{
if (spell->Id == SPELL_HURL_SPINE && me->HasAura(SPELL_TIDAL_SHIELD))
{
me->RemoveAurasDueToSpell(SPELL_TIDAL_SHIELD);
DoCast(me, SPELL_TIDAL_BURST, true);
ResetTimer();
}
}
void EnterCombat(Unit * /*who*/)
{
if (pInstance)
pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, IN_PROGRESS);
DoScriptText(SAY_AGGRO, me);
DoZoneInCombat();
events.ScheduleEvent(EVENT_BERSERK, 480000, GCD_CAST);
events.ScheduleEvent(EVENT_YELL, 45000 + (rand()%76)*1000, GCD_YELL);
ResetTimer();
}
}
void EnterCombat(Unit * /*who*/)
bool RemoveImpalingSpine()
{
if (!SpineTargetGUID) return false;
Unit *pTarget = Unit::GetUnit(*me, SpineTargetGUID);
if (pTarget && pTarget->HasAura(SPELL_IMPALING_SPINE))
pTarget->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE);
SpineTargetGUID=0;
return true;
}
void ResetTimer(uint32 inc = 0)
{
events.RescheduleEvent(EVENT_NEEDLE, 10000 + inc, GCD_CAST);
events.RescheduleEvent(EVENT_SPINE, 20000 + inc, GCD_CAST);
events.RescheduleEvent(EVENT_SHIELD, 60000 + inc);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_SHIELD:
DoCast(me, SPELL_TIDAL_SHIELD, true);
ResetTimer(45000);
break;
case EVENT_BERSERK:
DoScriptText(SAY_ENRAGE2, me);
DoCast(me, SPELL_BERSERK, true);
events.DelayEvents(15000, GCD_YELL);
break;
case EVENT_SPINE:
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (!pTarget) pTarget = me->getVictim();
if (pTarget)
{
DoCast(pTarget, SPELL_IMPALING_SPINE, true);
SpineTargetGUID = pTarget->GetGUID();
//must let target summon, otherwise you cannot click the spine
pTarget->SummonGameObject(GOBJECT_SPINE, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), me->GetOrientation(), 0, 0, 0, 0, 30);
DoScriptText(rand()%2 ? SAY_NEEDLE1 : SAY_NEEDLE2, me);
events.DelayEvents(1500, GCD_CAST);
events.DelayEvents(15000, GCD_YELL);
}
events.ScheduleEvent(EVENT_SPINE, 21000, GCD_CAST);
return;
}
case EVENT_NEEDLE:
{
//DoCast(me, SPELL_NEEDLE_SPINE, true);
std::list<Unit*> pTargets;
SelectTargetList(pTargets, 3, SELECT_TARGET_RANDOM, 80, true);
for (std::list<Unit*>::const_iterator i = pTargets.begin(); i != pTargets.end(); ++i)
DoCast(*i, 39835, true);
events.ScheduleEvent(EVENT_NEEDLE, urand(15000,25000), GCD_CAST);
events.DelayEvents(1500, GCD_CAST);
return;
}
case EVENT_YELL:
DoScriptText(RAND(SAY_SPECIAL1, SAY_SPECIAL2), me);
events.ScheduleEvent(EVENT_YELL, urand(25000,100000), GCD_YELL);
events.DelayEvents(15000, GCD_YELL);
break;
}
}
DoMeleeAttackIfReady();
}
};
};
␍class go_najentus_spine : public GameObjectScript
{
public:
go_najentus_spine() : GameObjectScript("go_najentus_spine") { }
bool OnGossipHello(Player* pPlayer, GameObject* pGo)
{
if (pInstance)
pInstance->SetData(DATA_HIGHWARLORDNAJENTUSEVENT, IN_PROGRESS);
DoScriptText(SAY_AGGRO, me);
DoZoneInCombat();
events.ScheduleEvent(EVENT_BERSERK, 480000, GCD_CAST);
events.ScheduleEvent(EVENT_YELL, 45000 + (rand()%76)*1000, GCD_YELL);
ResetTimer();
}
bool RemoveImpalingSpine()
{
if (!SpineTargetGUID) return false;
Unit *pTarget = Unit::GetUnit(*me, SpineTargetGUID);
if (pTarget && pTarget->HasAura(SPELL_IMPALING_SPINE))
pTarget->RemoveAurasDueToSpell(SPELL_IMPALING_SPINE);
SpineTargetGUID=0;
if (InstanceScript* pInstance = pGo->GetInstanceScript())
if (Creature* Najentus = Unit::GetCreature(*pGo, pInstance->GetData64(DATA_HIGHWARLORDNAJENTUS)))
if (CAST_AI(boss_najentus::boss_najentusAI, Najentus->AI())->RemoveImpalingSpine())
{
pPlayer->CastSpell(pPlayer, SPELL_CREATE_NAJENTUS_SPINE, true);
pGo->Delete();
}
return true;
}
void ResetTimer(uint32 inc = 0)
{
events.RescheduleEvent(EVENT_NEEDLE, 10000 + inc, GCD_CAST);
events.RescheduleEvent(EVENT_SPINE, 20000 + inc, GCD_CAST);
events.RescheduleEvent(EVENT_SHIELD, 60000 + inc);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch(eventId)
{
case EVENT_SHIELD:
DoCast(me, SPELL_TIDAL_SHIELD, true);
ResetTimer(45000);
break;
case EVENT_BERSERK:
DoScriptText(SAY_ENRAGE2, me);
DoCast(me, SPELL_BERSERK, true);
events.DelayEvents(15000, GCD_YELL);
break;
case EVENT_SPINE:
{
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
if (!pTarget) pTarget = me->getVictim();
if (pTarget)
{
DoCast(pTarget, SPELL_IMPALING_SPINE, true);
SpineTargetGUID = pTarget->GetGUID();
//must let target summon, otherwise you cannot click the spine
pTarget->SummonGameObject(GOBJECT_SPINE, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), me->GetOrientation(), 0, 0, 0, 0, 30);
DoScriptText(rand()%2 ? SAY_NEEDLE1 : SAY_NEEDLE2, me);
events.DelayEvents(1500, GCD_CAST);
events.DelayEvents(15000, GCD_YELL);
}
events.ScheduleEvent(EVENT_SPINE, 21000, GCD_CAST);
return;
}
case EVENT_NEEDLE:
{
//DoCast(me, SPELL_NEEDLE_SPINE, true);
std::list<Unit*> pTargets;
SelectTargetList(pTargets, 3, SELECT_TARGET_RANDOM, 80, true);
for (std::list<Unit*>::const_iterator i = pTargets.begin(); i != pTargets.end(); ++i)
DoCast(*i, 39835, true);
events.ScheduleEvent(EVENT_NEEDLE, urand(15000,25000), GCD_CAST);
events.DelayEvents(1500, GCD_CAST);
return;
}
case EVENT_YELL:
DoScriptText(RAND(SAY_SPECIAL1, SAY_SPECIAL2), me);
events.ScheduleEvent(EVENT_YELL, urand(25000,100000), GCD_YELL);
events.DelayEvents(15000, GCD_YELL);
break;
}
}
DoMeleeAttackIfReady();
}
};
bool GOHello_go_najentus_spine(Player* pPlayer, GameObject* pGo)
{
if (ScriptedInstance* pInstance = pGo->GetInstanceData())
if (Creature* Najentus = Unit::GetCreature(*pGo, pInstance->GetData64(DATA_HIGHWARLORDNAJENTUS)))
if (CAST_AI(boss_najentusAI, Najentus->AI())->RemoveImpalingSpine())
{
pPlayer->CastSpell(pPlayer, SPELL_CREATE_NAJENTUS_SPINE, true);
pGo->Delete();
}
return true;
}
CreatureAI* GetAI_boss_najentus(Creature* pCreature)
{
return new boss_najentusAI (pCreature);
}
void AddSC_boss_najentus()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_najentus";
newscript->GetAI = &GetAI_boss_najentus;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "go_najentus_spine";
newscript->pGOHello = &GOHello_go_najentus_spine;
newscript->RegisterSelf();
new boss_najentus();
new go_najentus_spine();
}
File diff suppressed because it is too large Load Diff
@@ -39,310 +39,312 @@ EndScriptData */
7 - Illidari Council Event
8 - Illidan Stormrage Event
*/
struct instance_black_temple : public ScriptedInstance
␍class instance_black_temple : public InstanceMapScript
{
instance_black_temple(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
public:
instance_black_temple() : InstanceMapScript("instance_black_temple") { }
uint32 m_auiEncounter[MAX_ENCOUNTER];
std::string str_data;
uint64 Najentus;
uint64 Akama; // This is the Akama that starts the Illidan encounter.
uint64 Akama_Shade; // This is the Akama that starts the Shade of Akama encounter.
uint64 ShadeOfAkama;
uint64 Supremus;
uint64 LadyMalande;
uint64 GathiosTheShatterer;
uint64 HighNethermancerZerevor;
uint64 VerasDarkshadow;
uint64 IllidariCouncil;
uint64 BloodElfCouncilVoice;
uint64 IllidanStormrage;
uint64 NajentusGate;
uint64 MainTempleDoors;
uint64 ShadeOfAkamaDoor;
uint64 CommonDoor;//Teron
uint64 TeronDoor;
uint64 GuurtogDoor;
uint64 MotherDoor;
uint64 TempleDoor;//Befor mother
uint64 CouncilDoor;
uint64 SimpleDoor;//council
uint64 IllidanGate;
uint64 IllidanDoor[2];
void Initialize()
InstanceScript* GetInstanceData_InstanceMapScript(Map* pMap)
{
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
Najentus = 0;
Akama = 0;
Akama_Shade = 0;
ShadeOfAkama = 0;
Supremus = 0;
LadyMalande = 0;
GathiosTheShatterer = 0;
HighNethermancerZerevor = 0;
VerasDarkshadow = 0;
IllidariCouncil = 0;
BloodElfCouncilVoice = 0;
IllidanStormrage = 0;
NajentusGate = 0;
MainTempleDoors = 0;
ShadeOfAkamaDoor= 0;
CommonDoor = 0;//teron
TeronDoor = 0;
GuurtogDoor = 0;
MotherDoor = 0;
TempleDoor = 0;
SimpleDoor = 0;//Bycouncil
CouncilDoor = 0;
IllidanGate = 0;
IllidanDoor[0] = 0;
IllidanDoor[1] = 0;
return new instance_black_temple_InstanceMapScript(pMap);
}
bool IsEncounterInProgress() const
struct instance_black_temple_InstanceMapScript : public InstanceScript
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS) return true;
instance_black_temple_InstanceMapScript(Map* pMap) : InstanceScript(pMap) {Initialize();};
return false;
}
uint32 m_auiEncounter[MAX_ENCOUNTER];
std::string str_data;
Player* GetPlayerInMap()
{
Map::PlayerList const& players = instance->GetPlayers();
uint64 Najentus;
uint64 Akama; // This is the Akama that starts the Illidan encounter.
uint64 Akama_Shade; // This is the Akama that starts the Shade of Akama encounter.
uint64 ShadeOfAkama;
uint64 Supremus;
uint64 LadyMalande;
uint64 GathiosTheShatterer;
uint64 HighNethermancerZerevor;
uint64 VerasDarkshadow;
uint64 IllidariCouncil;
uint64 BloodElfCouncilVoice;
uint64 IllidanStormrage;
if (!players.isEmpty())
uint64 NajentusGate;
uint64 MainTempleDoors;
uint64 ShadeOfAkamaDoor;
uint64 CommonDoor;//Teron
uint64 TeronDoor;
uint64 GuurtogDoor;
uint64 MotherDoor;
uint64 TempleDoor;//Befor mother
uint64 CouncilDoor;
uint64 SimpleDoor;//council
uint64 IllidanGate;
uint64 IllidanDoor[2];
void Initialize()
{
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
Najentus = 0;
Akama = 0;
Akama_Shade = 0;
ShadeOfAkama = 0;
Supremus = 0;
LadyMalande = 0;
GathiosTheShatterer = 0;
HighNethermancerZerevor = 0;
VerasDarkshadow = 0;
IllidariCouncil = 0;
BloodElfCouncilVoice = 0;
IllidanStormrage = 0;
NajentusGate = 0;
MainTempleDoors = 0;
ShadeOfAkamaDoor= 0;
CommonDoor = 0;//teron
TeronDoor = 0;
GuurtogDoor = 0;
MotherDoor = 0;
TempleDoor = 0;
SimpleDoor = 0;//Bycouncil
CouncilDoor = 0;
IllidanGate = 0;
IllidanDoor[0] = 0;
IllidanDoor[1] = 0;
}
bool IsEncounterInProgress() const
{
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS) return true;
return false;
}
Player* GetPlayerInMap()
{
Map::PlayerList const& players = instance->GetPlayers();
if (!players.isEmpty())
{
if (Player* plr = itr->getSource())
return plr;
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
{
if (Player* plr = itr->getSource())
return plr;
}
}
sLog.outDebug("TSCR: Instance Black Temple: GetPlayerInMap, but PlayerList is empty!");
return NULL;
}
void OnCreatureCreate(Creature* pCreature, bool /*add*/)
{
switch(pCreature->GetEntry())
{
case 22887: Najentus = pCreature->GetGUID(); break;
case 23089: Akama = pCreature->GetGUID(); break;
case 22990: Akama_Shade = pCreature->GetGUID(); break;
case 22841: ShadeOfAkama = pCreature->GetGUID(); break;
case 22898: Supremus = pCreature->GetGUID(); break;
case 22917: IllidanStormrage = pCreature->GetGUID(); break;
case 22949: GathiosTheShatterer = pCreature->GetGUID(); break;
case 22950: HighNethermancerZerevor = pCreature->GetGUID(); break;
case 22951: LadyMalande = pCreature->GetGUID(); break;
case 22952: VerasDarkshadow = pCreature->GetGUID(); break;
case 23426: IllidariCouncil = pCreature->GetGUID(); break;
case 23499: BloodElfCouncilVoice = pCreature->GetGUID(); break;
}
}
sLog.outDebug("TSCR: Instance Black Temple: GetPlayerInMap, but PlayerList is empty!");
return NULL;
}
void OnCreatureCreate(Creature* pCreature, bool /*add*/)
{
switch(pCreature->GetEntry())
void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
{
case 22887: Najentus = pCreature->GetGUID(); break;
case 23089: Akama = pCreature->GetGUID(); break;
case 22990: Akama_Shade = pCreature->GetGUID(); break;
case 22841: ShadeOfAkama = pCreature->GetGUID(); break;
case 22898: Supremus = pCreature->GetGUID(); break;
case 22917: IllidanStormrage = pCreature->GetGUID(); break;
case 22949: GathiosTheShatterer = pCreature->GetGUID(); break;
case 22950: HighNethermancerZerevor = pCreature->GetGUID(); break;
case 22951: LadyMalande = pCreature->GetGUID(); break;
case 22952: VerasDarkshadow = pCreature->GetGUID(); break;
case 23426: IllidariCouncil = pCreature->GetGUID(); break;
case 23499: BloodElfCouncilVoice = pCreature->GetGUID(); break;
}
}
void OnGameObjectCreate(GameObject* pGo, bool /*add*/)
{
switch(pGo->GetEntry())
{
case 185483: NajentusGate = pGo->GetGUID();// Gate past Naj'entus (at the entrance to Supermoose's courtyards)
if (m_auiEncounter[0] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185882: MainTempleDoors = pGo->GetGUID();// Main Temple Doors - right past Supermoose (Supremus)
if (m_auiEncounter[1] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185478: ShadeOfAkamaDoor = pGo->GetGUID();break;
case 185480: CommonDoor = pGo->GetGUID();
if (m_auiEncounter[3] == DONE)HandleGameObject(NULL,true,pGo);break;
case 186153: TeronDoor = pGo->GetGUID();
if (m_auiEncounter[3] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185892: GuurtogDoor = pGo->GetGUID();
if (m_auiEncounter[4] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185479: TempleDoor = pGo->GetGUID();
if (m_auiEncounter[5] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185482: MotherDoor = pGo->GetGUID();
if (m_auiEncounter[6] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185481: CouncilDoor = pGo->GetGUID();
if (m_auiEncounter[7] == DONE)HandleGameObject(NULL,true,pGo);break;
case 186152: SimpleDoor = pGo->GetGUID();
if (m_auiEncounter[7] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185905: IllidanGate = pGo->GetGUID(); break; // Gate leading to Temple Summit
case 186261: IllidanDoor[0] = pGo->GetGUID(); break; // Right door at Temple Summit
case 186262: IllidanDoor[1] = pGo->GetGUID(); break; // Left door at Temple Summit
}
}
uint64 GetData64(uint32 identifier)
{
switch(identifier)
{
case DATA_HIGHWARLORDNAJENTUS: return Najentus;
case DATA_AKAMA: return Akama;
case DATA_AKAMA_SHADE: return Akama_Shade;
case DATA_SHADEOFAKAMA: return ShadeOfAkama;
case DATA_SUPREMUS: return Supremus;
case DATA_ILLIDANSTORMRAGE: return IllidanStormrage;
case DATA_GATHIOSTHESHATTERER: return GathiosTheShatterer;
case DATA_HIGHNETHERMANCERZEREVOR: return HighNethermancerZerevor;
case DATA_LADYMALANDE: return LadyMalande;
case DATA_VERASDARKSHADOW: return VerasDarkshadow;
case DATA_ILLIDARICOUNCIL: return IllidariCouncil;
case DATA_GAMEOBJECT_NAJENTUS_GATE: return NajentusGate;
case DATA_GAMEOBJECT_ILLIDAN_GATE: return IllidanGate;
case DATA_GAMEOBJECT_ILLIDAN_DOOR_R: return IllidanDoor[0];
case DATA_GAMEOBJECT_ILLIDAN_DOOR_L: return IllidanDoor[1];
case DATA_GAMEOBJECT_SUPREMUS_DOORS: return MainTempleDoors;
case DATA_BLOOD_ELF_COUNCIL_VOICE: return BloodElfCouncilVoice;
switch(pGo->GetEntry())
{
case 185483: NajentusGate = pGo->GetGUID();// Gate past Naj'entus (at the entrance to Supermoose's courtyards)
if (m_auiEncounter[0] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185882: MainTempleDoors = pGo->GetGUID();// Main Temple Doors - right past Supermoose (Supremus)
if (m_auiEncounter[1] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185478: ShadeOfAkamaDoor = pGo->GetGUID();break;
case 185480: CommonDoor = pGo->GetGUID();
if (m_auiEncounter[3] == DONE)HandleGameObject(NULL,true,pGo);break;
case 186153: TeronDoor = pGo->GetGUID();
if (m_auiEncounter[3] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185892: GuurtogDoor = pGo->GetGUID();
if (m_auiEncounter[4] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185479: TempleDoor = pGo->GetGUID();
if (m_auiEncounter[5] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185482: MotherDoor = pGo->GetGUID();
if (m_auiEncounter[6] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185481: CouncilDoor = pGo->GetGUID();
if (m_auiEncounter[7] == DONE)HandleGameObject(NULL,true,pGo);break;
case 186152: SimpleDoor = pGo->GetGUID();
if (m_auiEncounter[7] == DONE)HandleGameObject(NULL,true,pGo);break;
case 185905: IllidanGate = pGo->GetGUID(); break; // Gate leading to Temple Summit
case 186261: IllidanDoor[0] = pGo->GetGUID(); break; // Right door at Temple Summit
case 186262: IllidanDoor[1] = pGo->GetGUID(); break; // Left door at Temple Summit
}
}
return 0;
}
void SetData(uint32 type, uint32 data)
{
switch(type)
uint64 GetData64(uint32 identifier)
{
case DATA_HIGHWARLORDNAJENTUSEVENT:
switch(identifier)
{
case DATA_HIGHWARLORDNAJENTUS: return Najentus;
case DATA_AKAMA: return Akama;
case DATA_AKAMA_SHADE: return Akama_Shade;
case DATA_SHADEOFAKAMA: return ShadeOfAkama;
case DATA_SUPREMUS: return Supremus;
case DATA_ILLIDANSTORMRAGE: return IllidanStormrage;
case DATA_GATHIOSTHESHATTERER: return GathiosTheShatterer;
case DATA_HIGHNETHERMANCERZEREVOR: return HighNethermancerZerevor;
case DATA_LADYMALANDE: return LadyMalande;
case DATA_VERASDARKSHADOW: return VerasDarkshadow;
case DATA_ILLIDARICOUNCIL: return IllidariCouncil;
case DATA_GAMEOBJECT_NAJENTUS_GATE: return NajentusGate;
case DATA_GAMEOBJECT_ILLIDAN_GATE: return IllidanGate;
case DATA_GAMEOBJECT_ILLIDAN_DOOR_R: return IllidanDoor[0];
case DATA_GAMEOBJECT_ILLIDAN_DOOR_L: return IllidanDoor[1];
case DATA_GAMEOBJECT_SUPREMUS_DOORS: return MainTempleDoors;
case DATA_BLOOD_ELF_COUNCIL_VOICE: return BloodElfCouncilVoice;
}
return 0;
}
void SetData(uint32 type, uint32 data)
{
switch(type)
{
case DATA_HIGHWARLORDNAJENTUSEVENT:
if (data == DONE)
{
HandleGameObject(NajentusGate, true);
}
m_auiEncounter[0] = data;break;
case DATA_SUPREMUSEVENT:
if (data == DONE)
{
HandleGameObject(NajentusGate, true);
}
m_auiEncounter[1] = data; break;
case DATA_SHADEOFAKAMAEVENT:
if (data == IN_PROGRESS)
{
HandleGameObject(ShadeOfAkamaDoor, false);
} else HandleGameObject(ShadeOfAkamaDoor, true);
m_auiEncounter[2] = data; break;
case DATA_TERONGOREFIENDEVENT:
if (data == IN_PROGRESS)
{
HandleGameObject(TeronDoor, false);
HandleGameObject(CommonDoor, false);
}else
{
HandleGameObject(TeronDoor, true);
HandleGameObject(CommonDoor, true);
}
m_auiEncounter[3] = data; break;
case DATA_GURTOGGBLOODBOILEVENT:
if (data == DONE)
{
HandleGameObject(GuurtogDoor, true);
}
m_auiEncounter[4] = data; break;
case DATA_RELIQUARYOFSOULSEVENT:
if (data == DONE)
{
HandleGameObject(TempleDoor, true);
}
m_auiEncounter[5] = data; break;
case DATA_MOTHERSHAHRAZEVENT:
if (data == DONE)
{
HandleGameObject(MotherDoor, true);
}
m_auiEncounter[6] = data; break;
case DATA_ILLIDARICOUNCILEVENT:
if (data == IN_PROGRESS)
{
HandleGameObject(CouncilDoor, false);
HandleGameObject(SimpleDoor, false);
}else
{
HandleGameObject(CouncilDoor, true);
HandleGameObject(SimpleDoor, true);
}
m_auiEncounter[7] = data; break;
case DATA_ILLIDANSTORMRAGEEVENT: m_auiEncounter[8] = data; break;
}
if (data == DONE)
{
HandleGameObject(NajentusGate, true);
OUT_SAVE_INST_DATA;
std::ostringstream saveStream;
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
<< m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4]
<< " " << m_auiEncounter[5] << " " << m_auiEncounter[6] << " " << m_auiEncounter[7]
<< " " << m_auiEncounter[8];
str_data = saveStream.str();
SaveToDB();
OUT_SAVE_INST_DATA_COMPLETE;
}
m_auiEncounter[0] = data;break;
case DATA_SUPREMUSEVENT:
if (data == DONE)
{
HandleGameObject(NajentusGate, true);
}
m_auiEncounter[1] = data; break;
case DATA_SHADEOFAKAMAEVENT:
if (data == IN_PROGRESS)
{
HandleGameObject(ShadeOfAkamaDoor, false);
} else HandleGameObject(ShadeOfAkamaDoor, true);
m_auiEncounter[2] = data; break;
case DATA_TERONGOREFIENDEVENT:
if (data == IN_PROGRESS)
{
HandleGameObject(TeronDoor, false);
HandleGameObject(CommonDoor, false);
}else
{
HandleGameObject(TeronDoor, true);
HandleGameObject(CommonDoor, true);
}
m_auiEncounter[3] = data; break;
case DATA_GURTOGGBLOODBOILEVENT:
if (data == DONE)
{
HandleGameObject(GuurtogDoor, true);
}
m_auiEncounter[4] = data; break;
case DATA_RELIQUARYOFSOULSEVENT:
if (data == DONE)
{
HandleGameObject(TempleDoor, true);
}
m_auiEncounter[5] = data; break;
case DATA_MOTHERSHAHRAZEVENT:
if (data == DONE)
{
HandleGameObject(MotherDoor, true);
}
m_auiEncounter[6] = data; break;
case DATA_ILLIDARICOUNCILEVENT:
if (data == IN_PROGRESS)
{
HandleGameObject(CouncilDoor, false);
HandleGameObject(SimpleDoor, false);
}else
{
HandleGameObject(CouncilDoor, true);
HandleGameObject(SimpleDoor, true);
}
m_auiEncounter[7] = data; break;
case DATA_ILLIDANSTORMRAGEEVENT: m_auiEncounter[8] = data; break;
}
if (data == DONE)
uint32 GetData(uint32 type)
{
OUT_SAVE_INST_DATA;
switch(type)
{
case DATA_HIGHWARLORDNAJENTUSEVENT: return m_auiEncounter[0];
case DATA_SUPREMUSEVENT: return m_auiEncounter[1];
case DATA_SHADEOFAKAMAEVENT: return m_auiEncounter[2];
case DATA_TERONGOREFIENDEVENT: return m_auiEncounter[3];
case DATA_GURTOGGBLOODBOILEVENT: return m_auiEncounter[4];
case DATA_RELIQUARYOFSOULSEVENT: return m_auiEncounter[5];
case DATA_MOTHERSHAHRAZEVENT: return m_auiEncounter[6];
case DATA_ILLIDARICOUNCILEVENT: return m_auiEncounter[7];
case DATA_ILLIDANSTORMRAGEEVENT: return m_auiEncounter[8];
}
std::ostringstream saveStream;
saveStream << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
<< m_auiEncounter[2] << " " << m_auiEncounter[3] << " " << m_auiEncounter[4]
<< " " << m_auiEncounter[5] << " " << m_auiEncounter[6] << " " << m_auiEncounter[7]
<< " " << m_auiEncounter[8];
str_data = saveStream.str();
SaveToDB();
OUT_SAVE_INST_DATA_COMPLETE;
return 0;
}
}
uint32 GetData(uint32 type)
{
switch(type)
std::string GetSaveData()
{
case DATA_HIGHWARLORDNAJENTUSEVENT: return m_auiEncounter[0];
case DATA_SUPREMUSEVENT: return m_auiEncounter[1];
case DATA_SHADEOFAKAMAEVENT: return m_auiEncounter[2];
case DATA_TERONGOREFIENDEVENT: return m_auiEncounter[3];
case DATA_GURTOGGBLOODBOILEVENT: return m_auiEncounter[4];
case DATA_RELIQUARYOFSOULSEVENT: return m_auiEncounter[5];
case DATA_MOTHERSHAHRAZEVENT: return m_auiEncounter[6];
case DATA_ILLIDARICOUNCILEVENT: return m_auiEncounter[7];
case DATA_ILLIDANSTORMRAGEEVENT: return m_auiEncounter[8];
return str_data;
}
return 0;
}
std::string GetSaveData()
{
return str_data;
}
void Load(const char* in)
{
if (!in)
void Load(const char* in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
if (!in)
{
OUT_LOAD_INST_DATA_FAIL;
return;
}
OUT_LOAD_INST_DATA(in);
std::istringstream loadStream(in);
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2]
>> m_auiEncounter[3] >> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6]
>> m_auiEncounter[7] >> m_auiEncounter[8];
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
OUT_LOAD_INST_DATA(in);
std::istringstream loadStream(in);
loadStream >> m_auiEncounter[0] >> m_auiEncounter[1] >> m_auiEncounter[2]
>> m_auiEncounter[3] >> m_auiEncounter[4] >> m_auiEncounter[5] >> m_auiEncounter[6]
>> m_auiEncounter[7] >> m_auiEncounter[8];
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
if (m_auiEncounter[i] == IN_PROGRESS)
m_auiEncounter[i] = NOT_STARTED;
OUT_LOAD_INST_DATA_COMPLETE;
}
};
InstanceData* GetInstanceData_instance_black_temple(Map* pMap)
{
return new instance_black_temple(pMap);
}
void AddSC_instance_black_temple()
{
Script *newscript;
newscript = new Script;
newscript->Name = "instance_black_temple";
newscript->GetInstanceData = &GetInstanceData_instance_black_temple;
newscript->RegisterSelf();
new instance_black_temple();
}