*Integrate Script system to Core
-added ScriptMgr for loading scripts -removed bindings -moved script system to src/game -moved scripts to src/scripts -VC project files updated -cmakes updated (not 100% done yet) NOTE to Devs: -file locations changed -precompiled renamed to ScriptedPch -ecsort_ai renamed to ScriptedEscortAI -follower_ai renamed to ScriptedFollowerAI -guard_ai renamed to ScriptedGuardAI -simple_ai renamed to ScriptedSimpleAI -sc_creature renamed to ScriptedCreature -sc_gossip renamed to ScriptedGossip -sc_instance renamed to ScriptedInstance *use the new headers in scripts, thank you NOTE to ALL: cmake not fully tested, please report any errors with it could make creashes, incompability USE AT YOUR OWN RISK before further tests!! --HG-- branch : trunk
This commit is contained in:
@@ -0,0 +1,432 @@
|
||||
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss General Bjarngrim
|
||||
SD%Complete: 70%
|
||||
SDComment: Waypoint needed, we expect boss to always have 2x Stormforged Lieutenant following
|
||||
SDCategory: Halls of Lightning
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "halls_of_lightning.h"
|
||||
|
||||
enum eEnums
|
||||
{
|
||||
//Yell
|
||||
SAY_AGGRO = -1602000,
|
||||
SAY_SLAY_1 = -1602001,
|
||||
SAY_SLAY_2 = -1602002,
|
||||
SAY_SLAY_3 = -1602003,
|
||||
SAY_DEATH = -1602004,
|
||||
SAY_BATTLE_STANCE = -1602005,
|
||||
EMOTE_BATTLE_STANCE = -1602006,
|
||||
SAY_BERSEKER_STANCE = -1602007,
|
||||
EMOTE_BERSEKER_STANCE = -1602008,
|
||||
SAY_DEFENSIVE_STANCE = -1602009,
|
||||
EMOTE_DEFENSIVE_STANCE = -1602010,
|
||||
|
||||
SPELL_DEFENSIVE_STANCE = 53790,
|
||||
//SPELL_DEFENSIVE_AURA = 41105,
|
||||
SPELL_SPELL_REFLECTION = 36096,
|
||||
SPELL_PUMMEL = 12555,
|
||||
SPELL_KNOCK_AWAY = 52029,
|
||||
SPELL_IRONFORM = 52022,
|
||||
|
||||
SPELL_BERSEKER_STANCE = 53791,
|
||||
//SPELL_BERSEKER_AURA = 41107,
|
||||
SPELL_INTERCEPT = 58769,
|
||||
SPELL_WHIRLWIND = 52027,
|
||||
SPELL_CLEAVE = 15284,
|
||||
|
||||
SPELL_BATTLE_STANCE = 53792,
|
||||
//SPELL_BATTLE_AURA = 41106,
|
||||
SPELL_MORTAL_STRIKE = 16856,
|
||||
SPELL_SLAM = 52026,
|
||||
|
||||
//OTHER SPELLS
|
||||
//SPELL_CHARGE_UP = 52098, // only used when starting walk from one platform to the other
|
||||
//SPELL_TEMPORARY_ELECTRICAL_CHARGE = 52092, // triggered part of above
|
||||
|
||||
NPC_STORMFORGED_LIEUTENANT = 29240,
|
||||
SPELL_ARC_WELD = 59085,
|
||||
SPELL_RENEW_STEEL_N = 52774,
|
||||
SPELL_RENEW_STEEL_H = 59160,
|
||||
|
||||
EQUIP_SWORD = 37871,
|
||||
EQUIP_SHIELD = 35642,
|
||||
EQUIP_MACE = 43623,
|
||||
|
||||
STANCE_DEFENSIVE = 0,
|
||||
STANCE_BERSERKER = 1,
|
||||
STANCE_BATTLE = 2
|
||||
};
|
||||
|
||||
/*######
|
||||
## boss_bjarngrim
|
||||
######*/
|
||||
|
||||
struct TRINITY_DLL_DECL boss_bjarngrimAI : public ScriptedAI
|
||||
{
|
||||
boss_bjarngrimAI(Creature *pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
m_uiStance = STANCE_DEFENSIVE;
|
||||
memset(&m_auiStormforgedLieutenantGUID, 0, sizeof(m_auiStormforgedLieutenantGUID));
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
bool m_bIsChangingStance;
|
||||
|
||||
uint8 m_uiChargingStatus;
|
||||
uint8 m_uiStance;
|
||||
|
||||
uint32 m_uiCharge_Timer;
|
||||
uint32 m_uiChangeStance_Timer;
|
||||
|
||||
uint32 m_uiReflection_Timer;
|
||||
uint32 m_uiKnockAway_Timer;
|
||||
uint32 m_uiPummel_Timer;
|
||||
uint32 m_uiIronform_Timer;
|
||||
|
||||
uint32 m_uiIntercept_Timer;
|
||||
uint32 m_uiWhirlwind_Timer;
|
||||
uint32 m_uiCleave_Timer;
|
||||
|
||||
uint32 m_uiMortalStrike_Timer;
|
||||
uint32 m_uiSlam_Timer;
|
||||
|
||||
uint64 m_auiStormforgedLieutenantGUID[2];
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_bIsChangingStance = false;
|
||||
|
||||
m_uiChargingStatus = 0;
|
||||
m_uiCharge_Timer = 1000;
|
||||
|
||||
m_uiChangeStance_Timer = 20000 + rand()%5000;
|
||||
|
||||
m_uiReflection_Timer = 8000;
|
||||
m_uiKnockAway_Timer = 20000;
|
||||
m_uiPummel_Timer = 10000;
|
||||
m_uiIronform_Timer = 25000;
|
||||
|
||||
m_uiIntercept_Timer = 5000;
|
||||
m_uiWhirlwind_Timer = 10000;
|
||||
m_uiCleave_Timer = 8000;
|
||||
|
||||
m_uiMortalStrike_Timer = 8000;
|
||||
m_uiSlam_Timer = 10000;
|
||||
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
{
|
||||
if (Creature* pStormforgedLieutenant = (Unit::GetCreature((*m_creature), m_auiStormforgedLieutenantGUID[i])))
|
||||
{
|
||||
if (!pStormforgedLieutenant->isAlive())
|
||||
pStormforgedLieutenant->Respawn();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_uiStance != STANCE_DEFENSIVE)
|
||||
{
|
||||
DoRemoveStanceAura(m_uiStance);
|
||||
DoCast(m_creature, SPELL_DEFENSIVE_STANCE);
|
||||
m_uiStance = STANCE_DEFENSIVE;
|
||||
}
|
||||
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_BJARNGRIM, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* pWho)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
|
||||
//must get both lieutenants here and make sure they are with him
|
||||
m_creature->CallForHelp(30.0f);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_BJARNGRIM, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, m_creature);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_BJARNGRIM, DONE);
|
||||
}
|
||||
|
||||
//TODO: remove when removal is done by mangos
|
||||
void DoRemoveStanceAura(uint8 uiStance)
|
||||
{
|
||||
switch(uiStance)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
m_creature->RemoveAurasDueToSpell(SPELL_DEFENSIVE_STANCE);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
m_creature->RemoveAurasDueToSpell(SPELL_BERSEKER_STANCE);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
m_creature->RemoveAurasDueToSpell(SPELL_BATTLE_STANCE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
// Change stance
|
||||
if (m_uiChangeStance_Timer <= uiDiff)
|
||||
{
|
||||
//wait for current spell to finish before change stance
|
||||
if (m_creature->IsNonMeleeSpellCasted(false))
|
||||
return;
|
||||
|
||||
DoRemoveStanceAura(m_uiStance);
|
||||
|
||||
int uiTempStance = rand()%(3-1);
|
||||
|
||||
if (uiTempStance >= m_uiStance)
|
||||
++uiTempStance;
|
||||
|
||||
m_uiStance = uiTempStance;
|
||||
|
||||
switch(m_uiStance)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
DoScriptText(SAY_DEFENSIVE_STANCE, m_creature);
|
||||
DoScriptText(EMOTE_DEFENSIVE_STANCE, m_creature);
|
||||
DoCast(m_creature, SPELL_DEFENSIVE_STANCE);
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SHIELD, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
case STANCE_BERSERKER:
|
||||
DoScriptText(SAY_BERSEKER_STANCE, m_creature);
|
||||
DoScriptText(EMOTE_BERSEKER_STANCE, m_creature);
|
||||
DoCast(m_creature, SPELL_BERSEKER_STANCE);
|
||||
SetEquipmentSlots(false, EQUIP_SWORD, EQUIP_SWORD, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
case STANCE_BATTLE:
|
||||
DoScriptText(SAY_BATTLE_STANCE, m_creature);
|
||||
DoScriptText(EMOTE_BATTLE_STANCE, m_creature);
|
||||
DoCast(m_creature, SPELL_BATTLE_STANCE);
|
||||
SetEquipmentSlots(false, EQUIP_MACE, EQUIP_UNEQUIP, EQUIP_NO_CHANGE);
|
||||
break;
|
||||
}
|
||||
|
||||
m_uiChangeStance_Timer = 20000 + rand()%5000;
|
||||
return;
|
||||
}
|
||||
else
|
||||
m_uiChangeStance_Timer -= uiDiff;
|
||||
|
||||
switch(m_uiStance)
|
||||
{
|
||||
case STANCE_DEFENSIVE:
|
||||
{
|
||||
if (m_uiReflection_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature, SPELL_SPELL_REFLECTION);
|
||||
m_uiReflection_Timer = 8000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiReflection_Timer -= uiDiff;
|
||||
|
||||
if (m_uiKnockAway_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature, SPELL_KNOCK_AWAY);
|
||||
m_uiKnockAway_Timer = 20000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiKnockAway_Timer -= uiDiff;
|
||||
|
||||
if (m_uiPummel_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), SPELL_PUMMEL);
|
||||
m_uiPummel_Timer = 10000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiPummel_Timer -= uiDiff;
|
||||
|
||||
if (m_uiIronform_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature, SPELL_IRONFORM);
|
||||
m_uiIronform_Timer = 25000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiIronform_Timer -= uiDiff;
|
||||
|
||||
break;
|
||||
}
|
||||
case STANCE_BERSERKER:
|
||||
{
|
||||
if (m_uiIntercept_Timer <= uiDiff)
|
||||
{
|
||||
//not much point is this, better random target and more often?
|
||||
DoCast(m_creature->getVictim(), SPELL_INTERCEPT);
|
||||
m_uiIntercept_Timer = 45000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiIntercept_Timer -= uiDiff;
|
||||
|
||||
if (m_uiWhirlwind_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature, SPELL_WHIRLWIND);
|
||||
m_uiWhirlwind_Timer = 10000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiWhirlwind_Timer -= uiDiff;
|
||||
|
||||
if (m_uiCleave_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), SPELL_CLEAVE);
|
||||
m_uiCleave_Timer = 8000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiCleave_Timer -= uiDiff;
|
||||
|
||||
break;
|
||||
}
|
||||
case STANCE_BATTLE:
|
||||
{
|
||||
if (m_uiMortalStrike_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), SPELL_MORTAL_STRIKE);
|
||||
m_uiMortalStrike_Timer = 20000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiMortalStrike_Timer -= uiDiff;
|
||||
|
||||
if (m_uiSlam_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), SPELL_SLAM);
|
||||
m_uiSlam_Timer = 15000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiSlam_Timer -= uiDiff;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
## mob_stormforged_lieutenant
|
||||
######*/
|
||||
|
||||
struct TRINITY_DLL_DECL mob_stormforged_lieutenantAI : public ScriptedAI
|
||||
{
|
||||
mob_stormforged_lieutenantAI(Creature *pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 m_uiArcWeld_Timer;
|
||||
uint32 m_uiRenewSteel_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_uiArcWeld_Timer = 20000 + rand()%1000;
|
||||
m_uiRenewSteel_Timer = 10000 + rand()%1000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* pWho)
|
||||
{
|
||||
if (m_pInstance)
|
||||
{
|
||||
if (Creature* pBjarngrim = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_BJARNGRIM)))
|
||||
{
|
||||
if (pBjarngrim->isAlive() && !pBjarngrim->getVictim())
|
||||
pBjarngrim->AI()->AttackStart(pWho);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (m_uiArcWeld_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), SPELL_ARC_WELD);
|
||||
m_uiArcWeld_Timer = 20000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiArcWeld_Timer -= uiDiff;
|
||||
|
||||
if (m_uiRenewSteel_Timer <= uiDiff)
|
||||
{
|
||||
if (m_pInstance)
|
||||
{
|
||||
if (Creature* pBjarngrim = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_BJARNGRIM)))
|
||||
{
|
||||
if (pBjarngrim->isAlive())
|
||||
DoCast(pBjarngrim, DUNGEON_MODE(SPELL_RENEW_STEEL_N, SPELL_RENEW_STEEL_H));
|
||||
}
|
||||
}
|
||||
m_uiRenewSteel_Timer = 10000 + rand()%4000;
|
||||
}
|
||||
else
|
||||
m_uiRenewSteel_Timer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_bjarngrim(Creature* pCreature)
|
||||
{
|
||||
return new boss_bjarngrimAI(pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_mob_stormforged_lieutenant(Creature* pCreature)
|
||||
{
|
||||
return new mob_stormforged_lieutenantAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_bjarngrim()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_bjarngrim";
|
||||
newscript->GetAI = &GetAI_boss_bjarngrim;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_stormforged_lieutenant";
|
||||
newscript->GetAI = &GetAI_mob_stormforged_lieutenant;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,380 @@
|
||||
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss Ionar
|
||||
SD%Complete: 80%
|
||||
SDComment: Timer check
|
||||
SDCategory: Halls of Lightning
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "halls_of_lightning.h"
|
||||
|
||||
enum eEnums
|
||||
{
|
||||
SAY_AGGRO = -1602011,
|
||||
SAY_SLAY_1 = -1602012,
|
||||
SAY_SLAY_2 = -1602013,
|
||||
SAY_SLAY_3 = -1602014,
|
||||
SAY_DEATH = -1602015,
|
||||
SAY_SPLIT_1 = -1602016,
|
||||
SAY_SPLIT_2 = -1602017,
|
||||
|
||||
SPELL_BALL_LIGHTNING_N = 52780,
|
||||
SPELL_BALL_LIGHTNING_H = 59800,
|
||||
SPELL_STATIC_OVERLOAD_N = 52658,
|
||||
SPELL_STATIC_OVERLOAD_H = 59795,
|
||||
|
||||
SPELL_DISPERSE = 52770,
|
||||
SPELL_SUMMON_SPARK = 52746,
|
||||
SPELL_SPARK_DESPAWN = 52776,
|
||||
|
||||
//Spark of Ionar
|
||||
SPELL_SPARK_VISUAL_TRIGGER_N = 52667,
|
||||
SPELL_SPARK_VISUAL_TRIGGER_H = 59833,
|
||||
|
||||
NPC_SPARK_OF_IONAR = 28926,
|
||||
|
||||
MAX_SPARKS = 5,
|
||||
POINT_CALLBACK = 0
|
||||
};
|
||||
|
||||
/*######
|
||||
## Boss Ionar
|
||||
######*/
|
||||
|
||||
struct TRINITY_DLL_DECL boss_ionarAI : public ScriptedAI
|
||||
{
|
||||
boss_ionarAI(Creature *pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
std::list<uint64> m_lSparkGUIDList;
|
||||
|
||||
bool m_bIsSplitPhase;
|
||||
uint32 m_uiSplit_Timer;
|
||||
uint32 m_uiSparkAtHomeCount;
|
||||
|
||||
uint32 m_uiStaticOverload_Timer;
|
||||
uint32 m_uiBallLightning_Timer;
|
||||
|
||||
uint32 m_uiHealthAmountModifier;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_lSparkGUIDList.clear();
|
||||
|
||||
m_bIsSplitPhase = true;
|
||||
m_uiSplit_Timer = 25000;
|
||||
m_uiSparkAtHomeCount = 0;
|
||||
|
||||
m_uiStaticOverload_Timer = 5000 + rand()%1000;
|
||||
m_uiBallLightning_Timer = 10000 + rand()%1000;
|
||||
|
||||
m_uiHealthAmountModifier = 1;
|
||||
|
||||
if (m_creature->GetVisibility() == VISIBILITY_OFF)
|
||||
m_creature->SetVisibility(VISIBILITY_ON);
|
||||
}
|
||||
|
||||
void AttackedBy(Unit* pAttacker)
|
||||
{
|
||||
if (m_creature->getVictim())
|
||||
return;
|
||||
|
||||
if (m_creature->GetVisibility() == VISIBILITY_OFF)
|
||||
return;
|
||||
|
||||
AttackStart(pAttacker);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_IONAR, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustReachedHome()
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_IONAR, NOT_STARTED);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* pWho)
|
||||
{
|
||||
if (m_creature->Attack(pWho, true))
|
||||
{
|
||||
m_creature->AddThreat(pWho, 0.0f);
|
||||
m_creature->SetInCombatWith(pWho);
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
|
||||
if (m_creature->GetVisibility() != VISIBILITY_OFF)
|
||||
m_creature->GetMotionMaster()->MoveChase(pWho);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, m_creature);
|
||||
DespawnSpark();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_IONAR, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
|
||||
}
|
||||
|
||||
void DespawnSpark()
|
||||
{
|
||||
if (m_lSparkGUIDList.empty())
|
||||
return;
|
||||
|
||||
for (std::list<uint64>::iterator itr = m_lSparkGUIDList.begin(); itr != m_lSparkGUIDList.end(); ++itr)
|
||||
{
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, *itr))
|
||||
{
|
||||
if (pTemp->isAlive())
|
||||
pTemp->ForcedDespawn();
|
||||
}
|
||||
}
|
||||
|
||||
m_lSparkGUIDList.clear();
|
||||
}
|
||||
|
||||
//make sparks come back
|
||||
void CallBackSparks()
|
||||
{
|
||||
//should never be empty here, but check
|
||||
if (m_lSparkGUIDList.empty())
|
||||
return;
|
||||
|
||||
for (std::list<uint64>::iterator itr = m_lSparkGUIDList.begin(); itr != m_lSparkGUIDList.end(); ++itr)
|
||||
{
|
||||
if (Creature* pSpark = Unit::GetCreature(*m_creature, *itr))
|
||||
{
|
||||
if (pSpark->isAlive())
|
||||
{
|
||||
if (pSpark->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||
pSpark->GetMotionMaster()->MovementExpired();
|
||||
|
||||
pSpark->SetSpeed(MOVE_RUN, pSpark->GetCreatureInfo()->speed * 2);
|
||||
pSpark->GetMotionMaster()->MovePoint(POINT_CALLBACK, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RegisterSparkAtHome()
|
||||
{
|
||||
++m_uiSparkAtHomeCount;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned)
|
||||
{
|
||||
if (pSummoned->GetEntry() == NPC_SPARK_OF_IONAR)
|
||||
{
|
||||
pSummoned->CastSpell(pSummoned, DUNGEON_MODE(SPELL_SPARK_VISUAL_TRIGGER_N,SPELL_SPARK_VISUAL_TRIGGER_H), true);
|
||||
|
||||
Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
|
||||
|
||||
if (m_creature->getVictim())
|
||||
pSummoned->AI()->AttackStart(pTarget ? pTarget : m_creature->getVictim());
|
||||
|
||||
m_lSparkGUIDList.push_back(pSummoned->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
// Splitted
|
||||
if (m_creature->GetVisibility() == VISIBILITY_OFF)
|
||||
{
|
||||
/*if (!m_creature->getVictim())
|
||||
{
|
||||
Reset();
|
||||
return;
|
||||
}*/
|
||||
|
||||
if (m_uiSplit_Timer <= uiDiff)
|
||||
{
|
||||
m_uiSplit_Timer = 2500;
|
||||
|
||||
// Return sparks to where Ionar splitted
|
||||
if (m_bIsSplitPhase)
|
||||
{
|
||||
CallBackSparks();
|
||||
m_bIsSplitPhase = false;
|
||||
}
|
||||
// Lightning effect and restore Ionar
|
||||
else if (m_uiSparkAtHomeCount == MAX_SPARKS)
|
||||
{
|
||||
m_creature->SetVisibility(VISIBILITY_ON);
|
||||
DoCast(m_creature, SPELL_SPARK_DESPAWN, false);
|
||||
|
||||
DespawnSpark();
|
||||
|
||||
m_uiSparkAtHomeCount = 0;
|
||||
m_uiSplit_Timer = 25000;
|
||||
m_bIsSplitPhase = true;
|
||||
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
|
||||
{
|
||||
if (m_creature->getVictim())
|
||||
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
m_uiSplit_Timer -= uiDiff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (m_uiStaticOverload_Timer <= uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(pTarget, DUNGEON_MODE(SPELL_STATIC_OVERLOAD_N, SPELL_STATIC_OVERLOAD_H));
|
||||
|
||||
m_uiStaticOverload_Timer = 5000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiStaticOverload_Timer -= uiDiff;
|
||||
|
||||
if (m_uiBallLightning_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_BALL_LIGHTNING_N, SPELL_BALL_LIGHTNING_H));
|
||||
m_uiBallLightning_Timer = 10000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiBallLightning_Timer -= uiDiff;
|
||||
|
||||
// Health check
|
||||
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(20*m_uiHealthAmountModifier)))
|
||||
{
|
||||
++m_uiHealthAmountModifier;
|
||||
|
||||
DoScriptText(RAND(SAY_SPLIT_1,SAY_SPLIT_2), m_creature);
|
||||
|
||||
if (m_creature->IsNonMeleeSpellCasted(false))
|
||||
m_creature->InterruptNonMeleeSpells(false);
|
||||
|
||||
DoCast(m_creature, SPELL_DISPERSE);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_ionar(Creature* pCreature)
|
||||
{
|
||||
return new boss_ionarAI(pCreature);
|
||||
}
|
||||
|
||||
bool EffectDummyCreature_boss_ionar(Unit* pCaster, uint32 uiSpellId, uint32 uiEffIndex, Creature* pCreatureTarget)
|
||||
{
|
||||
//always check spellid and effectindex
|
||||
if (uiSpellId == SPELL_DISPERSE && uiEffIndex == 0)
|
||||
{
|
||||
if (pCreatureTarget->GetEntry() != NPC_IONAR)
|
||||
return true;
|
||||
|
||||
for (uint8 i = 0; i < MAX_SPARKS; ++i)
|
||||
pCreatureTarget->CastSpell(pCreatureTarget, SPELL_SUMMON_SPARK, true);
|
||||
|
||||
pCreatureTarget->AttackStop();
|
||||
pCreatureTarget->SetVisibility(VISIBILITY_OFF);
|
||||
|
||||
if (pCreatureTarget->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||
pCreatureTarget->GetMotionMaster()->MovementExpired();
|
||||
|
||||
//always return true when we are handling this spell and effect
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*######
|
||||
## mob_spark_of_ionar
|
||||
######*/
|
||||
|
||||
struct TRINITY_DLL_DECL mob_spark_of_ionarAI : public ScriptedAI
|
||||
{
|
||||
mob_spark_of_ionarAI(Creature *pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
void Reset() { }
|
||||
|
||||
void MovementInform(uint32 uiType, uint32 uiPointId)
|
||||
{
|
||||
if (uiType != POINT_MOTION_TYPE || !m_pInstance)
|
||||
return;
|
||||
|
||||
if (uiPointId == POINT_CALLBACK)
|
||||
{
|
||||
if (Creature* pIonar = m_pInstance->instance->GetCreature(m_pInstance->GetData64(DATA_IONAR)))
|
||||
{
|
||||
if (!pIonar->isAlive())
|
||||
{
|
||||
m_creature->ForcedDespawn();
|
||||
return;
|
||||
}
|
||||
|
||||
if (boss_ionarAI* pIonarAI = dynamic_cast<boss_ionarAI*>(pIonar->AI()))
|
||||
pIonarAI->RegisterSparkAtHome();
|
||||
}
|
||||
else
|
||||
m_creature->ForcedDespawn();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_mob_spark_of_ionar(Creature* pCreature)
|
||||
{
|
||||
return new mob_spark_of_ionarAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_ionar()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_ionar";
|
||||
newscript->GetAI = &GetAI_boss_ionar;
|
||||
newscript->pEffectDummyCreature = &EffectDummyCreature_boss_ionar;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_spark_of_ionar";
|
||||
newscript->GetAI = &GetAI_mob_spark_of_ionar;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss Loken
|
||||
SD%Complete: 60%
|
||||
SDComment: Missing intro. Remove hack of Pulsing Shockwave when core supports. Aura is not working (59414)
|
||||
SDCategory: Halls of Lightning
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "halls_of_lightning.h"
|
||||
|
||||
#define MAX_ENCOUNTER_TIME 2 * 60 * 1000
|
||||
|
||||
enum eEnums
|
||||
{
|
||||
ACHIEVEMENT_TIMELY_DEATH = 1867,
|
||||
|
||||
SAY_AGGRO = -1602018,
|
||||
SAY_INTRO_1 = -1602019,
|
||||
SAY_INTRO_2 = -1602020,
|
||||
SAY_SLAY_1 = -1602021,
|
||||
SAY_SLAY_2 = -1602022,
|
||||
SAY_SLAY_3 = -1602023,
|
||||
SAY_DEATH = -1602024,
|
||||
SAY_NOVA_1 = -1602025,
|
||||
SAY_NOVA_2 = -1602026,
|
||||
SAY_NOVA_3 = -1602027,
|
||||
SAY_75HEALTH = -1602028,
|
||||
SAY_50HEALTH = -1602029,
|
||||
SAY_25HEALTH = -1602030,
|
||||
EMOTE_NOVA = -1602031,
|
||||
|
||||
SPELL_ARC_LIGHTNING = 52921,
|
||||
SPELL_LIGHTNING_NOVA_N = 52960,
|
||||
SPELL_LIGHTNING_NOVA_H = 59835,
|
||||
|
||||
SPELL_PULSING_SHOCKWAVE_N = 52961,
|
||||
SPELL_PULSING_SHOCKWAVE_H = 59836,
|
||||
SPELL_PULSING_SHOCKWAVE_AURA = 59414
|
||||
};
|
||||
|
||||
/*######
|
||||
## Boss Loken
|
||||
######*/
|
||||
|
||||
struct TRINITY_DLL_DECL boss_lokenAI : public ScriptedAI
|
||||
{
|
||||
boss_lokenAI(Creature* pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
bool m_bIsAura;
|
||||
|
||||
uint32 m_uiArcLightning_Timer;
|
||||
uint32 m_uiLightningNova_Timer;
|
||||
uint32 m_uiPulsingShockwave_Timer;
|
||||
uint32 m_uiResumePulsingShockwave_Timer;
|
||||
|
||||
uint32 m_uiHealthAmountModifier;
|
||||
|
||||
uint32 EncounterTime;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_bIsAura = false;
|
||||
|
||||
m_uiArcLightning_Timer = 15000;
|
||||
m_uiLightningNova_Timer = 20000;
|
||||
m_uiPulsingShockwave_Timer = 2000;
|
||||
m_uiResumePulsingShockwave_Timer = 15000;
|
||||
|
||||
m_uiHealthAmountModifier = 1;
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LOKEN, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* pWho)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
|
||||
EncounterTime = 0;
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LOKEN, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, m_creature);
|
||||
|
||||
if (IsHeroic() && EncounterTime <= MAX_ENCOUNTER_TIME)
|
||||
{
|
||||
AchievementEntry const *AchievTimelyDeath = GetAchievementStore()->LookupEntry(ACHIEVEMENT_TIMELY_DEATH);
|
||||
if (AchievTimelyDeath)
|
||||
{
|
||||
Map* pMap = m_creature->GetMap();
|
||||
if (pMap && pMap->IsDungeon())
|
||||
{
|
||||
Map::PlayerList const &players = pMap->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
itr->getSource()->CompletedAchievement(AchievTimelyDeath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LOKEN, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
EncounterTime += uiDiff;
|
||||
|
||||
if (m_bIsAura)
|
||||
{
|
||||
// workaround for PULSING_SHOCKWAVE
|
||||
if (m_uiPulsingShockwave_Timer <= uiDiff)
|
||||
{
|
||||
Map* pMap = m_creature->GetMap();
|
||||
if (pMap->IsDungeon())
|
||||
{
|
||||
Map::PlayerList const &PlayerList = pMap->GetPlayers();
|
||||
|
||||
if (PlayerList.isEmpty())
|
||||
return;
|
||||
|
||||
for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
|
||||
if (i->getSource() && i->getSource()->isAlive() && i->getSource()->isTargetableForAttack())
|
||||
{
|
||||
int32 dmg;
|
||||
float m_fDist = m_creature->GetExactDist(i->getSource()->GetPositionX(), i->getSource()->GetPositionY(), i->getSource()->GetPositionZ());
|
||||
|
||||
dmg = DUNGEON_MODE(100, 150); // need to correct damage
|
||||
if (m_fDist > 1.0f) // Further from 1 yard
|
||||
dmg *= m_fDist;
|
||||
|
||||
m_creature->CastCustomSpell(i->getSource(), DUNGEON_MODE(52942, 59837), &dmg, 0, 0, false);
|
||||
}
|
||||
}
|
||||
m_uiPulsingShockwave_Timer = 2000;
|
||||
} else m_uiPulsingShockwave_Timer -= uiDiff;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_uiResumePulsingShockwave_Timer <= uiDiff)
|
||||
{
|
||||
//breaks at movement, can we assume when it's time, this spell is casted and also must stop movement?
|
||||
DoCast(m_creature, SPELL_PULSING_SHOCKWAVE_AURA, true);
|
||||
|
||||
DoCast(m_creature, DUNGEON_MODE(SPELL_PULSING_SHOCKWAVE_N, SPELL_PULSING_SHOCKWAVE_H)); // need core support
|
||||
m_bIsAura = true;
|
||||
m_uiResumePulsingShockwave_Timer = 0;
|
||||
}
|
||||
else
|
||||
m_uiResumePulsingShockwave_Timer -= uiDiff;
|
||||
}
|
||||
|
||||
if (m_uiArcLightning_Timer <= uiDiff)
|
||||
{
|
||||
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
|
||||
DoCast(pTarget, SPELL_ARC_LIGHTNING);
|
||||
|
||||
m_uiArcLightning_Timer = 15000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiArcLightning_Timer -= uiDiff;
|
||||
|
||||
if (m_uiLightningNova_Timer <= uiDiff)
|
||||
{
|
||||
DoScriptText(RAND(SAY_NOVA_1,SAY_NOVA_2,SAY_NOVA_3), m_creature);
|
||||
DoScriptText(EMOTE_NOVA, m_creature);
|
||||
DoCast(m_creature, DUNGEON_MODE(SPELL_LIGHTNING_NOVA_N, SPELL_LIGHTNING_NOVA_H));
|
||||
|
||||
m_bIsAura = false;
|
||||
m_uiResumePulsingShockwave_Timer = DUNGEON_MODE(5000, 4000); // Pause Pulsing Shockwave aura
|
||||
m_uiLightningNova_Timer = 20000 + rand()%1000;
|
||||
}
|
||||
else
|
||||
m_uiLightningNova_Timer -= uiDiff;
|
||||
|
||||
// Health check
|
||||
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(25*m_uiHealthAmountModifier)))
|
||||
{
|
||||
switch(m_uiHealthAmountModifier)
|
||||
{
|
||||
case 1: DoScriptText(SAY_75HEALTH, m_creature); break;
|
||||
case 2: DoScriptText(SAY_50HEALTH, m_creature); break;
|
||||
case 3: DoScriptText(SAY_25HEALTH, m_creature); break;
|
||||
}
|
||||
|
||||
++m_uiHealthAmountModifier;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_loken(Creature* pCreature)
|
||||
{
|
||||
return new boss_lokenAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_loken()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_loken";
|
||||
newscript->GetAI = &GetAI_boss_loken;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,478 @@
|
||||
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Boss Volkhan
|
||||
SD%Complete: 60%
|
||||
SDComment: Not considered complete. Some events may fail and need further development
|
||||
SDCategory: Halls of Lightning
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "halls_of_lightning.h"
|
||||
|
||||
enum eEnums
|
||||
{
|
||||
SAY_AGGRO = -1602032,
|
||||
SAY_SLAY_1 = -1602033,
|
||||
SAY_SLAY_2 = -1602034,
|
||||
SAY_SLAY_3 = -1602035,
|
||||
SAY_DEATH = -1602036,
|
||||
SAY_STOMP_1 = -1602037,
|
||||
SAY_STOMP_2 = -1602038,
|
||||
SAY_FORGE_1 = -1602039,
|
||||
SAY_FORGE_2 = -1602040,
|
||||
EMOTE_TO_ANVIL = -1602041,
|
||||
EMOTE_SHATTER = -1602042,
|
||||
|
||||
SPELL_HEAT_N = 52387,
|
||||
SPELL_HEAT_H = 59528,
|
||||
SPELL_SHATTERING_STOMP_N = 52237,
|
||||
SPELL_SHATTERING_STOMP_H = 59529,
|
||||
|
||||
//unclear how "directions" of spells must be. Last, summoning GO, what is it for? Script depend on:
|
||||
SPELL_TEMPER = 52238, //TARGET_SCRIPT boss->anvil
|
||||
SPELL_TEMPER_DUMMY = 52654, //TARGET_SCRIPT anvil->boss
|
||||
|
||||
//SPELL_TEMPER_VISUAL = 52661, //summons GO
|
||||
|
||||
SPELL_SUMMON_MOLTEN_GOLEM = 52405,
|
||||
|
||||
//Molten Golem
|
||||
SPELL_BLAST_WAVE = 23113,
|
||||
SPELL_IMMOLATION_STRIKE_N = 52433,
|
||||
SPELL_IMMOLATION_STRIKE_H = 59530,
|
||||
SPELL_SHATTER_N = 52429,
|
||||
SPELL_SHATTER_H = 59527,
|
||||
|
||||
NPC_VOLKHAN_ANVIL = 28823,
|
||||
NPC_MOLTEN_GOLEM = 28695,
|
||||
NPC_BRITTLE_GOLEM = 28681,
|
||||
|
||||
POINT_ID_ANVIL = 0,
|
||||
MAX_GOLEM = 2,
|
||||
|
||||
ACHIEVEMENT_SHATTER_RESISTANT = 2042
|
||||
};
|
||||
|
||||
/*######
|
||||
## Boss Volkhan
|
||||
######*/
|
||||
|
||||
struct TRINITY_DLL_DECL boss_volkhanAI : public ScriptedAI
|
||||
{
|
||||
boss_volkhanAI(Creature *pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
std::list<uint64> m_lGolemGUIDList;
|
||||
|
||||
bool m_bHasTemper;
|
||||
bool m_bIsStriking;
|
||||
bool m_bCanShatterGolem;
|
||||
|
||||
uint8 GolemsShattered;
|
||||
uint32 m_uiPause_Timer;
|
||||
uint32 m_uiShatteringStomp_Timer;
|
||||
uint32 m_uiShatter_Timer;
|
||||
|
||||
uint32 m_uiHealthAmountModifier;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_bIsStriking = false;
|
||||
m_bHasTemper = false;
|
||||
m_bCanShatterGolem = false;
|
||||
|
||||
m_uiPause_Timer = 3500;
|
||||
m_uiShatteringStomp_Timer = 0;
|
||||
m_uiShatter_Timer = 5000;
|
||||
GolemsShattered = 0;
|
||||
|
||||
m_uiHealthAmountModifier = 1;
|
||||
|
||||
DespawnGolem();
|
||||
m_lGolemGUIDList.clear();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VOLKHAN, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* pWho)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VOLKHAN, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void AttackStart(Unit* pWho)
|
||||
{
|
||||
if (m_creature->Attack(pWho, true))
|
||||
{
|
||||
m_creature->AddThreat(pWho, 0.0f);
|
||||
m_creature->SetInCombatWith(pWho);
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
|
||||
if (!m_bHasTemper)
|
||||
m_creature->GetMotionMaster()->MoveChase(pWho);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* pKiller)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, m_creature);
|
||||
DespawnGolem();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_VOLKHAN, DONE);
|
||||
|
||||
if (IsHeroic() && GolemsShattered < 5)
|
||||
{
|
||||
AchievementEntry const *AchievShatterResistant = GetAchievementStore()->LookupEntry(ACHIEVEMENT_SHATTER_RESISTANT);
|
||||
if (AchievShatterResistant)
|
||||
{
|
||||
Map* pMap = m_creature->GetMap();
|
||||
if (pMap && pMap->IsDungeon())
|
||||
{
|
||||
Map::PlayerList const &players = pMap->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
itr->getSource()->CompletedAchievement(AchievShatterResistant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KilledUnit(Unit* pVictim)
|
||||
{
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
|
||||
}
|
||||
|
||||
void DespawnGolem()
|
||||
{
|
||||
if (m_lGolemGUIDList.empty())
|
||||
return;
|
||||
|
||||
for (std::list<uint64>::iterator itr = m_lGolemGUIDList.begin(); itr != m_lGolemGUIDList.end(); ++itr)
|
||||
{
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, *itr))
|
||||
{
|
||||
if (pTemp->isAlive())
|
||||
pTemp->ForcedDespawn();
|
||||
}
|
||||
}
|
||||
|
||||
m_lGolemGUIDList.clear();
|
||||
}
|
||||
|
||||
void ShatterGolem()
|
||||
{
|
||||
if (m_lGolemGUIDList.empty())
|
||||
return;
|
||||
|
||||
for (std::list<uint64>::iterator itr = m_lGolemGUIDList.begin(); itr != m_lGolemGUIDList.end(); ++itr)
|
||||
{
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, *itr))
|
||||
{
|
||||
// only shatter brittle golems
|
||||
if (pTemp->isAlive() && pTemp->GetEntry() == NPC_BRITTLE_GOLEM)
|
||||
{
|
||||
pTemp->CastSpell(pTemp, DUNGEON_MODE(SPELL_SHATTER_N, SPELL_SHATTER_H), false);
|
||||
GolemsShattered += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
|
||||
{
|
||||
if (pSpell->Id == SPELL_TEMPER_DUMMY)
|
||||
m_bIsStriking = true;
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned)
|
||||
{
|
||||
if (pSummoned->GetEntry() == NPC_MOLTEN_GOLEM)
|
||||
{
|
||||
m_lGolemGUIDList.push_back(pSummoned->GetGUID());
|
||||
|
||||
if (Unit* pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0))
|
||||
pSummoned->AI()->AttackStart(pTarget);
|
||||
|
||||
//why healing when just summoned?
|
||||
pSummoned->CastSpell(pSummoned, DUNGEON_MODE(SPELL_HEAT_N, SPELL_HEAT_H), false, NULL, NULL, m_creature->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (m_bIsStriking)
|
||||
{
|
||||
if (m_uiPause_Timer <= uiDiff)
|
||||
{
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() != TARGETED_MOTION_TYPE)
|
||||
{
|
||||
if (m_creature->getVictim())
|
||||
m_creature->GetMotionMaster()->MoveChase(m_creature->getVictim());
|
||||
}
|
||||
|
||||
m_bHasTemper = false;
|
||||
m_bIsStriking = false;
|
||||
m_uiPause_Timer = 3500;
|
||||
}
|
||||
else
|
||||
m_uiPause_Timer -= uiDiff;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// When to start shatter? After 60, 40 or 20% hp?
|
||||
if (!m_bHasTemper && m_uiHealthAmountModifier >= 3)
|
||||
{
|
||||
if (m_uiShatteringStomp_Timer <= uiDiff)
|
||||
{
|
||||
//should he stomp even if he has no brittle golem to shatter?
|
||||
|
||||
DoScriptText(RAND(SAY_STOMP_1,SAY_STOMP_2), m_creature);
|
||||
|
||||
DoCast(m_creature, DUNGEON_MODE(SPELL_SHATTERING_STOMP_N, SPELL_SHATTERING_STOMP_H));
|
||||
|
||||
DoScriptText(EMOTE_SHATTER, m_creature);
|
||||
|
||||
m_uiShatteringStomp_Timer = 30000;
|
||||
m_bCanShatterGolem = true;
|
||||
}
|
||||
else
|
||||
m_uiShatteringStomp_Timer -= uiDiff;
|
||||
}
|
||||
|
||||
// Shatter Golems 3 seconds after Shattering Stomp
|
||||
if (m_bCanShatterGolem)
|
||||
{
|
||||
if (m_uiShatter_Timer <= uiDiff)
|
||||
{
|
||||
ShatterGolem();
|
||||
m_uiShatter_Timer = 3000;
|
||||
m_bCanShatterGolem = false;
|
||||
}
|
||||
else
|
||||
m_uiShatter_Timer -= uiDiff;
|
||||
}
|
||||
|
||||
// Health check
|
||||
if (!m_bCanShatterGolem && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < (100-(20*m_uiHealthAmountModifier)))
|
||||
{
|
||||
++m_uiHealthAmountModifier;
|
||||
|
||||
if (m_creature->IsNonMeleeSpellCasted(false))
|
||||
m_creature->InterruptNonMeleeSpells(false);
|
||||
|
||||
DoScriptText(RAND(SAY_FORGE_1,SAY_FORGE_2), m_creature);
|
||||
|
||||
m_bHasTemper = true;
|
||||
|
||||
DoCast(m_creature, SPELL_TEMPER, false);
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_volkhan(Creature* pCreature)
|
||||
{
|
||||
return new boss_volkhanAI(pCreature);
|
||||
}
|
||||
|
||||
bool EffectDummyCreature_boss_volkhan(Unit* pCaster, uint32 uiSpellId, uint32 uiEffIndex, Creature* pCreatureTarget)
|
||||
{
|
||||
//always check spellid and effectindex
|
||||
if (uiSpellId == SPELL_TEMPER_DUMMY && uiEffIndex == 0)
|
||||
{
|
||||
if (pCaster->GetEntry() != NPC_VOLKHAN_ANVIL || pCreatureTarget->GetEntry() != NPC_VOLKHAN)
|
||||
return true;
|
||||
|
||||
for (uint8 i = 0; i < MAX_GOLEM; ++i)
|
||||
{
|
||||
pCreatureTarget->CastSpell(pCaster, SPELL_SUMMON_MOLTEN_GOLEM, true);
|
||||
}
|
||||
|
||||
//always return true when we are handling this spell and effect
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*######
|
||||
## npc_volkhan_anvil
|
||||
######*/
|
||||
|
||||
bool EffectDummyCreature_npc_volkhan_anvil(Unit* pCaster, uint32 uiSpellId, uint32 uiEffIndex, Creature* pCreatureTarget)
|
||||
{
|
||||
//always check spellid and effectindex
|
||||
if (uiSpellId == SPELL_TEMPER && uiEffIndex == 0)
|
||||
{
|
||||
if (pCaster->GetEntry() != NPC_VOLKHAN || pCreatureTarget->GetEntry() != NPC_VOLKHAN_ANVIL)
|
||||
return true;
|
||||
|
||||
Creature *cre = CAST_CRE(pCaster);
|
||||
|
||||
DoScriptText(EMOTE_TO_ANVIL, pCaster);
|
||||
|
||||
float fX, fY, fZ;
|
||||
pCreatureTarget->GetContactPoint(pCaster, fX, fY, fZ, INTERACTION_DISTANCE);
|
||||
|
||||
pCaster->AttackStop();
|
||||
|
||||
if (pCaster->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||
pCaster->GetMotionMaster()->MovementExpired();
|
||||
|
||||
cre->GetMap()->CreatureRelocation(cre, fX, fY, fZ, pCreatureTarget->GetOrientation());
|
||||
cre->SendMonsterMove(fX, fY, fZ, 0, cre->GetUnitMovementFlags(), 1);
|
||||
|
||||
pCreatureTarget->CastSpell(pCaster, SPELL_TEMPER_DUMMY, false);
|
||||
|
||||
//always return true when we are handling this spell and effect
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*######
|
||||
## mob_molten_golem
|
||||
######*/
|
||||
|
||||
struct TRINITY_DLL_DECL mob_molten_golemAI : public ScriptedAI
|
||||
{
|
||||
mob_molten_golemAI(Creature *pCreature) : ScriptedAI(pCreature)
|
||||
{
|
||||
}
|
||||
|
||||
bool m_bIsFrozen;
|
||||
|
||||
uint32 m_uiBlast_Timer;
|
||||
uint32 m_uiDeathDelay_Timer;
|
||||
uint32 m_uiImmolation_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
m_bIsFrozen = false;
|
||||
|
||||
m_uiBlast_Timer = 20000;
|
||||
m_uiDeathDelay_Timer = 0;
|
||||
m_uiImmolation_Timer = 5000;
|
||||
}
|
||||
|
||||
void AttackStart(Unit* pWho)
|
||||
{
|
||||
if (m_creature->Attack(pWho, true))
|
||||
{
|
||||
m_creature->AddThreat(pWho, 0.0f);
|
||||
m_creature->SetInCombatWith(pWho);
|
||||
pWho->SetInCombatWith(m_creature);
|
||||
|
||||
if (!m_bIsFrozen)
|
||||
m_creature->GetMotionMaster()->MoveChase(pWho);
|
||||
}
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* pDoneBy, uint32 &uiDamage)
|
||||
{
|
||||
if (uiDamage > m_creature->GetHealth())
|
||||
{
|
||||
m_creature->UpdateEntry(NPC_BRITTLE_GOLEM);
|
||||
m_creature->SetHealth(1);
|
||||
uiDamage = 0;
|
||||
m_creature->RemoveAllAuras();
|
||||
m_creature->AttackStop();
|
||||
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
if (m_creature->IsNonMeleeSpellCasted(false))
|
||||
m_creature->InterruptNonMeleeSpells(false);
|
||||
if (m_creature->GetMotionMaster()->GetCurrentMovementGeneratorType() == TARGETED_MOTION_TYPE)
|
||||
m_creature->GetMotionMaster()->MovementExpired();
|
||||
m_bIsFrozen = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SpellHit(Unit* pCaster, const SpellEntry* pSpell)
|
||||
{
|
||||
//this is the dummy effect of the spells
|
||||
if (pSpell->Id == SPELL_SHATTER_N || pSpell->Id == SPELL_SHATTER_H)
|
||||
{
|
||||
if (m_creature->GetEntry() == NPC_BRITTLE_GOLEM)
|
||||
m_creature->ForcedDespawn();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 uiDiff)
|
||||
{
|
||||
//Return since we have no target or if we are frozen
|
||||
if (!UpdateVictim() || m_bIsFrozen)
|
||||
return;
|
||||
|
||||
if (m_uiBlast_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature, SPELL_BLAST_WAVE);
|
||||
m_uiBlast_Timer = 20000;
|
||||
}
|
||||
else
|
||||
m_uiBlast_Timer -= uiDiff;
|
||||
|
||||
if (m_uiImmolation_Timer <= uiDiff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_IMMOLATION_STRIKE_N, SPELL_IMMOLATION_STRIKE_H));
|
||||
m_uiImmolation_Timer = 5000;
|
||||
}
|
||||
else
|
||||
m_uiImmolation_Timer -= uiDiff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_mob_molten_golem(Creature* pCreature)
|
||||
{
|
||||
return new mob_molten_golemAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_volkhan()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_volkhan";
|
||||
newscript->GetAI = &GetAI_boss_volkhan;
|
||||
newscript->pEffectDummyCreature = &EffectDummyCreature_boss_volkhan;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "npc_volkhan_anvil";
|
||||
newscript->pEffectDummyCreature = &EffectDummyCreature_npc_volkhan_anvil;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_molten_golem";
|
||||
newscript->GetAI = &GetAI_mob_molten_golem;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
||||
* This program is free software licensed under GPL version 2
|
||||
* Please see the included DOCS/LICENSE.TXT for more information */
|
||||
|
||||
#ifndef DEF_HALLS_OF_LIGHTNING_H
|
||||
#define DEF_HALLS_OF_LIGHTNING_H
|
||||
|
||||
enum eTypes
|
||||
{
|
||||
MAX_ENCOUNTER = 4,
|
||||
|
||||
DATA_BJARNGRIM = 1,
|
||||
DATA_IONAR = 2,
|
||||
DATA_LOKEN = 3,
|
||||
DATA_VOLKHAN = 4,
|
||||
|
||||
TYPE_BJARNGRIM = 10,
|
||||
TYPE_IONAR = 11,
|
||||
TYPE_LOKEN = 12,
|
||||
TYPE_VOLKHAN = 13,
|
||||
|
||||
NPC_BJARNGRIM = 28586,
|
||||
NPC_VOLKHAN = 28587,
|
||||
NPC_IONAR = 28546,
|
||||
NPC_LOKEN = 28923,
|
||||
|
||||
GO_BJARNGRIM_DOOR = 191416, //_doors10
|
||||
GO_VOLKHAN_DOOR = 191325, //_doors07
|
||||
GO_IONAR_DOOR = 191326, //_doors05
|
||||
GO_LOKEN_DOOR = 191324, //_doors02
|
||||
GO_LOKEN_THRONE = 192654
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,237 @@
|
||||
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Instance_Halls_of_Lightning
|
||||
SD%Complete: 90%
|
||||
SDComment: All ready.
|
||||
SDCategory: Halls of Lightning
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "halls_of_lightning.h"
|
||||
|
||||
/* Halls of Lightning encounters:
|
||||
0 - General Bjarngrim
|
||||
1 - Volkhan
|
||||
2 - Ionar
|
||||
3 - Loken
|
||||
*/
|
||||
|
||||
struct TRINITY_DLL_DECL instance_halls_of_lightning : public ScriptedInstance
|
||||
{
|
||||
instance_halls_of_lightning(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
|
||||
uint64 m_uiGeneralBjarngrimGUID;
|
||||
uint64 m_uiIonarGUID;
|
||||
uint64 m_uiLokenGUID;
|
||||
uint64 m_uiVolkhanGUID;
|
||||
|
||||
uint64 m_uiBjarngrimDoorGUID;
|
||||
uint64 m_uiVolkhanDoorGUID;
|
||||
uint64 m_uiIonarDoorGUID;
|
||||
uint64 m_uiLokenDoorGUID;
|
||||
uint64 m_uiLokenGlobeGUID;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
|
||||
m_uiGeneralBjarngrimGUID = 0;
|
||||
m_uiVolkhanGUID = 0;
|
||||
m_uiIonarGUID = 0;
|
||||
m_uiLokenGUID = 0;
|
||||
|
||||
m_uiBjarngrimDoorGUID = 0;
|
||||
m_uiVolkhanDoorGUID = 0;
|
||||
m_uiIonarDoorGUID = 0;
|
||||
m_uiLokenDoorGUID = 0;
|
||||
m_uiLokenGlobeGUID = 0;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature, bool add)
|
||||
{
|
||||
switch(pCreature->GetEntry())
|
||||
{
|
||||
case NPC_BJARNGRIM:
|
||||
m_uiGeneralBjarngrimGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_VOLKHAN:
|
||||
m_uiVolkhanGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_IONAR:
|
||||
m_uiIonarGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_LOKEN:
|
||||
m_uiLokenGUID = pCreature->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo, bool add)
|
||||
{
|
||||
switch(pGo->GetEntry())
|
||||
{
|
||||
case GO_BJARNGRIM_DOOR:
|
||||
m_uiBjarngrimDoorGUID = pGo->GetGUID();
|
||||
if (m_auiEncounter[0] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_VOLKHAN_DOOR:
|
||||
m_uiVolkhanDoorGUID = pGo->GetGUID();
|
||||
if (m_auiEncounter[1] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_IONAR_DOOR:
|
||||
m_uiIonarDoorGUID = pGo->GetGUID();
|
||||
if (m_auiEncounter[2] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_LOKEN_DOOR:
|
||||
m_uiLokenDoorGUID = pGo->GetGUID();
|
||||
if (m_auiEncounter[3] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_LOKEN_THRONE:
|
||||
m_uiLokenGlobeGUID = pGo->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 uiType, uint32 uiData)
|
||||
{
|
||||
switch(uiType)
|
||||
{
|
||||
case TYPE_BJARNGRIM:
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(m_uiBjarngrimDoorGUID);
|
||||
m_auiEncounter[0] = uiData;
|
||||
break;
|
||||
case TYPE_VOLKHAN:
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(m_uiVolkhanDoorGUID);
|
||||
m_auiEncounter[1] = uiData;
|
||||
break;
|
||||
case TYPE_IONAR:
|
||||
if (uiData == DONE)
|
||||
DoUseDoorOrButton(m_uiIonarDoorGUID);
|
||||
m_auiEncounter[2] = uiData;
|
||||
break;
|
||||
case TYPE_LOKEN:
|
||||
if (uiData == DONE)
|
||||
{
|
||||
DoUseDoorOrButton(m_uiLokenDoorGUID);
|
||||
|
||||
//Appears to be type 5 GO with animation. Need to figure out how this work, code below only placeholder
|
||||
if (GameObject* pGlobe = instance->GetGameObject(m_uiLokenGlobeGUID))
|
||||
pGlobe->SetGoState(GO_STATE_ACTIVE);
|
||||
}
|
||||
m_auiEncounter[3] = uiData;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 uiType)
|
||||
{
|
||||
switch(uiType)
|
||||
{
|
||||
case TYPE_BJARNGRIM:
|
||||
return m_auiEncounter[0];
|
||||
case TYPE_VOLKHAN:
|
||||
return m_auiEncounter[1];
|
||||
case TYPE_IONAR:
|
||||
return m_auiEncounter[2];
|
||||
case TYPE_LOKEN:
|
||||
return m_auiEncounter[3];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 uiData)
|
||||
{
|
||||
switch(uiData)
|
||||
{
|
||||
case DATA_BJARNGRIM:
|
||||
return m_uiGeneralBjarngrimGUID;
|
||||
case DATA_VOLKHAN:
|
||||
return m_uiVolkhanGUID;
|
||||
case DATA_IONAR:
|
||||
return m_uiIonarGUID;
|
||||
case DATA_LOKEN:
|
||||
return m_uiLokenGUID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "H L " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " "
|
||||
<< m_auiEncounter[2] << " " << m_auiEncounter[3];
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint16 data0, data1, data2, data3;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
|
||||
|
||||
if (dataHead1 == 'H' && dataHead2 == 'L')
|
||||
{
|
||||
m_auiEncounter[0] = data0;
|
||||
m_auiEncounter[1] = data1;
|
||||
m_auiEncounter[2] = data2;
|
||||
m_auiEncounter[3] = data3;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
} else OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
};
|
||||
|
||||
InstanceData* GetInstanceData_instance_halls_of_lightning(Map* pMap)
|
||||
{
|
||||
return new instance_halls_of_lightning(pMap);
|
||||
}
|
||||
|
||||
void AddSC_instance_halls_of_lightning()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "instance_halls_of_lightning";
|
||||
newscript->GetInstanceData = &GetInstanceData_instance_halls_of_lightning;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/* Script Data Start
|
||||
SDName: Boss krystallus
|
||||
SDAuthor: LordVanMartin
|
||||
SD%Complete:
|
||||
SDComment:
|
||||
SDCategory:
|
||||
Script Data End */
|
||||
|
||||
/*** SQL START ***
|
||||
update creature_template set scriptname = 'boss_krystallus' where entry = '';
|
||||
*** SQL END ***/
|
||||
#include "ScriptedPch.h"
|
||||
#include "halls_of_stone.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_BOULDER_TOSS = 50843,
|
||||
H_SPELL_BOULDER_TOSS = 59742,
|
||||
SPELL_GROUND_SPIKE = 59750,
|
||||
SPELL_GROUND_SLAM = 50827,
|
||||
SPELL_SHATTER = 50810,
|
||||
H_SPELL_SHATTER = 61546,
|
||||
SPELL_STOMP = 48131,
|
||||
H_SPELL_STOMP = 59744
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = -1603007,
|
||||
SAY_KILL = -1603008,
|
||||
SAY_DEATH = -1603009,
|
||||
SAY_SHATTER = -1603010
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_krystallusAI : public ScriptedAI
|
||||
{
|
||||
boss_krystallusAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
}
|
||||
|
||||
uint32 uiBoulderTossTimer;
|
||||
uint32 uiGroundSpikeTimer;
|
||||
uint32 uiGroundSlamTimer;
|
||||
uint32 uiShatterTimer;
|
||||
uint32 uiStompTimer;
|
||||
|
||||
bool bIsSlam;
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
bIsSlam = false;
|
||||
|
||||
uiBoulderTossTimer = 3000 + rand()%6000;
|
||||
uiGroundSpikeTimer = 9000 + rand()%5000;
|
||||
uiGroundSlamTimer = 15000 + rand()%3000;
|
||||
uiStompTimer = 20000 + rand()%9000;
|
||||
uiShatterTimer = 0;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_KRYSTALLUS_EVENT, NOT_STARTED);
|
||||
}
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_KRYSTALLUS_EVENT, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiBoulderTossTimer <= diff)
|
||||
{
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(pTarget, DUNGEON_MODE(SPELL_BOULDER_TOSS, H_SPELL_BOULDER_TOSS));
|
||||
uiBoulderTossTimer = 9000 + rand()%6000;
|
||||
} else uiBoulderTossTimer -= diff;
|
||||
|
||||
if (uiGroundSpikeTimer <= diff)
|
||||
{
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(pTarget, SPELL_GROUND_SPIKE);
|
||||
uiGroundSpikeTimer = 12000 + rand()%5000;
|
||||
} else uiGroundSpikeTimer -= diff;
|
||||
|
||||
if (uiStompTimer <= diff)
|
||||
{
|
||||
DoCast(m_creature, DUNGEON_MODE(SPELL_STOMP, H_SPELL_STOMP));
|
||||
uiStompTimer = 20000 + rand()%9000;
|
||||
} else uiStompTimer -= diff;
|
||||
|
||||
if (uiGroundSlamTimer <= diff)
|
||||
{
|
||||
DoCast(m_creature, SPELL_GROUND_SLAM);
|
||||
bIsSlam = true;
|
||||
uiShatterTimer = 10000;
|
||||
uiGroundSlamTimer = 15000 + rand()%3000;
|
||||
} else uiGroundSlamTimer -= diff;
|
||||
|
||||
if (bIsSlam)
|
||||
{
|
||||
if (uiShatterTimer <= diff)
|
||||
{
|
||||
DoCast(m_creature, DUNGEON_MODE(SPELL_SHATTER, H_SPELL_SHATTER));
|
||||
bIsSlam = false;
|
||||
} else uiShatterTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, m_creature);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_KRYSTALLUS_EVENT, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
if (victim == m_creature)
|
||||
return;
|
||||
DoScriptText(SAY_KILL, m_creature);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_krystallus(Creature* pCreature)
|
||||
{
|
||||
return new boss_krystallusAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_krystallus()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_krystallus";
|
||||
newscript->GetAI = &GetAI_boss_krystallus;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,177 @@
|
||||
/* Script Data Start
|
||||
SDName: Boss maiden_of_grief
|
||||
SDAuthor: LordVanMartin
|
||||
SD%Complete:
|
||||
SDComment:
|
||||
SDCategory:
|
||||
Script Data End */
|
||||
|
||||
/*** SQL START ***
|
||||
update creature_template set scriptname = 'boss_maiden_of_grief' where entry = '';
|
||||
*** SQL END ***/
|
||||
#include "ScriptedPch.h"
|
||||
#include "halls_of_stone.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_PARTING_SORROW = 59723,
|
||||
SPELL_STORM_OF_GRIEF_N = 50752,
|
||||
SPELL_STORM_OF_GRIEF_H = 59772,
|
||||
SPELL_SHOCK_OF_SORROW_N = 50760,
|
||||
SPELL_SHOCK_OF_SORROW_H = 59726,
|
||||
SPELL_PILLAR_OF_WOE_N = 50761,
|
||||
SPELL_PILLAR_OF_WOE_H = 59727
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = -1603000,
|
||||
SAY_SLAY_1 = -1603001,
|
||||
SAY_SLAY_2 = -1603002,
|
||||
SAY_SLAY_3 = -1603003,
|
||||
SAY_SLAY_4 = -1603004,
|
||||
SAY_DEATH = -1603005,
|
||||
SAY_STUN = -1603006
|
||||
};
|
||||
|
||||
enum Achievements
|
||||
{
|
||||
ACHIEVEMENT_GOOD_GRIEF = 1866
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_maiden_of_griefAI : public ScriptedAI
|
||||
{
|
||||
boss_maiden_of_griefAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = m_creature->GetInstanceData();
|
||||
}
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
|
||||
uint32 PartingSorrowTimer;
|
||||
uint32 StormOfGriefTimer;
|
||||
uint32 ShockOfSorrowTimer;
|
||||
uint32 PillarOfWoeTimer;
|
||||
uint32 AchievTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
PartingSorrowTimer = 25000 + rand()%5000;
|
||||
StormOfGriefTimer = 10000;
|
||||
ShockOfSorrowTimer = 20000+rand()%5000;
|
||||
PillarOfWoeTimer = 5000 + rand()%10000;
|
||||
AchievTimer = 0;
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MAIDEN_OF_GRIEF_EVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_MAIDEN_DOOR)))
|
||||
if (pDoor->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
pInstance->SetData(DATA_MAIDEN_OF_GRIEF_EVENT, IN_PROGRESS);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
//Achievement counter
|
||||
if (pInstance)
|
||||
if (pInstance->GetData(DATA_MAIDEN_OF_GRIEF_EVENT) == IN_PROGRESS)
|
||||
AchievTimer += diff;
|
||||
|
||||
if (IsHeroic())
|
||||
{
|
||||
if (PartingSorrowTimer <= diff)
|
||||
{
|
||||
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 0);
|
||||
|
||||
if(pTarget)
|
||||
DoCast(pTarget, SPELL_PARTING_SORROW);
|
||||
|
||||
PartingSorrowTimer = 30000 + rand()%10000;
|
||||
} else PartingSorrowTimer -= diff;
|
||||
}
|
||||
|
||||
if (StormOfGriefTimer <= diff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_STORM_OF_GRIEF_N, SPELL_STORM_OF_GRIEF_H), true);
|
||||
StormOfGriefTimer = 15000 + rand()%5000;
|
||||
} else StormOfGriefTimer -= diff;
|
||||
|
||||
if (ShockOfSorrowTimer <= diff)
|
||||
{
|
||||
DoResetThreat();
|
||||
DoScriptText(SAY_STUN, m_creature);
|
||||
DoCast(m_creature, DUNGEON_MODE(SPELL_SHOCK_OF_SORROW_N, SPELL_SHOCK_OF_SORROW_H));
|
||||
ShockOfSorrowTimer = 20000 + rand()%10000;
|
||||
} else ShockOfSorrowTimer -= diff;
|
||||
|
||||
if (PillarOfWoeTimer <= diff)
|
||||
{
|
||||
Unit *pTarget = SelectUnit(SELECT_TARGET_RANDOM, 1);
|
||||
|
||||
if (pTarget)
|
||||
DoCast(pTarget, DUNGEON_MODE(SPELL_PILLAR_OF_WOE_N, SPELL_PILLAR_OF_WOE_H));
|
||||
else
|
||||
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_PILLAR_OF_WOE_N, SPELL_PILLAR_OF_WOE_H));
|
||||
|
||||
PillarOfWoeTimer = 5000 + rand()%20000;
|
||||
} else PillarOfWoeTimer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, m_creature);
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_MAIDEN_OF_GRIEF_EVENT, DONE);
|
||||
|
||||
AchievementEntry const *AchievGoodGrief = GetAchievementStore()->LookupEntry(ACHIEVEMENT_GOOD_GRIEF);
|
||||
Map* pMap = m_creature->GetMap();
|
||||
|
||||
if (IsHeroic() && AchievTimer < 60000 && pMap && pMap->IsDungeon() && AchievGoodGrief)
|
||||
{
|
||||
Map::PlayerList const &players = pMap->GetPlayers();
|
||||
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
|
||||
itr->getSource()->CompletedAchievement(AchievGoodGrief);
|
||||
}
|
||||
}
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
if (victim == m_creature)
|
||||
return;
|
||||
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3,SAY_SLAY_4), m_creature);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_maiden_of_grief(Creature* pCreature)
|
||||
{
|
||||
return new boss_maiden_of_griefAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_maiden_of_grief()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_maiden_of_grief";
|
||||
newscript->GetAI = &GetAI_boss_maiden_of_grief;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,300 @@
|
||||
/* Script Data Start
|
||||
SDName: Boss sjonnir
|
||||
SDAuthor: LordVanMartin
|
||||
SD%Complete:
|
||||
SDComment:
|
||||
SDCategory:
|
||||
Script Data End */
|
||||
|
||||
/*** SQL START ***
|
||||
update creature_template set scriptname = 'boss_sjonnir' where entry = '';
|
||||
*** SQL END ***/
|
||||
#include "ScriptedPch.h"
|
||||
#include "halls_of_stone.h"
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_LIGHTING_RING = 51849, //Periodic Trigger (interval 2s) spell = 50841
|
||||
H_SPELL_LIGHTING_RING = 59861, //Periodic Trigger (interval 2s) spell = 59849
|
||||
SPELL_LIGHTING_RING_1 = 50840, //Periodic Trigger (interval 2s) spell = 50841
|
||||
H_SPELL_LIGHTING_RING_1 = 59848, //Periodic Trigger (interval 2s) spell = 59849
|
||||
SPELL_STATIC_CHARGE = 50834, //Periodic Trigger 2s interval, spell =50835
|
||||
H_SPELL_STATIC_CHARGE = 59846, //Periodic Trigger 2s interval, spell =50847
|
||||
SPELL_CHAIN_LIGHTING = 50830,
|
||||
H_SPELL_CHAIN_LIGHTING = 59844,
|
||||
SPELL_LIGHTING_SHIELD = 50831,
|
||||
H_SPELL_LIGHTING_SHIELD = 59845,
|
||||
SPELL_FRENZY = 28747
|
||||
};
|
||||
|
||||
enum Yells
|
||||
{
|
||||
SAY_AGGRO = -1603011,
|
||||
SAY_SLAY_1 = -1603012,
|
||||
SAY_SLAY_2 = -1603013,
|
||||
SAY_SLAY_3 = -1603014,
|
||||
SAY_DEATH = -1603015
|
||||
};
|
||||
|
||||
#define EMOTE_GENERIC_FRENZY -1000002
|
||||
|
||||
enum SjonnirCreatures
|
||||
{
|
||||
CREATURE_FORGED_IRON_TROGG = 27979,
|
||||
CREATURE_MALFORMED_OOZE = 27981,
|
||||
CREATURE_FORGED_IRON_DWARF = 27982,
|
||||
CREATURE_IRON_SLUDGE = 28165
|
||||
};
|
||||
|
||||
enum Misc
|
||||
{
|
||||
DATA_TIME_BEFORE_OOZE = 150000, //2min 30 secs
|
||||
ACHIEV_ABUSE_THE_OOZE = 2155
|
||||
};
|
||||
|
||||
struct Locations
|
||||
{
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
static Locations PipeLocations[] =
|
||||
{
|
||||
{1295.44, 734.07, 200.3}, //left
|
||||
{1297.7, 595.6, 199.9} //right
|
||||
};
|
||||
|
||||
static Locations CenterPoint = {1295.21, 667.157, 189.691};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_sjonnirAI : public ScriptedAI
|
||||
{
|
||||
boss_sjonnirAI(Creature *c) : ScriptedAI(c), lSummons(me)
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
}
|
||||
|
||||
bool bIsFrenzy;
|
||||
|
||||
uint32 uiChainLightningTimer;
|
||||
uint32 uiLightningShieldTimer;
|
||||
uint32 uiStaticChargeTimer;
|
||||
uint32 uiLightningRingTimer;
|
||||
uint32 uiSummonTimer;
|
||||
uint32 uiFrenzyTimer;
|
||||
uint32 uiEncounterTimer;
|
||||
uint32 uiKilledIronSludges;
|
||||
|
||||
SummonList lSummons;
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
bIsFrenzy = false;
|
||||
|
||||
uiEncounterTimer = 0;
|
||||
uiChainLightningTimer = 3000 + rand()%5000;
|
||||
uiLightningShieldTimer = 20000 + rand()%5000;
|
||||
uiStaticChargeTimer = 20000 + rand()%5000;
|
||||
uiLightningRingTimer = 30000 + rand()%5000;
|
||||
uiSummonTimer = 5000;
|
||||
uiFrenzyTimer = 300000; //5 minutes
|
||||
uiKilledIronSludges = 0;
|
||||
|
||||
lSummons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_SJONNIR_EVENT, NOT_STARTED);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
|
||||
uiEncounterTimer = 0;
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
if (GameObject *pDoor = pInstance->instance->GetGameObject(pInstance->GetData64(DATA_SJONNIR_DOOR)))
|
||||
if (pDoor->GetGoState() == GO_STATE_READY)
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
pInstance->SetData(DATA_SJONNIR_EVENT, IN_PROGRESS);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
//Return since we have no target
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (uiChainLightningTimer <= diff)
|
||||
{
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(pTarget, DUNGEON_MODE(SPELL_CHAIN_LIGHTING, H_SPELL_CHAIN_LIGHTING));
|
||||
uiChainLightningTimer = 10000 + rand()%5000;
|
||||
} else uiChainLightningTimer -= diff;
|
||||
|
||||
if (uiLightningShieldTimer <= diff)
|
||||
{
|
||||
DoCast(m_creature, DUNGEON_MODE(SPELL_LIGHTING_SHIELD, H_SPELL_LIGHTING_SHIELD));
|
||||
uiLightningShieldTimer -= diff;
|
||||
}
|
||||
|
||||
if (uiStaticChargeTimer <= diff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), DUNGEON_MODE(SPELL_STATIC_CHARGE, H_SPELL_STATIC_CHARGE));
|
||||
uiStaticChargeTimer = 20000 + rand()%5000;
|
||||
} uiStaticChargeTimer -= diff;
|
||||
|
||||
if (uiLightningRingTimer <= diff)
|
||||
{
|
||||
if (m_creature->IsNonMeleeSpellCasted(false))
|
||||
m_creature->InterruptNonMeleeSpells(false);
|
||||
DoCast(m_creature, DUNGEON_MODE(SPELL_LIGHTING_RING, H_SPELL_LIGHTING_RING));
|
||||
uiLightningRingTimer = 30000 + rand()%5000;
|
||||
} else uiLightningRingTimer -= diff;
|
||||
|
||||
if (uiSummonTimer <= diff)
|
||||
{
|
||||
uint32 uiSummonPipe = rand()%2;
|
||||
m_creature->SummonCreature(uiEncounterTimer > DATA_TIME_BEFORE_OOZE ? CREATURE_MALFORMED_OOZE :
|
||||
RAND(CREATURE_FORGED_IRON_DWARF,CREATURE_FORGED_IRON_TROGG),
|
||||
PipeLocations[uiSummonPipe].x, PipeLocations[uiSummonPipe].y, PipeLocations[uiSummonPipe].z, 0.0f,
|
||||
TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
uiSummonTimer = 20000;
|
||||
} else uiSummonTimer -= diff;
|
||||
|
||||
if (!bIsFrenzy)
|
||||
{
|
||||
if (uiFrenzyTimer <= diff)
|
||||
{
|
||||
DoCast(m_creature, SPELL_FRENZY);
|
||||
bIsFrenzy = true;
|
||||
}
|
||||
else uiFrenzyTimer -= diff;
|
||||
}
|
||||
|
||||
uiEncounterTimer +=diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* summon)
|
||||
{
|
||||
summon->GetMotionMaster()->MovePoint(0, CenterPoint.x, CenterPoint.y, CenterPoint.z);
|
||||
/*if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
summon->AI()->AttackStart(pTarget);*/
|
||||
lSummons.Summon(summon);
|
||||
}
|
||||
|
||||
void JustDied(Unit* killer)
|
||||
{
|
||||
DoScriptText(SAY_DEATH, m_creature);
|
||||
lSummons.DespawnAll();
|
||||
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->SetData(DATA_SJONNIR_EVENT, DONE);
|
||||
if (IsHeroic() && uiKilledIronSludges > 4)
|
||||
pInstance->DoCompleteAchievement(ACHIEV_ABUSE_THE_OOZE);
|
||||
}
|
||||
}
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
if (victim == m_creature)
|
||||
return;
|
||||
DoScriptText(RAND(SAY_SLAY_1,SAY_SLAY_2,SAY_SLAY_3), m_creature);
|
||||
}
|
||||
|
||||
void KilledIronSludge()
|
||||
{
|
||||
++uiKilledIronSludges;
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_sjonnir(Creature* pCreature)
|
||||
{
|
||||
return new boss_sjonnirAI (pCreature);
|
||||
}
|
||||
|
||||
struct TRINITY_DLL_DECL mob_malformed_oozeAI : public ScriptedAI
|
||||
{
|
||||
mob_malformed_oozeAI(Creature *c) : ScriptedAI(c) {}
|
||||
|
||||
uint32 uiMergeTimer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
uiMergeTimer = 10000;
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (uiMergeTimer <= diff)
|
||||
{
|
||||
if (Creature* pTemp = m_creature->FindNearestCreature(CREATURE_MALFORMED_OOZE, 3.0f, true))
|
||||
{
|
||||
DoSpawnCreature(CREATURE_IRON_SLUDGE, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN_OUT_OF_COMBAT, 20000);
|
||||
pTemp->DisappearAndDie();
|
||||
m_creature->DisappearAndDie();
|
||||
}
|
||||
uiMergeTimer = 3000;
|
||||
} else uiMergeTimer -= diff;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_mob_malformed_ooze(Creature* pCreature)
|
||||
{
|
||||
return new mob_malformed_oozeAI(pCreature);
|
||||
}
|
||||
|
||||
struct TRINITY_DLL_DECL mob_iron_sludgeAI : public ScriptedAI
|
||||
{
|
||||
mob_iron_sludgeAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
}
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
|
||||
void JustDied(Unit* pKiller)
|
||||
{
|
||||
if (pInstance)
|
||||
if(Creature* pSjonnir = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_SJONNIR)))
|
||||
CAST_AI(boss_sjonnirAI, pSjonnir->AI())->KilledIronSludge();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_mob_iron_sludge(Creature* pCreature)
|
||||
{
|
||||
return new mob_iron_sludgeAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_sjonnir()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_sjonnir";
|
||||
newscript->GetAI = &GetAI_boss_sjonnir;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_malformed_ooze";
|
||||
newscript->GetAI = &GetAI_mob_malformed_ooze;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_iron_sludge";
|
||||
newscript->GetAI = &GetAI_mob_iron_sludge;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,690 @@
|
||||
#include "ScriptedPch.h"
|
||||
#include "ScriptedEscortAI.h"
|
||||
#include "halls_of_stone.h"
|
||||
|
||||
enum Texts
|
||||
{
|
||||
SAY_KILL_1 = -1603016,
|
||||
SAY_KILL_2 = -1603017,
|
||||
SAY_KILL_3 = -1603018,
|
||||
SAY_LOW_HEALTH = -1603019,
|
||||
SAY_DEATH = -1603020,
|
||||
SAY_PLAYER_DEATH_1 = -1603021,
|
||||
SAY_PLAYER_DEATH_2 = -1603022,
|
||||
SAY_PLAYER_DEATH_3 = -1603023,
|
||||
SAY_ESCORT_START = -1603024,
|
||||
|
||||
SAY_SPAWN_DWARF = -1603025,
|
||||
SAY_SPAWN_TROGG = -1603026,
|
||||
SAY_SPAWN_OOZE = -1603027,
|
||||
SAY_SPAWN_EARTHEN = -1603028,
|
||||
|
||||
SAY_EVENT_INTRO_1 = -1603029,
|
||||
SAY_EVENT_INTRO_2 = -1603030,
|
||||
SAY_EVENT_INTRO_3_ABED = -1603031,
|
||||
|
||||
SAY_EVENT_A_1 = -1603032,
|
||||
SAY_EVENT_A_2_KADD = -1603033,
|
||||
SAY_EVENT_A_3 = -1603034,
|
||||
|
||||
SAY_EVENT_B_1 = -1603035,
|
||||
SAY_EVENT_B_2_MARN = -1603036,
|
||||
SAY_EVENT_B_3 = -1603037,
|
||||
|
||||
SAY_EVENT_C_1 = -1603038,
|
||||
SAY_EVENT_C_2_ABED = -1603039,
|
||||
SAY_EVENT_C_3 = -1603040,
|
||||
|
||||
SAY_EVENT_D_1 = -1603041,
|
||||
SAY_EVENT_D_2_ABED = -1603042,
|
||||
SAY_EVENT_D_3 = -1603043,
|
||||
SAY_EVENT_D_4_ABED = -1603044,
|
||||
|
||||
SAY_EVENT_END_01 = -1603045,
|
||||
SAY_EVENT_END_02 = -1603046,
|
||||
SAY_EVENT_END_03_ABED = -1603047,
|
||||
SAY_EVENT_END_04 = -1603048,
|
||||
SAY_EVENT_END_05_ABED = -1603049,
|
||||
SAY_EVENT_END_06 = -1603050,
|
||||
SAY_EVENT_END_07_ABED = -1603051,
|
||||
SAY_EVENT_END_08 = -1603052,
|
||||
SAY_EVENT_END_09_KADD = -1603053,
|
||||
SAY_EVENT_END_10 = -1603054,
|
||||
SAY_EVENT_END_11_KADD = -1603055,
|
||||
SAY_EVENT_END_12 = -1603056,
|
||||
SAY_EVENT_END_13_KADD = -1603057,
|
||||
SAY_EVENT_END_14 = -1603058,
|
||||
SAY_EVENT_END_15_MARN = -1603059,
|
||||
SAY_EVENT_END_16 = -1603060,
|
||||
SAY_EVENT_END_17_MARN = -1603061,
|
||||
SAY_EVENT_END_18 = -1603062,
|
||||
SAY_EVENT_END_19_MARN = -1603063,
|
||||
SAY_EVENT_END_20 = -1603064,
|
||||
SAY_EVENT_END_21_ABED = -1603065,
|
||||
|
||||
SAY_VICTORY_SJONNIR_1 = -1603066,
|
||||
SAY_VICTORY_SJONNIR_2 = -1603067,
|
||||
|
||||
SAY_ENTRANCE_MEET = -1603068,
|
||||
|
||||
TEXT_ID_START = 13100,
|
||||
TEXT_ID_PROGRESS = 13101
|
||||
};
|
||||
|
||||
enum BrannCreatures
|
||||
{
|
||||
CREATURE_TRIBUNAL_OF_THE_AGES = 28234,
|
||||
CREATURE_BRANN_BRONZEBEARD = 28070,
|
||||
CREATURE_DARK_MATTER_TARGET = 28237,
|
||||
CREATURE_SEARING_GAZE_TARGET = 28265,
|
||||
CREATURE_DARK_RUNE_PROTECTOR = 27983,
|
||||
CREATURE_DARK_RUNE_STORMCALLER = 27984,
|
||||
CREATURE_IRON_GOLEM_CUSTODIAN = 27985,
|
||||
};
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_STEALTH = 58506,
|
||||
//Kadrak
|
||||
SPELL_GLARE_OF_THE_TRIBUNAL = 50988,
|
||||
H_SPELL_GLARE_OF_THE_TRIBUNAL = 59868,
|
||||
//Marnak
|
||||
SPELL_DARK_MATTER = 51012,
|
||||
H_SPELL_DARK_MATTER = 59868,
|
||||
//Abedneum
|
||||
SPELL_SEARING_GAZE = 51136,
|
||||
H_SPELL_SEARING_GAZE = 59867
|
||||
};
|
||||
|
||||
enum Quests
|
||||
{
|
||||
QUEST_HALLS_OF_STONE = 13207
|
||||
};
|
||||
|
||||
#define GOSSIP_ITEM_START "Brann, it would be our honor!"
|
||||
#define GOSSIP_ITEM_PROGRESS "Let's move Brann, enough of the history lessons!"
|
||||
|
||||
struct Locations
|
||||
{
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
static Locations SpawnLocations[]=
|
||||
{
|
||||
{946.992, 397.016, 208.374},
|
||||
{960.748, 382.944, 208.374},
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL mob_tribuna_controllerAI : public ScriptedAI
|
||||
{
|
||||
mob_tribuna_controllerAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
SetCombatMovement(false);
|
||||
}
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
|
||||
uint32 uiKaddrakEncounterTimer;
|
||||
uint32 uiMarnakEncounterTimer;
|
||||
uint32 uiAbedneumEncounterTimer;
|
||||
|
||||
bool bKaddrakActivated;
|
||||
bool bMarnakActivated;
|
||||
bool bAbedneumActivated;
|
||||
|
||||
std::list<Creature*> lKaddrakGUIDList;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
uiKaddrakEncounterTimer = 1500;
|
||||
uiMarnakEncounterTimer = 10000;
|
||||
uiAbedneumEncounterTimer = 10000;
|
||||
|
||||
bKaddrakActivated = false;
|
||||
bMarnakActivated = false;
|
||||
bAbedneumActivated = false;
|
||||
|
||||
lKaddrakGUIDList.clear();
|
||||
}
|
||||
|
||||
void UpdateFacesList()
|
||||
{
|
||||
/*GetCreatureListWithEntryInGrid(lKaddrakGUIDList, m_creature, CREATURE_KADDRAK, 50.0f);
|
||||
if (!lKaddrakGUIDList.empty())
|
||||
{
|
||||
uint32 uiPositionCounter = 0;
|
||||
for (std::list<Creature*>::iterator itr = lKaddrakGUIDList.begin(); itr != lKaddrakGUIDList.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->isAlive())
|
||||
{
|
||||
if (uiPositionCounter == 0)
|
||||
{
|
||||
(*itr)->GetMap()->CreatureRelocation((*itr), 927.265, 333.200, 218.780, (*itr)->GetOrientation());
|
||||
(*itr)->SendMonsterMove(927.265, 333.200, 218.780, 0, (*itr)->GetMovementFlags(), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*itr)->GetMap()->CreatureRelocation((*itr), 921.745, 328.076, 218.780, (*itr)->GetOrientation());
|
||||
(*itr)->SendMonsterMove(921.745, 328.076, 218.780, 0, (*itr)->GetMovementFlags(), 1);
|
||||
}
|
||||
}
|
||||
++uiPositionCounter;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if(bKaddrakActivated)
|
||||
{
|
||||
if (uiKaddrakEncounterTimer <= diff)
|
||||
{
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
if (!lKaddrakGUIDList.empty())
|
||||
for (std::list<Creature*>::iterator itr = lKaddrakGUIDList.begin(); itr != lKaddrakGUIDList.end(); ++itr)
|
||||
if ((*itr)->isAlive())
|
||||
(*itr)->CastSpell(pTarget, DUNGEON_MODE(SPELL_GLARE_OF_THE_TRIBUNAL, H_SPELL_GLARE_OF_THE_TRIBUNAL), true);
|
||||
uiKaddrakEncounterTimer = 1500;
|
||||
} else uiKaddrakEncounterTimer -= diff;
|
||||
}
|
||||
if (bMarnakActivated)
|
||||
{
|
||||
if (uiMarnakEncounterTimer <= diff)
|
||||
{
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
{
|
||||
if (Creature* pSummon = m_creature->SummonCreature(CREATURE_DARK_MATTER_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000))
|
||||
{
|
||||
pSummon->SetDisplayId(11686);
|
||||
pSummon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
pSummon->CastSpell(pTarget, DUNGEON_MODE(SPELL_DARK_MATTER, H_SPELL_DARK_MATTER), true);
|
||||
}
|
||||
}
|
||||
uiMarnakEncounterTimer = 30000 + rand()%1000;
|
||||
} else uiMarnakEncounterTimer -= diff;
|
||||
}
|
||||
if (bAbedneumActivated)
|
||||
{
|
||||
if (uiAbedneumEncounterTimer <= diff)
|
||||
{
|
||||
if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
{
|
||||
if (Creature* pSummon = m_creature->SummonCreature(CREATURE_SEARING_GAZE_TARGET, pTarget->GetPositionX(), pTarget->GetPositionY(), pTarget->GetPositionZ(), 0.0f, TEMPSUMMON_TIMED_DESPAWN, 1000))
|
||||
{
|
||||
pSummon->SetDisplayId(11686);
|
||||
pSummon->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
|
||||
pSummon->CastSpell(pTarget, DUNGEON_MODE(SPELL_SEARING_GAZE, H_SPELL_SEARING_GAZE), true);
|
||||
}
|
||||
}
|
||||
uiAbedneumEncounterTimer = 30000 + rand()%1000;
|
||||
} else uiAbedneumEncounterTimer -= diff;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL npc_brann_hosAI : public npc_escortAI
|
||||
{
|
||||
npc_brann_hosAI(Creature *c) : npc_escortAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
}
|
||||
|
||||
uint32 uiStep;
|
||||
uint32 uiPhaseTimer;
|
||||
|
||||
uint64 uiControllerGUID;
|
||||
std::list<uint64> lDwarfGUIDList;
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
|
||||
bool bIsBattle;
|
||||
bool bIsLowHP;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if (!HasEscortState(STATE_ESCORT_ESCORTING))
|
||||
{
|
||||
bIsLowHP = false;
|
||||
bIsBattle = false;
|
||||
uiStep = 0;
|
||||
uiPhaseTimer = 0;
|
||||
uiControllerGUID = 0;
|
||||
|
||||
DespawnDwarf();
|
||||
|
||||
if (pInstance)
|
||||
pInstance->SetData(DATA_BRANN_EVENT, NOT_STARTED);
|
||||
}
|
||||
}
|
||||
|
||||
void DespawnDwarf()
|
||||
{
|
||||
if (lDwarfGUIDList.empty())
|
||||
return;
|
||||
for (std::list<uint64>::iterator itr = lDwarfGUIDList.begin(); itr != lDwarfGUIDList.end(); ++itr)
|
||||
{
|
||||
Creature* pTemp = Unit::GetCreature(*m_creature, pInstance ? (*itr) : 0);
|
||||
if (pTemp && pTemp->isAlive())
|
||||
pTemp->ForcedDespawn();
|
||||
}
|
||||
lDwarfGUIDList.clear();
|
||||
}
|
||||
|
||||
void WaypointReached(uint32 uiPointId)
|
||||
{
|
||||
switch(uiPointId)
|
||||
{
|
||||
case 7:
|
||||
if (Creature* pCreature = GetClosestCreatureWithEntry(m_creature, CREATURE_TRIBUNAL_OF_THE_AGES, 100.0f))
|
||||
{
|
||||
if (!pCreature->isAlive())
|
||||
pCreature->Respawn();
|
||||
CAST_AI(mob_tribuna_controllerAI, pCreature->AI())->UpdateFacesList();
|
||||
uiControllerGUID = pCreature->GetGUID();
|
||||
}
|
||||
break;
|
||||
case 13:
|
||||
DoScriptText(SAY_EVENT_INTRO_1, m_creature);
|
||||
SetEscortPaused(true);
|
||||
SetRun(true);
|
||||
JumpToNextStep(20000);
|
||||
break;
|
||||
case 17:
|
||||
DoScriptText(SAY_EVENT_INTRO_2, m_creature);
|
||||
if (pInstance)
|
||||
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_TRIBUNAL_CONSOLE),true);
|
||||
m_creature->SetStandState(UNIT_STAND_STATE_KNEEL);
|
||||
SetEscortPaused(true);
|
||||
JumpToNextStep(8500);
|
||||
break;
|
||||
case 18:
|
||||
SetEscortPaused(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnDwarf(uint32 uiType)
|
||||
{
|
||||
switch(uiType)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
uint32 uiSpawnNumber = DUNGEON_MODE(2,3);
|
||||
for (uint8 i = 0; i < uiSpawnNumber; ++i)
|
||||
m_creature->SummonCreature(CREATURE_DARK_RUNE_PROTECTOR, SpawnLocations[0].x, SpawnLocations[0].y, SpawnLocations[0].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
m_creature->SummonCreature(CREATURE_DARK_RUNE_STORMCALLER, SpawnLocations[0].x, SpawnLocations[0].y, SpawnLocations[0].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
for (uint8 i = 0; i < 2; ++i)
|
||||
m_creature->SummonCreature(CREATURE_DARK_RUNE_STORMCALLER, SpawnLocations[1].x, SpawnLocations[1].y, SpawnLocations[1].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
break;
|
||||
case 3:
|
||||
m_creature->SummonCreature(CREATURE_IRON_GOLEM_CUSTODIAN, SpawnLocations[1].x, SpawnLocations[1].y, SpawnLocations[1].z, 0.0f, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void JustSummoned(Creature* pSummoned)
|
||||
{
|
||||
lDwarfGUIDList.push_back(pSummoned->GetGUID());
|
||||
pSummoned->AddThreat(m_creature, 0.0f);
|
||||
pSummoned->AI()->AttackStart(m_creature);
|
||||
}
|
||||
|
||||
void JumpToNextStep(uint32 uiTimer)
|
||||
{
|
||||
uiPhaseTimer = uiTimer;
|
||||
++uiStep;
|
||||
}
|
||||
|
||||
void StartWP()
|
||||
{
|
||||
m_creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
SetEscortPaused(false);
|
||||
uiStep = 1;
|
||||
Start();
|
||||
}
|
||||
|
||||
void UpdateEscortAI(const uint32 uiDiff)
|
||||
{
|
||||
if (uiPhaseTimer <= uiDiff)
|
||||
{
|
||||
switch(uiStep)
|
||||
{
|
||||
case 1:
|
||||
if (pInstance)
|
||||
{
|
||||
if (pInstance->GetData(DATA_BRANN_EVENT) != NOT_STARTED)
|
||||
return;
|
||||
pInstance->SetData(DATA_BRANN_EVENT, IN_PROGRESS);
|
||||
}
|
||||
bIsBattle = false;
|
||||
DoScriptText(SAY_ESCORT_START, m_creature);
|
||||
JumpToNextStep(0);
|
||||
break;
|
||||
case 3:
|
||||
SetEscortPaused(false);
|
||||
JumpToNextStep(0);
|
||||
break;
|
||||
case 5:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = (Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM))))
|
||||
DoScriptText(SAY_EVENT_INTRO_3_ABED, pTemp);
|
||||
JumpToNextStep(8500);
|
||||
break;
|
||||
case 6:
|
||||
DoScriptText(SAY_EVENT_A_1, m_creature);
|
||||
JumpToNextStep(6500);
|
||||
break;
|
||||
case 7:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_KADDRAK)))
|
||||
DoScriptText(SAY_EVENT_A_2_KADD, pTemp);
|
||||
JumpToNextStep(12500);
|
||||
break;
|
||||
case 8:
|
||||
DoScriptText(SAY_EVENT_A_3, m_creature);
|
||||
if (pInstance)
|
||||
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_KADDRAK),true);
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, uiControllerGUID))
|
||||
CAST_AI(mob_tribuna_controllerAI, pTemp->AI())->bKaddrakActivated = true;
|
||||
JumpToNextStep(5000);
|
||||
break;
|
||||
case 9:
|
||||
SpawnDwarf(1);
|
||||
JumpToNextStep(20000);
|
||||
break;
|
||||
case 10:
|
||||
DoScriptText(SAY_EVENT_B_1, m_creature);
|
||||
JumpToNextStep(6000);
|
||||
break;
|
||||
case 11:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_MARNAK)))
|
||||
DoScriptText(SAY_EVENT_B_2_MARN, pTemp);
|
||||
SpawnDwarf(1);
|
||||
JumpToNextStep(20000);
|
||||
break;
|
||||
case 12:
|
||||
DoScriptText(SAY_EVENT_B_3, m_creature);
|
||||
if (pInstance)
|
||||
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_MARNAK),true);
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, uiControllerGUID))
|
||||
CAST_AI(mob_tribuna_controllerAI, pTemp->AI())->bMarnakActivated = true;
|
||||
JumpToNextStep(10000);
|
||||
break;
|
||||
case 13:
|
||||
SpawnDwarf(1);
|
||||
JumpToNextStep(10000);
|
||||
break;
|
||||
case 14:
|
||||
SpawnDwarf(2);
|
||||
JumpToNextStep(20000);
|
||||
break;
|
||||
case 15:
|
||||
DoScriptText(SAY_EVENT_C_1, m_creature);
|
||||
SpawnDwarf(1);
|
||||
JumpToNextStep(10000);
|
||||
break;
|
||||
case 16:
|
||||
SpawnDwarf(2);
|
||||
JumpToNextStep(20000);
|
||||
break;
|
||||
case 17:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
|
||||
DoScriptText(SAY_EVENT_C_2_ABED, pTemp);
|
||||
SpawnDwarf(1);
|
||||
JumpToNextStep(20000);
|
||||
break;
|
||||
case 18:
|
||||
DoScriptText(SAY_EVENT_C_3, m_creature);
|
||||
if (pInstance)
|
||||
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_ABEDNEUM),true);
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, uiControllerGUID))
|
||||
CAST_AI(mob_tribuna_controllerAI, pTemp->AI())->bAbedneumActivated = true;
|
||||
JumpToNextStep(5000);
|
||||
break;
|
||||
case 19:
|
||||
SpawnDwarf(2);
|
||||
JumpToNextStep(10000);
|
||||
break;
|
||||
case 20:
|
||||
SpawnDwarf(1);
|
||||
JumpToNextStep(15000);
|
||||
break;
|
||||
case 21:
|
||||
DoScriptText(SAY_EVENT_D_1, m_creature);
|
||||
SpawnDwarf(3);
|
||||
JumpToNextStep(20000);
|
||||
break;
|
||||
case 22:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
|
||||
DoScriptText(SAY_EVENT_D_2_ABED, pTemp);
|
||||
SpawnDwarf(1);
|
||||
JumpToNextStep(5000);
|
||||
break;
|
||||
case 23:
|
||||
SpawnDwarf(2);
|
||||
JumpToNextStep(15000);
|
||||
break;
|
||||
case 24:
|
||||
DoScriptText(SAY_EVENT_D_3, m_creature);
|
||||
SpawnDwarf(3);
|
||||
JumpToNextStep(5000);
|
||||
break;
|
||||
case 25:
|
||||
SpawnDwarf(1);
|
||||
JumpToNextStep(5000);
|
||||
break;
|
||||
case 26:
|
||||
SpawnDwarf(2);
|
||||
JumpToNextStep(10000);
|
||||
break;
|
||||
case 27:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
|
||||
DoScriptText(SAY_EVENT_D_4_ABED, pTemp);
|
||||
SpawnDwarf(1);
|
||||
JumpToNextStep(10000);
|
||||
break;
|
||||
case 28:
|
||||
DoScriptText(SAY_EVENT_END_01, m_creature);
|
||||
m_creature->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
if (pInstance)
|
||||
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_SKY_FLOOR),true);
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, uiControllerGUID))
|
||||
pTemp->DealDamage(pTemp, pTemp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);
|
||||
bIsBattle = true;
|
||||
SetEscortPaused(false);
|
||||
JumpToNextStep(6500);
|
||||
break;
|
||||
case 29:
|
||||
DoScriptText(SAY_EVENT_END_02, m_creature);
|
||||
JumpToNextStep(5500);
|
||||
break;
|
||||
case 30:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
|
||||
DoScriptText(SAY_EVENT_END_03_ABED, pTemp);
|
||||
JumpToNextStep(8500);
|
||||
break;
|
||||
case 31:
|
||||
DoScriptText(SAY_EVENT_END_04, m_creature);
|
||||
JumpToNextStep(11500);
|
||||
break;
|
||||
case 32:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
|
||||
DoScriptText(SAY_EVENT_END_05_ABED, pTemp);
|
||||
JumpToNextStep(11500);
|
||||
break;
|
||||
case 33:
|
||||
DoScriptText(SAY_EVENT_END_06, m_creature);
|
||||
JumpToNextStep(4500);
|
||||
break;
|
||||
case 34:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
|
||||
DoScriptText(SAY_EVENT_END_07_ABED, pTemp);
|
||||
JumpToNextStep(22500);
|
||||
break;
|
||||
case 35:
|
||||
DoScriptText(SAY_EVENT_END_08, m_creature);
|
||||
JumpToNextStep(7500);
|
||||
break;
|
||||
case 36:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_KADDRAK)))
|
||||
DoScriptText(SAY_EVENT_END_09_KADD, pTemp);
|
||||
JumpToNextStep(18500);
|
||||
break;
|
||||
case 37:
|
||||
DoScriptText(SAY_EVENT_END_10, m_creature);
|
||||
JumpToNextStep(5500);
|
||||
break;
|
||||
case 38:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_KADDRAK)))
|
||||
DoScriptText(SAY_EVENT_END_11_KADD, pTemp);
|
||||
JumpToNextStep(20500);
|
||||
break;
|
||||
case 39:
|
||||
DoScriptText(SAY_EVENT_END_12, m_creature);
|
||||
JumpToNextStep(2500);
|
||||
break;
|
||||
case 40:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_KADDRAK)))
|
||||
DoScriptText(SAY_EVENT_END_13_KADD, pTemp);
|
||||
JumpToNextStep(19500);
|
||||
break;
|
||||
case 41:
|
||||
DoScriptText(SAY_EVENT_END_14, m_creature);
|
||||
JumpToNextStep(10500);
|
||||
break;
|
||||
case 42:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_MARNAK)))
|
||||
DoScriptText(SAY_EVENT_END_15_MARN, pTemp);
|
||||
JumpToNextStep(6500);
|
||||
break;
|
||||
case 43:
|
||||
DoScriptText(SAY_EVENT_END_16, m_creature);
|
||||
JumpToNextStep(6500);
|
||||
break;
|
||||
case 44:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_MARNAK)))
|
||||
DoScriptText(SAY_EVENT_END_17_MARN, pTemp);
|
||||
JumpToNextStep(25500);
|
||||
break;
|
||||
case 45:
|
||||
DoScriptText(SAY_EVENT_END_18, m_creature);
|
||||
JumpToNextStep(23500);
|
||||
break;
|
||||
case 46:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_MARNAK)))
|
||||
DoScriptText(SAY_EVENT_END_19_MARN, pTemp);
|
||||
JumpToNextStep(3500);
|
||||
break;
|
||||
case 47:
|
||||
DoScriptText(SAY_EVENT_END_20, m_creature);
|
||||
JumpToNextStep(8500);
|
||||
break;
|
||||
case 48:
|
||||
if (pInstance)
|
||||
if (Creature* pTemp = Unit::GetCreature(*m_creature, pInstance->GetData64(DATA_ABEDNEUM)))
|
||||
DoScriptText(SAY_EVENT_END_21_ABED, pTemp);
|
||||
JumpToNextStep(5500);
|
||||
break;
|
||||
case 49:
|
||||
{
|
||||
if (pInstance)
|
||||
{
|
||||
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_KADDRAK),true);
|
||||
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_MARNAK),true);
|
||||
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_ABEDNEUM),true);
|
||||
pInstance->HandleGameObject(pInstance->GetData64(DATA_GO_SKY_FLOOR),true);
|
||||
pInstance->SetData(DATA_BRANN_EVENT, DONE);
|
||||
}
|
||||
Player* pPlayer = GetPlayerForEscort();
|
||||
if (pPlayer)
|
||||
pPlayer->GroupEventHappens(QUEST_HALLS_OF_STONE, m_creature);
|
||||
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP);
|
||||
m_creature->SetUInt32Value(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_QUESTGIVER);
|
||||
JumpToNextStep(180000);
|
||||
break;
|
||||
}
|
||||
case 50:
|
||||
SetEscortPaused(false);
|
||||
break;
|
||||
}
|
||||
} else uiPhaseTimer -= uiDiff;
|
||||
|
||||
if (!bIsLowHP && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) <= 30)
|
||||
{
|
||||
DoScriptText(SAY_LOW_HEALTH, m_creature);
|
||||
bIsLowHP = true;
|
||||
} else if (bIsLowHP && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) > 30)
|
||||
bIsLowHP = false;
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
bool GossipHello_npc_brann_hos(Player* pPlayer, Creature* pCreature)
|
||||
{
|
||||
if (pCreature->isQuestGiver())
|
||||
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
|
||||
|
||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_ITEM_START, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||
pPlayer->SEND_GOSSIP_MENU(TEXT_ID_START, pCreature->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GossipSelect_npc_brann_hos(Player* pPlayer, Creature* pCreature, uint32 uiSender, uint32 uiAction)
|
||||
{
|
||||
if (uiAction == GOSSIP_ACTION_INFO_DEF+1 || uiAction == GOSSIP_ACTION_INFO_DEF+2)
|
||||
{
|
||||
pPlayer->CLOSE_GOSSIP_MENU();
|
||||
CAST_AI(npc_brann_hosAI, pCreature->AI())->StartWP();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_mob_tribuna_controller(Creature* pCreature)
|
||||
{
|
||||
return new mob_tribuna_controllerAI(pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_npc_brann_hos(Creature* pCreature)
|
||||
{
|
||||
return new npc_brann_hosAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_halls_of_stone()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "npc_brann_hos";
|
||||
newscript->GetAI = &GetAI_npc_brann_hos;
|
||||
newscript->pGossipHello = &GossipHello_npc_brann_hos;
|
||||
newscript->pGossipSelect = &GossipSelect_npc_brann_hos;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_tribuna_controller";
|
||||
newscript->GetAI = &GetAI_mob_tribuna_controller;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef DEF_HALLS_OF_STONE_H
|
||||
#define DEF_HALLS_OF_STONE_H
|
||||
enum Data
|
||||
{
|
||||
DATA_KRYSTALLUS_EVENT,
|
||||
DATA_MAIDEN_OF_GRIEF_EVENT,
|
||||
DATA_SJONNIR_EVENT,
|
||||
DATA_BRANN_EVENT
|
||||
};
|
||||
enum Data64
|
||||
{
|
||||
DATA_KRYSTALLUS,
|
||||
DATA_MAIDEN_OF_GRIEF,
|
||||
DATA_SJONNIR,
|
||||
DATA_KADDRAK,
|
||||
DATA_MARNAK,
|
||||
DATA_ABEDNEUM,
|
||||
DATA_GO_TRIBUNAL_CONSOLE,
|
||||
DATA_GO_KADDRAK,
|
||||
DATA_GO_MARNAK,
|
||||
DATA_GO_ABEDNEUM,
|
||||
DATA_GO_SKY_FLOOR,
|
||||
DATA_SJONNIR_DOOR,
|
||||
DATA_MAIDEN_DOOR
|
||||
};
|
||||
enum Creatures
|
||||
{
|
||||
CREATURE_MAIDEN = 27975,
|
||||
CREATURE_KRYSTALLUS = 27977,
|
||||
CREATURE_SJONNIR = 27978,
|
||||
CREATURE_MARNAK = 30897,
|
||||
CREATURE_KADDRAK = 30898,
|
||||
CREATURE_ABEDNEUM = 30899,
|
||||
CREATURE_BRANN = 28070
|
||||
};
|
||||
enum GameObjects
|
||||
{
|
||||
GO_ABEDNEUM = 191669,
|
||||
GO_MARNAK = 192170,
|
||||
GO_KADDRAK = 192171,
|
||||
GO_MAIDEN_DOOR = 191292,
|
||||
GO_BRANN_DOOR = 191295,
|
||||
GO_SJONNIR_DOOR = 191296,
|
||||
GO_TRIBUNAL_CONSOLE = 193907,
|
||||
GO_TRIBUNAL_CHEST = 190586,
|
||||
GO_TRIBUNAL_CHEST_HERO = 193996
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,254 @@
|
||||
#include "ScriptedPch.h"
|
||||
#include "halls_of_stone.h"
|
||||
|
||||
#define MAX_ENCOUNTER 4
|
||||
|
||||
/* Halls of Stone encounters:
|
||||
0- Krystallus
|
||||
1- Maiden of Grief
|
||||
2- Escort Event
|
||||
3- Sjonnir The Ironshaper
|
||||
*/
|
||||
|
||||
struct TRINITY_DLL_DECL instance_halls_of_stone : public ScriptedInstance
|
||||
{
|
||||
instance_halls_of_stone(Map* pMap) : ScriptedInstance(pMap) {Initialize();};
|
||||
|
||||
uint64 uiMaidenOfGrief;
|
||||
uint64 uiKrystallus;
|
||||
uint64 uiSjonnir;
|
||||
|
||||
uint64 uiKaddrak;
|
||||
uint64 uiAbedneum;
|
||||
uint64 uiMarnak;
|
||||
uint64 uiBrann;
|
||||
|
||||
uint64 uiMaidenOfGriefDoor;
|
||||
uint64 uiSjonnirDoor;
|
||||
uint64 uiBrannDoor;
|
||||
uint64 uiTribunalConsole;
|
||||
uint64 uiTribunalChest;
|
||||
uint64 uiTribunalSkyFloor;
|
||||
uint64 uiKaddrakGo;
|
||||
uint64 uiAbedneumGo;
|
||||
uint64 uiMarnakGo;
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
|
||||
std::string str_data;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
uiMaidenOfGrief = 0;
|
||||
uiKrystallus = 0;
|
||||
uiSjonnir = 0;
|
||||
|
||||
uiKaddrak = 0;
|
||||
uiMarnak = 0;
|
||||
uiAbedneum = 0;
|
||||
uiBrann = 0;
|
||||
|
||||
uiMaidenOfGriefDoor = 0;
|
||||
uiSjonnirDoor = 0;
|
||||
uiBrannDoor = 0;
|
||||
uiKaddrakGo = 0;
|
||||
uiMarnakGo = 0;
|
||||
uiAbedneumGo = 0;
|
||||
uiTribunalConsole = 0;
|
||||
uiTribunalChest = 0;
|
||||
uiTribunalSkyFloor = 0;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature, bool add)
|
||||
{
|
||||
switch(pCreature->GetEntry())
|
||||
{
|
||||
case CREATURE_MAIDEN: uiMaidenOfGrief = pCreature->GetGUID(); break;
|
||||
case CREATURE_KRYSTALLUS: uiKrystallus = pCreature->GetGUID(); break;
|
||||
case CREATURE_SJONNIR: uiSjonnir = pCreature->GetGUID(); break;
|
||||
case CREATURE_MARNAK: uiMarnak = pCreature->GetGUID(); break;
|
||||
case CREATURE_KADDRAK: uiKaddrak = pCreature->GetGUID(); break;
|
||||
case CREATURE_ABEDNEUM: uiAbedneum = pCreature->GetGUID(); break;
|
||||
case CREATURE_BRANN: uiBrann = pCreature->GetGUID(); break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo, bool add)
|
||||
{
|
||||
switch(pGo->GetEntry())
|
||||
{
|
||||
case GO_ABEDNEUM:
|
||||
uiAbedneumGo = pGo->GetGUID();
|
||||
break;
|
||||
case GO_MARNAK:
|
||||
uiMarnakGo = pGo->GetGUID();
|
||||
break;
|
||||
case GO_KADDRAK:
|
||||
uiKaddrakGo = pGo->GetGUID();
|
||||
break;
|
||||
case GO_MAIDEN_DOOR:
|
||||
uiMaidenOfGriefDoor = pGo->GetGUID();
|
||||
if (m_auiEncounter[0] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
else
|
||||
pGo->SetGoState(GO_STATE_READY);
|
||||
break;
|
||||
case GO_BRANN_DOOR:
|
||||
uiBrannDoor = pGo->GetGUID();
|
||||
if (m_auiEncounter[1] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
else
|
||||
pGo->SetGoState(GO_STATE_READY);
|
||||
break;
|
||||
case GO_SJONNIR_DOOR:
|
||||
uiSjonnirDoor = pGo->GetGUID();
|
||||
if (m_auiEncounter[2] == DONE)
|
||||
pGo->SetGoState(GO_STATE_ACTIVE);
|
||||
else
|
||||
pGo->SetGoState(GO_STATE_READY);
|
||||
break;
|
||||
case GO_TRIBUNAL_CONSOLE:
|
||||
uiTribunalConsole = pGo->GetGUID();
|
||||
break;
|
||||
case GO_TRIBUNAL_CHEST:
|
||||
case GO_TRIBUNAL_CHEST_HERO:
|
||||
uiTribunalChest = pGo->GetGUID();
|
||||
if (m_auiEncounter[2] == DONE)
|
||||
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
|
||||
break;
|
||||
case 191527:
|
||||
uiTribunalSkyFloor = pGo->GetGUID();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_MAIDEN_OF_GRIEF_EVENT:
|
||||
m_auiEncounter[1] = data;
|
||||
if (m_auiEncounter[1] == DONE)
|
||||
HandleGameObject(uiBrannDoor,true);
|
||||
break;
|
||||
case DATA_KRYSTALLUS_EVENT:
|
||||
m_auiEncounter[0] = data;
|
||||
if (m_auiEncounter[0] == DONE)
|
||||
HandleGameObject(uiMaidenOfGriefDoor,true);
|
||||
break;
|
||||
case DATA_SJONNIR_EVENT:
|
||||
m_auiEncounter[3] = data;
|
||||
break;
|
||||
case DATA_BRANN_EVENT:
|
||||
m_auiEncounter[2] = data;
|
||||
if (m_auiEncounter[2] == DONE)
|
||||
{
|
||||
HandleGameObject(uiSjonnirDoor,true);
|
||||
GameObject *pGo = instance->GetGameObject(uiTribunalChest);
|
||||
if (pGo)
|
||||
pGo->RemoveFlag(GAMEOBJECT_FLAGS,GO_FLAG_INTERACT_COND);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case DATA_KRYSTALLUS_EVENT: return m_auiEncounter[0];
|
||||
case DATA_MAIDEN_OF_GRIEF_EVENT: return m_auiEncounter[1];
|
||||
case DATA_SJONNIR_EVENT: return m_auiEncounter[2];
|
||||
case DATA_BRANN_EVENT: return m_auiEncounter[3];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 identifier)
|
||||
{
|
||||
switch(identifier)
|
||||
{
|
||||
case DATA_MAIDEN_OF_GRIEF: return uiMaidenOfGrief;
|
||||
case DATA_KRYSTALLUS: return uiKrystallus;
|
||||
case DATA_SJONNIR: return uiSjonnir;
|
||||
case DATA_KADDRAK: return uiKaddrak;
|
||||
case DATA_MARNAK: return uiMarnak;
|
||||
case DATA_ABEDNEUM: return uiAbedneum;
|
||||
case DATA_GO_TRIBUNAL_CONSOLE: return uiTribunalConsole;
|
||||
case DATA_GO_KADDRAK: return uiKaddrakGo;
|
||||
case DATA_GO_ABEDNEUM: return uiAbedneumGo;
|
||||
case DATA_GO_MARNAK: return uiMarnakGo;
|
||||
case DATA_GO_SKY_FLOOR: return uiTribunalSkyFloor;
|
||||
case DATA_SJONNIR_DOOR: return uiSjonnirDoor;
|
||||
case DATA_MAIDEN_DOOR: return uiMaidenOfGriefDoor;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "H S " << m_auiEncounter[0] << " " << m_auiEncounter[1] << " " << m_auiEncounter[2] << " " << m_auiEncounter[3];
|
||||
|
||||
str_data = saveStream.str();
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return str_data;
|
||||
}
|
||||
|
||||
void Load(const char* in)
|
||||
{
|
||||
if (!in)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(in);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint16 data0, data1, data2, data3;
|
||||
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3;
|
||||
|
||||
if (dataHead1 == 'H' && dataHead2 == 'S')
|
||||
{
|
||||
m_auiEncounter[0] = data0;
|
||||
m_auiEncounter[1] = data1;
|
||||
m_auiEncounter[2] = data2;
|
||||
m_auiEncounter[3] = data3;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
|
||||
} else OUT_LOAD_INST_DATA_FAIL;
|
||||
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
};
|
||||
|
||||
InstanceData* GetInstanceData_instance_halls_of_stone(Map* pMap)
|
||||
{
|
||||
return new instance_halls_of_stone(pMap);
|
||||
}
|
||||
|
||||
void AddSC_instance_halls_of_stone()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "instance_halls_of_stone";
|
||||
newscript->GetInstanceData = &GetInstanceData_instance_halls_of_stone;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
@@ -0,0 +1,560 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: Assembly of Iron encounter
|
||||
SD%Complete: 60%
|
||||
SDComment: Runes need DB support, chain lightning won't cast, supercharge won't cast (pTarget error?) - it worked before during debugging.
|
||||
SDCategory: Ulduar - Ulduar
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
// Any boss
|
||||
#define SPELL_SUPERCHARGE 61920
|
||||
#define SPELL_BERSERK 47008 // Hard enrage, don't know the correct ID.
|
||||
|
||||
// Steelbreaker
|
||||
#define SPELL_HIGH_VOLTAGE 61890
|
||||
#define SPELL_HIGH_VOLTAGE_H 63498
|
||||
#define SPELL_FUSION_PUNCH 61903
|
||||
#define SPELL_FUSION_PUNCH_H 63493
|
||||
#define SPELL_STATIC_DISRUPTION 44008
|
||||
#define SPELL_STATIC_DISRUPTION_H 63494
|
||||
#define SPELL_OVERWHELMING_POWER_H 61888
|
||||
#define SPELL_OVERWHELMING_POWER 64637
|
||||
#define SPELL_ELECTRICAL_CHARGE 61902
|
||||
|
||||
// Runemaster Molgeim
|
||||
#define SPELL_SHIELD_OF_RUNES 62274
|
||||
#define SPELL_SHIELD_OF_RUNES_H 63489
|
||||
#define SPELL_RUNE_OF_POWER 64320
|
||||
#define SPELL_RUNE_OF_DEATH 62269
|
||||
#define SPELL_RUNE_OF_SUMMONING 62273
|
||||
#define SPELL_LIGHTNING_BLAST 62054
|
||||
#define SPELL_LIGHTNING_BLAST_H 63491
|
||||
#define CREATURE_RUNE_OF_SUMMONING 33051
|
||||
|
||||
// Stormcaller Brundir
|
||||
#define SPELL_CHAIN_LIGHTNING_N 61879
|
||||
#define SPELL_CHAIN_LIGHTNING_H 63479
|
||||
#define SPELL_OVERLOAD 61869
|
||||
#define SPELL_OVERLOAD_H 63481
|
||||
#define SPELL_LIGHTNING_WHIRL 61915
|
||||
#define SPELL_LIGHTNING_WHIRL_H 63483
|
||||
#define SPELL_LIGHTNING_TENDRILS 61887
|
||||
#define SPELL_LIGHTNING_TENDRILS_H 63486
|
||||
#define SPELL_STORMSHIELD 64187
|
||||
|
||||
enum eEnums
|
||||
{
|
||||
EVENT_ENRAGE,
|
||||
// Steelbreaker
|
||||
EVENT_FUSION_PUNCH,
|
||||
EVENT_STATIC_DISRUPTION,
|
||||
EVENT_OVERWHELMING_POWER,
|
||||
// Molgeim
|
||||
EVENT_RUNE_OF_POWER,
|
||||
EVENT_SHIELD_OF_RUNES,
|
||||
EVENT_RUNE_OF_DEATH,
|
||||
EVENT_RUNE_OF_SUMMONING,
|
||||
EVENT_LIGHTNING_BLAST,
|
||||
// Brundir
|
||||
EVENT_CHAIN_LIGHTNING,
|
||||
EVENT_OVERLOAD,
|
||||
EVENT_LIGHTNING_WHIRL,
|
||||
EVENT_LIGHTNING_TENDRILS,
|
||||
EVENT_STORMSHIELD,
|
||||
MAX_EVENT
|
||||
|
||||
};
|
||||
|
||||
bool IsEncounterComplete(ScriptedInstance* pInstance, Creature* m_creature)
|
||||
{
|
||||
if (!pInstance || !m_creature)
|
||||
return false;
|
||||
|
||||
for (uint8 i = 0; i < 3; ++i)
|
||||
{
|
||||
uint64 guid = pInstance->GetData64(DATA_STEELBREAKER+i);
|
||||
if(!guid)
|
||||
return false;
|
||||
|
||||
if(Creature *boss = (Unit::GetCreature((*m_creature), guid)))
|
||||
{
|
||||
if(boss->isAlive())
|
||||
return false;
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct TRINITY_DLL_DECL boss_steelbreakerAI : public ScriptedAI
|
||||
{
|
||||
boss_steelbreakerAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
events.Reset();
|
||||
phase = 0;
|
||||
m_creature->RemoveAllAuras();
|
||||
if(pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
ScriptedInstance* pInstance;
|
||||
uint32 phase;
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
DoZoneInCombat();
|
||||
DoCast(m_creature, RAID_MODE(SPELL_HIGH_VOLTAGE, SPELL_HIGH_VOLTAGE_H));
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 900000);
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void UpdatePhase()
|
||||
{
|
||||
++phase;
|
||||
events.SetPhase(phase);
|
||||
events.RescheduleEvent(EVENT_FUSION_PUNCH, 15000);
|
||||
if(phase >= 2)
|
||||
events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 30000);
|
||||
if(phase >= 3)
|
||||
events.RescheduleEvent(EVENT_OVERWHELMING_POWER, rand()%5000);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* pKiller, uint32 &damage)
|
||||
{
|
||||
if(damage >= m_creature->GetHealth())
|
||||
{
|
||||
if(Creature* Brundir = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_STORMCALLER_BRUNDIR) : 0))
|
||||
if(Brundir->isAlive())
|
||||
{
|
||||
Brundir->SetHealth(Brundir->GetMaxHealth());
|
||||
}
|
||||
|
||||
if(Creature* Molgeim = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_RUNEMASTER_MOLGEIM) : 0))
|
||||
if(Molgeim->isAlive())
|
||||
{
|
||||
Molgeim->SetHealth(Molgeim->GetMaxHealth());
|
||||
}
|
||||
DoCast(SPELL_SUPERCHARGE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
if(IsEncounterComplete(pInstance, m_creature) && pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, DONE);
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *who)
|
||||
{
|
||||
if(phase == 3)
|
||||
DoCast(m_creature, SPELL_ELECTRICAL_CHARGE);
|
||||
}
|
||||
|
||||
void SpellHit(Unit *from, const SpellEntry *spell)
|
||||
{
|
||||
if(spell->Id == SPELL_SUPERCHARGE)
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while(uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch(eventId)
|
||||
{
|
||||
case EVENT_ENRAGE:
|
||||
DoCast(SPELL_BERSERK);
|
||||
break;
|
||||
case EVENT_FUSION_PUNCH:
|
||||
DoCast(me->getVictim(), RAID_MODE(SPELL_FUSION_PUNCH_H, SPELL_FUSION_PUNCH));
|
||||
events.ScheduleEvent(EVENT_FUSION_PUNCH, 13000 + (rand()%9)*1000);
|
||||
break;
|
||||
case EVENT_STATIC_DISRUPTION:
|
||||
{
|
||||
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM);
|
||||
DoCast(pTarget, RAID_MODE(SPELL_STATIC_DISRUPTION_H, SPELL_STATIC_DISRUPTION));
|
||||
events.ScheduleEvent(EVENT_STATIC_DISRUPTION, 20000 + (rand()%20)*1000);
|
||||
}
|
||||
break;
|
||||
case EVENT_OVERWHELMING_POWER:
|
||||
DoCast(me->getVictim(), RAID_MODE(SPELL_OVERWHELMING_POWER, SPELL_OVERWHELMING_POWER_H));
|
||||
events.ScheduleEvent(EVENT_OVERWHELMING_POWER, RAID_MODE(60000, 35000));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_runemaster_molgeimAI : public ScriptedAI
|
||||
{
|
||||
boss_runemaster_molgeimAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if(pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
|
||||
events.Reset();
|
||||
m_creature->RemoveAllAuras();
|
||||
phase = 0;
|
||||
}
|
||||
|
||||
ScriptedInstance* pInstance;
|
||||
EventMap events;
|
||||
uint32 phase;
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoZoneInCombat();
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 900000);
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void UpdatePhase()
|
||||
{
|
||||
++phase;
|
||||
events.SetPhase(phase);
|
||||
events.RescheduleEvent(EVENT_SHIELD_OF_RUNES, 27000);
|
||||
events.RescheduleEvent(EVENT_RUNE_OF_POWER, 60000);
|
||||
if(phase >= 2)
|
||||
events.RescheduleEvent(EVENT_RUNE_OF_DEATH, 30000);
|
||||
if(phase >= 3)
|
||||
events.RescheduleEvent(EVENT_RUNE_OF_SUMMONING, 20000+(rand()%10)*1000);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* pKiller, uint32 &damage)
|
||||
{
|
||||
if(damage >= m_creature->GetHealth())
|
||||
{
|
||||
if(Creature* Steelbreaker = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_STEELBREAKER) : 0))
|
||||
if(Steelbreaker->isAlive())
|
||||
{
|
||||
Steelbreaker->SetHealth(Steelbreaker->GetMaxHealth());
|
||||
}
|
||||
|
||||
if(Creature* Brundir = Unit::GetCreature((*m_creature), pInstance ? pInstance->GetData64(DATA_STORMCALLER_BRUNDIR) : 0))
|
||||
if(Brundir->isAlive())
|
||||
{
|
||||
Brundir->SetHealth(Brundir->GetMaxHealth());
|
||||
}
|
||||
DoCast(m_creature, SPELL_SUPERCHARGE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
if(IsEncounterComplete(pInstance, m_creature) && pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, DONE);
|
||||
}
|
||||
|
||||
void SpellHit(Unit *from, const SpellEntry *spell)
|
||||
{
|
||||
if(spell->Id == SPELL_SUPERCHARGE)
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while(uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch(eventId)
|
||||
{
|
||||
case EVENT_ENRAGE:
|
||||
DoCast(SPELL_BERSERK);
|
||||
break;
|
||||
case EVENT_RUNE_OF_POWER: // Improve target selection; random alive friendly
|
||||
{
|
||||
Unit *Target = DoSelectLowestHpFriendly(60);
|
||||
if(!Target || (Target && !Target->isAlive()))
|
||||
Target = m_creature;
|
||||
DoCast(Target, SPELL_RUNE_OF_POWER);
|
||||
events.ScheduleEvent(EVENT_RUNE_OF_POWER, 60000);
|
||||
}
|
||||
break;
|
||||
case EVENT_SHIELD_OF_RUNES:
|
||||
DoCast(m_creature, RAID_MODE(SPELL_SHIELD_OF_RUNES, SPELL_SHIELD_OF_RUNES_H));
|
||||
events.ScheduleEvent(EVENT_SHIELD_OF_RUNES, 27000+ (rand()%7)*1000);
|
||||
break;
|
||||
case EVENT_RUNE_OF_DEATH:
|
||||
{
|
||||
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM);
|
||||
DoCast(pTarget, SPELL_RUNE_OF_DEATH);
|
||||
events.ScheduleEvent(EVENT_RUNE_OF_DEATH, 30000+ (rand()%10)*1000);
|
||||
}
|
||||
break;
|
||||
case EVENT_RUNE_OF_SUMMONING:
|
||||
{
|
||||
Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM);
|
||||
DoCast(pTarget, SPELL_RUNE_OF_SUMMONING);
|
||||
events.ScheduleEvent(EVENT_RUNE_OF_SUMMONING, 20000+(rand()%10)*1000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL mob_lightning_elementalAI : public ScriptedAI
|
||||
{
|
||||
mob_lightning_elementalAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
Charge();
|
||||
}
|
||||
|
||||
Unit* Target;
|
||||
|
||||
void Charge()
|
||||
{
|
||||
Target = m_creature->SelectNearestTarget();
|
||||
m_creature->AddThreat(Target, 5000000.0f);
|
||||
AttackStart(Target);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if(!m_creature->isInCombat())
|
||||
return;
|
||||
|
||||
if(m_creature->IsWithinMeleeRange(Target))
|
||||
{
|
||||
DoCast(Target, RAID_MODE(SPELL_LIGHTNING_BLAST, SPELL_LIGHTNING_BLAST_H));
|
||||
m_creature->Kill(m_creature); // hack until spell works
|
||||
}
|
||||
|
||||
m_creature->GetMotionMaster()->MoveChase(Target); // needed at every update?
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL mob_rune_of_summoningAI : public ScriptedAI
|
||||
{
|
||||
mob_rune_of_summoningAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
SummonLightningElemental();
|
||||
}
|
||||
|
||||
void SummonLightningElemental()
|
||||
{
|
||||
m_creature->SummonCreature(CREATURE_RUNE_OF_SUMMONING, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 0, TEMPSUMMON_CORPSE_DESPAWN );
|
||||
m_creature->DealDamage(m_creature, m_creature->GetHealth());
|
||||
}
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_stormcaller_brundirAI : public ScriptedAI
|
||||
{
|
||||
boss_stormcaller_brundirAI(Creature *c) : ScriptedAI(c)
|
||||
{
|
||||
pInstance = c->GetInstanceData();
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
if(pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, NOT_STARTED);
|
||||
m_creature->RemoveAllAuras();
|
||||
events.Reset();
|
||||
phase = 0;
|
||||
}
|
||||
|
||||
EventMap events;
|
||||
ScriptedInstance* pInstance;
|
||||
uint32 phase;
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoZoneInCombat();
|
||||
events.ScheduleEvent(EVENT_ENRAGE, 900000);
|
||||
UpdatePhase();
|
||||
}
|
||||
|
||||
void UpdatePhase()
|
||||
{
|
||||
++phase;
|
||||
events.SetPhase(phase);
|
||||
events.RescheduleEvent(EVENT_CHAIN_LIGHTNING, 9000+ (rand()%8)*1000);
|
||||
events.RescheduleEvent(EVENT_OVERLOAD, 60000+ (rand()%65)*1000);
|
||||
if(phase >= 2)
|
||||
events.RescheduleEvent(EVENT_LIGHTNING_WHIRL, 20000+ (rand()%20)*1000);
|
||||
if(phase >= 3)
|
||||
{
|
||||
DoCast(m_creature, SPELL_STORMSHIELD);
|
||||
events.RescheduleEvent(EVENT_LIGHTNING_TENDRILS, 40000+ (rand()%40)*1000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void DamageTaken(Unit* pKiller, uint32 &damage)
|
||||
{
|
||||
if(damage >= m_creature->GetHealth())
|
||||
{
|
||||
if(Creature* Steelbreaker = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_STEELBREAKER) : 0))
|
||||
if(Steelbreaker->isAlive())
|
||||
{
|
||||
Steelbreaker->SetHealth(Steelbreaker->GetMaxHealth());
|
||||
}
|
||||
|
||||
if(Creature* Molgeim = Unit::GetCreature(*m_creature, pInstance ? pInstance->GetData64(DATA_RUNEMASTER_MOLGEIM) : 0))
|
||||
if(Molgeim->isAlive())
|
||||
{
|
||||
Molgeim->SetHealth(Molgeim->GetMaxHealth());
|
||||
}
|
||||
|
||||
DoCast(SPELL_SUPERCHARGE);
|
||||
}
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
if(IsEncounterComplete(pInstance, m_creature) && pInstance)
|
||||
pInstance->SetData(TYPE_ASSEMBLY, DONE);
|
||||
}
|
||||
|
||||
void SpellHit(Unit *from, const SpellEntry *spell)
|
||||
{
|
||||
if(spell->Id == SPELL_SUPERCHARGE)
|
||||
{
|
||||
UpdatePhase();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
while(uint32 eventId = events.ExecuteEvent())
|
||||
{
|
||||
switch(eventId)
|
||||
{
|
||||
case EVENT_ENRAGE:
|
||||
DoCast(SPELL_BERSERK);
|
||||
break;
|
||||
case EVENT_CHAIN_LIGHTNING:
|
||||
{
|
||||
Unit* Target = SelectUnit(SELECT_TARGET_RANDOM,0);
|
||||
DoCast(Target, RAID_MODE(SPELL_CHAIN_LIGHTNING_N , SPELL_CHAIN_LIGHTNING_H));
|
||||
events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 9000+ (rand()%8)*1000);
|
||||
}
|
||||
break;
|
||||
case EVENT_OVERLOAD:
|
||||
DoCast(RAID_MODE(SPELL_OVERLOAD , SPELL_OVERLOAD_H));
|
||||
events.ScheduleEvent(EVENT_OVERLOAD, 60000+ (rand()%65)*1000);
|
||||
break;
|
||||
case EVENT_LIGHTNING_WHIRL:
|
||||
DoCast(RAID_MODE(SPELL_LIGHTNING_WHIRL , SPELL_LIGHTNING_WHIRL_H));
|
||||
events.ScheduleEvent(EVENT_LIGHTNING_WHIRL, 20000+ (rand()%20)*1000);
|
||||
break;
|
||||
case EVENT_LIGHTNING_TENDRILS:
|
||||
DoCast(RAID_MODE(SPELL_LIGHTNING_TENDRILS, SPELL_LIGHTNING_TENDRILS_H));
|
||||
events.DelayEvents(15000, 5000);
|
||||
DoResetThreat();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_steelbreaker(Creature* pCreature)
|
||||
{
|
||||
return new boss_steelbreakerAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_boss_runemaster_molgeim(Creature* pCreature)
|
||||
{
|
||||
return new boss_runemaster_molgeimAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_boss_stormcaller_brundir(Creature* pCreature)
|
||||
{
|
||||
return new boss_stormcaller_brundirAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_mob_lightning_elemental(Creature* pCreature)
|
||||
{
|
||||
return new mob_lightning_elementalAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_mob_rune_of_summoning(Creature* pCreature)
|
||||
{
|
||||
return new mob_rune_of_summoningAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_assembly_of_iron()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_steelbreaker";
|
||||
newscript->GetAI = &GetAI_boss_steelbreaker;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_runemaster_molgeim";
|
||||
newscript->GetAI = &GetAI_boss_runemaster_molgeim;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_stormcaller_brundir";
|
||||
newscript->GetAI = &GetAI_boss_stormcaller_brundir;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_lightning_elemental";
|
||||
newscript->GetAI = &GetAI_mob_lightning_elemental;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "mob_rune_of_summoning";
|
||||
newscript->GetAI = &GetAI_mob_rune_of_summoning;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
//boss_auriaya
|
||||
#define SPELL_TERRIFYING_SCREECH 64386
|
||||
#define SPELL_SETINEL_BLAST 64679
|
||||
#define SPELL_SONIC_SCREECH 64422
|
||||
#define SPELL_SUMMON_SWARMING_GUARDIAN 64397
|
||||
//wrong text ids. correct are beetwen -1000000 AND -1999999
|
||||
//beetwen -2000000 and -2999999 are custom texts so wtf?
|
||||
#define SAY_AGGRO -2615016
|
||||
#define SAY_SLAY_1 -2615017
|
||||
|
||||
struct TRINITY_DLL_DECL boss_auriaya_AI : public BossAI
|
||||
{
|
||||
boss_auriaya_AI(Creature *pCreature) : BossAI(pCreature, TYPE_AURIAYA)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 TERRIFYING_SCREECH_Timer;
|
||||
uint32 SONIC_SCREECH_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
TERRIFYING_SCREECH_Timer = 180000;
|
||||
SONIC_SCREECH_Timer = 30000;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO,m_creature);
|
||||
}
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
DoScriptText(SAY_SLAY_1, m_creature);
|
||||
}
|
||||
|
||||
void JustDied(Unit *victim)
|
||||
{
|
||||
DoScriptText(SAY_SLAY_1, m_creature);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_AURIAYA, DONE);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) {}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if (TERRIFYING_SCREECH_Timer <= diff)
|
||||
{
|
||||
DoCast(SPELL_TERRIFYING_SCREECH);
|
||||
DoScriptText(SAY_SLAY_1, m_creature);
|
||||
TERRIFYING_SCREECH_Timer = 180000;
|
||||
} else TERRIFYING_SCREECH_Timer -= diff;
|
||||
|
||||
if (SONIC_SCREECH_Timer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_SONIC_SCREECH);
|
||||
SONIC_SCREECH_Timer = 30000;
|
||||
} else SONIC_SCREECH_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_auriaya(Creature* pCreature)
|
||||
{
|
||||
return new boss_auriaya_AI (pCreature);
|
||||
}
|
||||
void AddSC_boss_auriaya()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_auriaya";
|
||||
newscript->GetAI = &GetAI_boss_auriaya;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,395 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
#define SPELL_PURSUED 62374
|
||||
#define SPELL_GATHERING_SPEED 62375
|
||||
#define SPELL_BATTERING_RAM 62376
|
||||
#define SPELL_FLAME_VENTS 62396
|
||||
#define SPELL_MISSILE_BARRAGE 62400
|
||||
#define SPELL_SYSTEMS_SHUTDOWN 62475
|
||||
|
||||
#define SPELL_FLAME_CANNON 62395
|
||||
//#define SPELL_FLAME_CANNON 64692 trigger the same spell
|
||||
|
||||
#define SPELL_OVERLOAD_CIRCUIT 62399
|
||||
|
||||
#define SPELL_SEARING_FLAME 62402
|
||||
|
||||
#define SPELL_BLAZE 62292
|
||||
|
||||
#define SPELL_SMOKE_TRAIL 63575
|
||||
|
||||
#define SPELL_MIMIRON_INFERNO 62910
|
||||
|
||||
#define SPELL_HODIR_FURY 62297
|
||||
|
||||
#define SPELL_ELECTROSHOCK 62522
|
||||
|
||||
enum Mobs
|
||||
{
|
||||
MOB_MECHANOLIFT = 33214,
|
||||
MOB_LIQUID = 33189,
|
||||
MOB_CONTAINER = 33218,
|
||||
};
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_PURSUE = 1,
|
||||
EVENT_MISSILE,
|
||||
EVENT_VENT,
|
||||
EVENT_SPEED,
|
||||
EVENT_SUMMON,
|
||||
EVENT_MIMIRON_INFERNO, // Not Blizzlike
|
||||
EVENT_HODIR_FURY, // Not Blizzlike
|
||||
};
|
||||
|
||||
enum Seats
|
||||
{
|
||||
SEAT_PLAYER = 0,
|
||||
SEAT_TURRET = 1,
|
||||
SEAT_DEVICE = 2,
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_flame_leviathanAI : public BossAI
|
||||
{
|
||||
boss_flame_leviathanAI(Creature *pCreature) : BossAI(pCreature, TYPE_LEVIATHAN), vehicle(me->GetVehicleKit())
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
assert(vehicle);
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
Vehicle *vehicle;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
_Reset();
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
_EnterCombat();
|
||||
me->SetReactState(REACT_DEFENSIVE);
|
||||
events.ScheduleEvent(EVENT_PURSUE, 0);
|
||||
events.ScheduleEvent(EVENT_MISSILE, 1500);
|
||||
events.ScheduleEvent(EVENT_VENT, 20000);
|
||||
events.ScheduleEvent(EVENT_SPEED, 15000);
|
||||
events.ScheduleEvent(EVENT_SUMMON, 0);
|
||||
//events.ScheduleEvent(EVENT_MIMIRON_INFERNO, 60000 + (rand()%60000)); // Not Blizzlike
|
||||
//events.ScheduleEvent(EVENT_HODIR_FURY, 60000 + (rand()%60000)); // Not Blizzlike
|
||||
if (Creature *turret = CAST_CRE(vehicle->GetPassenger(7)))
|
||||
turret->AI()->DoZoneInCombat();
|
||||
}
|
||||
|
||||
// TODO: effect 0 and effect 1 may be on different target
|
||||
void SpellHitTarget(Unit *pTarget, const SpellEntry *spell)
|
||||
{
|
||||
if (spell->Id == SPELL_PURSUED)
|
||||
AttackStart(pTarget);
|
||||
}
|
||||
|
||||
void JustDied(Unit *victim)
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_LEVIATHAN, DONE);
|
||||
}
|
||||
|
||||
void SpellHit(Unit *caster, const SpellEntry *spell)
|
||||
{
|
||||
if(spell->Id == 62472)
|
||||
vehicle->InstallAllAccessories();
|
||||
else if(spell->Id == SPELL_ELECTROSHOCK)
|
||||
me->InterruptSpell(CURRENT_CHANNELED_SPELL);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!me->isInCombat())
|
||||
return;
|
||||
|
||||
if (me->getThreatManager().isThreatListEmpty())
|
||||
{
|
||||
EnterEvadeMode();
|
||||
return;
|
||||
}
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if (me->hasUnitState(UNIT_STAT_CASTING))
|
||||
return;
|
||||
|
||||
uint32 eventId = events.GetEvent();
|
||||
if (!me->getVictim())
|
||||
eventId = EVENT_PURSUE;
|
||||
|
||||
switch(eventId)
|
||||
{
|
||||
case 0: break; // this is a must
|
||||
case EVENT_PURSUE:
|
||||
DoCastAOE(SPELL_PURSUED, true);
|
||||
//events.RepeatEvent(35000); // this should not be used because eventId may be overriden
|
||||
events.RescheduleEvent(EVENT_PURSUE, 35000);
|
||||
if(!me->getVictim()) // all siege engines and demolishers are dead
|
||||
UpdateVictim(); // begin to kill other things
|
||||
return;
|
||||
case EVENT_MISSILE:
|
||||
//TODO: without target no visual effect
|
||||
//DoCastAOE(SPELL_MISSILE_BARRAGE);
|
||||
DoCast(me->getVictim(), SPELL_MISSILE_BARRAGE);
|
||||
events.RepeatEvent(1500);
|
||||
return;
|
||||
case EVENT_VENT:
|
||||
DoCastAOE(SPELL_FLAME_VENTS);
|
||||
events.RepeatEvent(20000);
|
||||
return;
|
||||
case EVENT_SPEED:
|
||||
DoCastAOE(SPELL_GATHERING_SPEED);
|
||||
events.RepeatEvent(15000);
|
||||
return;
|
||||
case EVENT_SUMMON:
|
||||
if(summons.size() < 15) // 4seat+1turret+10lift
|
||||
if(Creature *lift = DoSummonFlyer(MOB_MECHANOLIFT, me, rand()%20 + 20, 50, 0))
|
||||
lift->GetMotionMaster()->MoveRandom(100);
|
||||
events.RepeatEvent(2000);
|
||||
return;
|
||||
case EVENT_MIMIRON_INFERNO: // Not Blizzlike
|
||||
DoCast(me->getVictim(), SPELL_MIMIRON_INFERNO);
|
||||
events.RepeatEvent(60000 + (rand()%60000));
|
||||
return;
|
||||
case EVENT_HODIR_FURY: // Not Blizzlike
|
||||
DoCast(me->getVictim(), SPELL_HODIR_FURY);
|
||||
events.RepeatEvent(60000 + (rand()%60000));
|
||||
default:
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
DoSpellAttackIfReady(SPELL_BATTERING_RAM);
|
||||
}
|
||||
};
|
||||
|
||||
//#define BOSS_DEBUG
|
||||
|
||||
struct TRINITY_DLL_DECL boss_flame_leviathan_seatAI : public PassiveAI
|
||||
{
|
||||
boss_flame_leviathan_seatAI(Creature *c) : PassiveAI(c), vehicle(c->GetVehicleKit())
|
||||
{
|
||||
assert(vehicle);
|
||||
#ifdef BOSS_DEBUG
|
||||
me->SetReactState(REACT_AGGRESSIVE);
|
||||
#endif
|
||||
}
|
||||
|
||||
Vehicle *vehicle;
|
||||
|
||||
#ifdef BOSS_DEBUG
|
||||
void MoveInLineOfSight(Unit *who)
|
||||
{
|
||||
if(who->GetTypeId() == TYPEID_PLAYER && CAST_PLR(who)->isGameMaster()
|
||||
&& !who->GetVehicle() && vehicle->GetPassenger(SEAT_TURRET))
|
||||
who->EnterVehicle(vehicle, SEAT_PLAYER);
|
||||
}
|
||||
#endif
|
||||
|
||||
void PassengerBoarded(Unit *who, int8 seatId, bool apply)
|
||||
{
|
||||
if(!me->GetVehicle())
|
||||
return;
|
||||
|
||||
if(seatId == SEAT_PLAYER)
|
||||
{
|
||||
if(!apply)
|
||||
return;
|
||||
|
||||
if(Creature *turret = CAST_CRE(vehicle->GetPassenger(SEAT_TURRET)))
|
||||
{
|
||||
turret->setFaction(me->GetVehicleBase()->getFaction());
|
||||
turret->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
|
||||
turret->AI()->AttackStart(who);
|
||||
}
|
||||
if(Unit *device = vehicle->GetPassenger(SEAT_DEVICE))
|
||||
{
|
||||
device->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
device->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
}
|
||||
else if(seatId == SEAT_TURRET)
|
||||
{
|
||||
if(apply)
|
||||
return;
|
||||
|
||||
if(Unit *device = vehicle->GetPassenger(SEAT_DEVICE))
|
||||
{
|
||||
device->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
device->SetUInt32Value(UNIT_FIELD_FLAGS, 0); // unselectable
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_flame_leviathan_defense_turretAI : public TurretAI
|
||||
{
|
||||
boss_flame_leviathan_defense_turretAI(Creature *c) : TurretAI(c) {}
|
||||
|
||||
void DamageTaken(Unit *who, uint32 &damage)
|
||||
{
|
||||
if(!CanAIAttack(who))
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
bool CanAIAttack(const Unit *who) const
|
||||
{
|
||||
if (who->GetTypeId() != TYPEID_PLAYER || !who->GetVehicle() || who->GetVehicleBase()->GetEntry() != 33114)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_flame_leviathan_overload_deviceAI : public PassiveAI
|
||||
{
|
||||
boss_flame_leviathan_overload_deviceAI(Creature *c) : PassiveAI(c) {}
|
||||
|
||||
void DoAction(const int32 param)
|
||||
{
|
||||
if(param == EVENT_SPELLCLICK)
|
||||
{
|
||||
me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
if(me->GetVehicle())
|
||||
{
|
||||
if(Unit *player = me->GetVehicle()->GetPassenger(SEAT_PLAYER))
|
||||
{
|
||||
player->ExitVehicle();
|
||||
me->GetVehicleBase()->CastSpell(player, SPELL_SMOKE_TRAIL, true);
|
||||
if(Unit *leviathan = me->GetVehicleBase()->GetVehicleBase())
|
||||
player->GetMotionMaster()->MoveKnockbackFrom(leviathan->GetPositionX(), leviathan->GetPositionY(), 30, 30);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_flame_leviathan_safety_containerAI : public PassiveAI
|
||||
{
|
||||
boss_flame_leviathan_safety_containerAI(Creature *c) : PassiveAI(c) {}
|
||||
|
||||
void MovementInform(uint32 type, uint32 id)
|
||||
{
|
||||
if(id == me->GetEntry())
|
||||
{
|
||||
if(Creature *liquid = DoSummon(MOB_LIQUID, me, 0))
|
||||
liquid->CastSpell(liquid, 62494, true);
|
||||
me->DisappearAndDie(); // this will relocate creature to sky
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if(!me->GetVehicle() && me->isSummon() && me->GetMotionMaster()->GetCurrentMovementGeneratorType() != POINT_MOTION_TYPE)
|
||||
me->GetMotionMaster()->MoveFall(409.8f, me->GetEntry());
|
||||
}
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL spell_pool_of_tarAI : public TriggerAI
|
||||
{
|
||||
spell_pool_of_tarAI(Creature *c) : TriggerAI(c)
|
||||
{
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
}
|
||||
|
||||
void DamageTaken(Unit *who, uint32 &damage)
|
||||
{
|
||||
damage = 0;
|
||||
}
|
||||
|
||||
void SpellHit(Unit* caster, const SpellEntry *spell)
|
||||
{
|
||||
if(spell->SchoolMask & SPELL_SCHOOL_MASK_FIRE && !me->HasAura(SPELL_BLAZE))
|
||||
me->CastSpell(me, SPELL_BLAZE, true);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_flame_leviathan(Creature* pCreature)
|
||||
{
|
||||
return new boss_flame_leviathanAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_boss_flame_leviathan_seat(Creature* pCreature)
|
||||
{
|
||||
return new boss_flame_leviathan_seatAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_boss_flame_leviathan_defense_turret(Creature* pCreature)
|
||||
{
|
||||
return new boss_flame_leviathan_defense_turretAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_boss_flame_leviathan_overload_device(Creature* pCreature)
|
||||
{
|
||||
return new boss_flame_leviathan_overload_deviceAI (pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_boss_flame_leviathan_safety_containerAI(Creature* pCreature)
|
||||
{
|
||||
return new boss_flame_leviathan_safety_containerAI(pCreature);
|
||||
}
|
||||
|
||||
CreatureAI* GetAI_spell_pool_of_tar(Creature* pCreature)
|
||||
{
|
||||
return new spell_pool_of_tarAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_flame_leviathan()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_flame_leviathan";
|
||||
newscript->GetAI = &GetAI_boss_flame_leviathan;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_flame_leviathan_seat";
|
||||
newscript->GetAI = &GetAI_boss_flame_leviathan_seat;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_flame_leviathan_defense_turret";
|
||||
newscript->GetAI = &GetAI_boss_flame_leviathan_defense_turret;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_flame_leviathan_overload_device";
|
||||
newscript->GetAI = &GetAI_boss_flame_leviathan_overload_device;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_flame_leviathan_safety_container";
|
||||
newscript->GetAI = &GetAI_boss_flame_leviathan_safety_containerAI;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "spell_pool_of_tar";
|
||||
newscript->GetAI = &GetAI_spell_pool_of_tar;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
/*
|
||||
#define SAY_AGGRO -1
|
||||
#define SAY_SLAY -1
|
||||
*/
|
||||
|
||||
struct TRINITY_DLL_DECL boss_freyaAI : public BossAI
|
||||
{
|
||||
boss_freyaAI(Creature* pCreature) : BossAI(pCreature, TYPE_FREYA)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
}
|
||||
|
||||
void JustDied(Unit *victim)
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_FREYA, DONE);
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho)
|
||||
{
|
||||
// DoScriptText(SAY_AGGRO, m_creature);
|
||||
m_creature->SetInCombatWithZone();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_FREYA, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
//SPELLS TODO:
|
||||
|
||||
//
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
EnterEvadeIfOutOfCombatArea(diff);
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_freya(Creature* pCreature)
|
||||
{
|
||||
return new boss_freyaAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_freya()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_freya";
|
||||
newscript->GetAI = &GetAI_boss_freya;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
/*
|
||||
#define SAY_AGGRO -1
|
||||
#define SAY_SLAY -1
|
||||
*/
|
||||
|
||||
struct TRINITY_DLL_DECL boss_hodirAI : public BossAI
|
||||
{
|
||||
boss_hodirAI(Creature *pCreature) : BossAI(pCreature, TYPE_HODIR)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
}
|
||||
|
||||
void JustDied(Unit *victim)
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_HODIR, DONE);
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho)
|
||||
{
|
||||
// DoScriptText(SAY_AGGRO, m_creature);
|
||||
m_creature->SetInCombatWithZone();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_HODIR, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
//SPELLS TODO:
|
||||
|
||||
//
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
EnterEvadeIfOutOfCombatArea(diff);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_hodir(Creature* pCreature)
|
||||
{
|
||||
return new boss_hodirAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_hodir()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_hodir";
|
||||
newscript->GetAI = &GetAI_boss_hodir;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
#define SPELL_FLAME_JETS 62680
|
||||
#define SPELL_SCORCH 62546
|
||||
#define SPELL_SLAG_POT 62717
|
||||
|
||||
//wrong ids. not in db
|
||||
#define SAY_AGGRO -10000002
|
||||
#define SAY_SLAY -1000003
|
||||
|
||||
struct TRINITY_DLL_DECL boss_ignis_AI : public BossAI
|
||||
{
|
||||
boss_ignis_AI(Creature *pCreature) : BossAI(pCreature, TYPE_IGNIS) {}
|
||||
|
||||
uint32 FLAME_JETS_Timer;
|
||||
uint32 SCORCH_Timer;
|
||||
uint32 SLAG_POT_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
FLAME_JETS_Timer = 32000;
|
||||
SCORCH_Timer = 100;
|
||||
SLAG_POT_Timer = 100;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO,m_creature);
|
||||
}
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
DoScriptText(SAY_SLAY, m_creature);
|
||||
}
|
||||
|
||||
void JustDied(Unit *victim)
|
||||
{
|
||||
DoScriptText(SAY_SLAY, m_creature);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) {}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if(m_creature->GetPositionY() < 150 || m_creature->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles.
|
||||
{
|
||||
m_creature->RemoveAllAuras();
|
||||
m_creature->DeleteThreatList();
|
||||
m_creature->CombatStop(false);
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
if (FLAME_JETS_Timer <= diff)
|
||||
{
|
||||
DoCast(SPELL_FLAME_JETS);
|
||||
DoScriptText(SAY_SLAY, m_creature);
|
||||
FLAME_JETS_Timer = 25000;
|
||||
} else FLAME_JETS_Timer -= diff;
|
||||
|
||||
if (SCORCH_Timer <= diff)
|
||||
{
|
||||
DoCast(SPELL_SCORCH);
|
||||
SCORCH_Timer = 20000;
|
||||
} else SCORCH_Timer -= diff;
|
||||
|
||||
if (SLAG_POT_Timer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
|
||||
DoCast(pTarget, SPELL_SLAG_POT);
|
||||
DoScriptText(SAY_SLAY, m_creature);
|
||||
SLAG_POT_Timer = 30000;
|
||||
} else SLAG_POT_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_ignis(Creature* pCreature)
|
||||
{
|
||||
return new boss_ignis_AI (pCreature);
|
||||
}
|
||||
void AddSC_boss_ignis()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_ignis";
|
||||
newscript->GetAI = &GetAI_boss_ignis;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
#include "Vehicle.h"
|
||||
|
||||
#define SPELL_ARM_DEAD_DAMAGE RAID_MODE(63629,63979)
|
||||
#define SPELL_TWO_ARM_SMASH RAID_MODE(63356,64003)
|
||||
#define SPELL_ONE_ARM_SMASH RAID_MODE(63573,64006)
|
||||
#define SPELL_STONE_SHOUT RAID_MODE(63716,64005)
|
||||
#define SPELL_PETRIFY_BREATH RAID_MODE(62030,63980)
|
||||
|
||||
#define SPELL_STONE_GRIP RAID_MODE(62166,63981)
|
||||
#define SPELL_ARM_SWEEP RAID_MODE(63766,63983)
|
||||
|
||||
enum Events
|
||||
{
|
||||
EVENT_NONE = 0,
|
||||
EVENT_SMASH,
|
||||
EVENT_GRIP,
|
||||
EVENT_SWEEP,
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_kologarnAI : public BossAI
|
||||
{
|
||||
boss_kologarnAI(Creature *pCreature) : BossAI(pCreature, TYPE_KOLOGARN), vehicle(me->GetVehicleKit()),
|
||||
left(false), right(false)
|
||||
{
|
||||
m_pInstance = me->GetInstanceData();
|
||||
assert(vehicle);
|
||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE);
|
||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED); // i think this is a hack, but there is no other way to disable his rotation
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
Vehicle *vehicle;
|
||||
bool left, right;
|
||||
|
||||
void AttackStart(Unit *who)
|
||||
{
|
||||
me->Attack(who, true);
|
||||
}
|
||||
|
||||
void JustDied(Unit *victim)
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_KOLOGARN, DONE);
|
||||
}
|
||||
|
||||
void PassengerBoarded(Unit *who, int8 seatId, bool apply)
|
||||
{
|
||||
if(who->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
if(who->GetEntry() == 32933)
|
||||
left = apply;
|
||||
else if(who->GetEntry() == 32934)
|
||||
right = apply;
|
||||
who->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_STUNNED);
|
||||
CAST_CRE(who)->SetReactState(REACT_PASSIVE);
|
||||
}
|
||||
}
|
||||
|
||||
void EnterCombat(Unit *who)
|
||||
{
|
||||
_EnterCombat();
|
||||
events.ScheduleEvent(EVENT_SMASH, 5000);
|
||||
events.ScheduleEvent(EVENT_SWEEP, 10000);
|
||||
events.ScheduleEvent(EVENT_GRIP, 15000);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if(!UpdateVictim())
|
||||
return;
|
||||
|
||||
events.Update(diff);
|
||||
|
||||
if(me->hasUnitState(UNIT_STAT_CASTING))
|
||||
return;
|
||||
|
||||
// TODO: because we are using hack, he is stunned and cannot cast, so we use triggered for every spell
|
||||
switch(events.GetEvent())
|
||||
{
|
||||
case EVENT_NONE: break;
|
||||
case EVENT_SMASH:
|
||||
if(left && right)
|
||||
DoCastVictim(SPELL_TWO_ARM_SMASH, true);
|
||||
else if(left || right)
|
||||
DoCastVictim(SPELL_ONE_ARM_SMASH, true);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_SWEEP:
|
||||
if(left)
|
||||
DoCastAOE(SPELL_ARM_SWEEP, true);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
case EVENT_GRIP:
|
||||
if(right)
|
||||
DoCastAOE(SPELL_STONE_GRIP, true);
|
||||
events.RepeatEvent(15000);
|
||||
break;
|
||||
default:
|
||||
events.PopEvent();
|
||||
break;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_kologarn(Creature* pCreature)
|
||||
{
|
||||
return new boss_kologarnAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_kologarn()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_kologarn";
|
||||
newscript->GetAI = &GetAI_boss_kologarn;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/* ScriptData
|
||||
SDName: razorscale
|
||||
SDAuthor: MaXiMiUS
|
||||
SD%Complete: 65
|
||||
EndScriptData */
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
//not in db
|
||||
#define SAY_AGGRO -2000000
|
||||
#define SAY_KILL -2000001
|
||||
#define SAY_PHASE_2_TRANS -2000002
|
||||
#define SAY_PHASE_3_TRANS -2000003
|
||||
#define EMOTE_BREATH -2000004
|
||||
|
||||
enum Spells
|
||||
{
|
||||
SPELL_FLAMEBUFFET = 64016,
|
||||
SPELL_FIREBALL = 62796,
|
||||
|
||||
SPELL_WINGBUFFET = 62666,
|
||||
SPELL_FLAMEBREATH = 63317,
|
||||
SPELL_FUSEARMOR = 64771,
|
||||
SPELL_DEVOURINGFLAME = 63014
|
||||
};
|
||||
|
||||
enum Mobs
|
||||
{
|
||||
NPC_DARK_RUNE_SENTINEL = 33846
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL boss_razorscaleAI : public BossAI
|
||||
{
|
||||
boss_razorscaleAI(Creature *pCreature) : BossAI(pCreature, TYPE_RAZORSCALE) {}
|
||||
|
||||
uint8 Phase;
|
||||
|
||||
uint32 FlameBreathTimer;
|
||||
uint32 FuseArmorTimer;
|
||||
uint32 DevouringFlameTimer;
|
||||
uint32 FlameBuffetTimer;
|
||||
uint32 SummonAddsTimer;
|
||||
uint32 WingBuffetTimer;
|
||||
uint32 FireballTimer;
|
||||
//uint32 StunTimer;
|
||||
//uint32 CastSpellsTimer;
|
||||
|
||||
bool InitialSpawn;
|
||||
bool IsFlying;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
Phase = 1;
|
||||
|
||||
FlyPhase(Phase, 0);
|
||||
|
||||
FlameBreathTimer = 20000;
|
||||
DevouringFlameTimer = 2000;
|
||||
FuseArmorTimer = 15000;
|
||||
FlameBuffetTimer = 3000;
|
||||
SummonAddsTimer = 45000;
|
||||
WingBuffetTimer = 17000;
|
||||
FireballTimer = 18000;
|
||||
//StunTimer = 30000;
|
||||
//CastSpellsTimer = 0;
|
||||
|
||||
InitialSpawn = true;
|
||||
IsFlying = true;
|
||||
|
||||
m_creature->ApplySpellImmune(0, IMMUNITY_STATE, SPELL_AURA_MOD_TAUNT, true);
|
||||
m_creature->ApplySpellImmune(1, IMMUNITY_EFFECT,SPELL_EFFECT_ATTACK_ME, true);
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO, m_creature);
|
||||
DoZoneInCombat();
|
||||
}
|
||||
|
||||
void JustDied(Unit* Killer)
|
||||
{
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
DoScriptText(SAY_KILL, m_creature);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if(m_creature->GetPositionY() > -60 || m_creature->GetPositionX() < 450) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles.
|
||||
{
|
||||
m_creature->RemoveAllAuras();
|
||||
m_creature->DeleteThreatList();
|
||||
m_creature->CombatStop(false);
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
// Victim is not controlled by a player (should never happen)
|
||||
if (m_creature->getVictim() && !m_creature->getVictim()->GetCharmerOrOwnerPlayerOrPlayerItself())
|
||||
m_creature->Kill(m_creature->getVictim());
|
||||
|
||||
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 99 && Phase == 1) // TODO: Only land (exit Phase 1) if brought down with harpoon guns! This is important!
|
||||
{
|
||||
Phase = 2;
|
||||
DoScriptText(SAY_PHASE_2_TRANS, m_creature); // Audio: "Move quickly! She won't remain grounded for long!"
|
||||
}
|
||||
|
||||
if ((m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 33 && Phase == 2) // Health under 33%, Razorscale can't fly anymore.
|
||||
{
|
||||
Phase = 3;
|
||||
DoScriptText(SAY_PHASE_3_TRANS, m_creature); // "Razorscale lands permanently!"
|
||||
// TODO: Cast Devouring Flame on all harpoon guns simultaneously, briefly after Phase 3 starts (lasts until the harpoon guns are destroyed)
|
||||
}
|
||||
|
||||
/*
|
||||
if (Phase == 2 && CastSpellsTimer > 0) // 5 seconds of spell casting, after stun breaks, during Phase 2
|
||||
{
|
||||
if (CastSpellsTimer <= diff) // 5 seconds are up
|
||||
Phase = 1; // Return to phase 1
|
||||
else
|
||||
CastSpellsTimer -= diff;
|
||||
}*/
|
||||
|
||||
FlyPhase(Phase, diff);
|
||||
|
||||
if (Phase >= 2) // Ground Phase (Phase 3 = permanent ground phase)
|
||||
{
|
||||
if (FuseArmorTimer <= diff)
|
||||
{
|
||||
DoCastVictim(SPELL_FUSEARMOR);
|
||||
FuseArmorTimer = 10000;
|
||||
} else FuseArmorTimer -= diff;
|
||||
|
||||
if (WingBuffetTimer <= diff)
|
||||
{
|
||||
DoCast(SPELL_WINGBUFFET);
|
||||
WingBuffetTimer = urand(7000,14000);
|
||||
} else WingBuffetTimer -= diff;
|
||||
|
||||
if (FireballTimer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
|
||||
{
|
||||
m_creature->SetInFront(pTarget);
|
||||
DoCast(pTarget, SPELL_FIREBALL);
|
||||
}
|
||||
|
||||
FireballTimer = 18000;
|
||||
} else FireballTimer -= diff;
|
||||
|
||||
if (FlameBreathTimer <= diff)
|
||||
{
|
||||
DoScriptText(EMOTE_BREATH, m_creature); // TODO: "Razorscale takes a deep breath..."
|
||||
DoCastVictim(SPELL_FLAMEBREATH);
|
||||
FlameBreathTimer = 15000;
|
||||
WingBuffetTimer = 0;
|
||||
} else FlameBreathTimer -= diff;
|
||||
|
||||
if (Phase == 3)
|
||||
{
|
||||
if (FlameBuffetTimer <= diff)
|
||||
{
|
||||
DoScriptText(EMOTE_BREATH, m_creature);
|
||||
std::list<Unit*> pTargets;
|
||||
SelectTargetList(pTargets, RAID_MODE(3,9), SELECT_TARGET_RANDOM, 100, true);
|
||||
uint8 i = 0;
|
||||
for (std::list<Unit*>::iterator itr = pTargets.begin(); itr != pTargets.end();)
|
||||
{
|
||||
if (m_creature->HasInArc(M_PI, *itr))
|
||||
{
|
||||
DoCast(*itr, SPELL_FLAMEBUFFET, true);
|
||||
++i;
|
||||
}
|
||||
if (++itr == pTargets.end() || i == RAID_MODE(3,9))
|
||||
{
|
||||
AttackStart(*--itr); // seems to attack targets randomly during perma-ground phase..
|
||||
break;
|
||||
}
|
||||
}
|
||||
FlameBuffetTimer = 25000;
|
||||
} else FlameBuffetTimer -= diff;
|
||||
}
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
else if (Phase == 1) //Flying Phase
|
||||
{
|
||||
if (InitialSpawn)
|
||||
SummonAdds();
|
||||
|
||||
InitialSpawn = false;
|
||||
|
||||
if (FireballTimer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
|
||||
{
|
||||
m_creature->SetInFront(pTarget);
|
||||
DoCast(pTarget, SPELL_FIREBALL);
|
||||
}
|
||||
|
||||
FireballTimer = 18000;
|
||||
} else FireballTimer -= diff;
|
||||
|
||||
if (DevouringFlameTimer <= diff)
|
||||
{
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
|
||||
{
|
||||
m_creature->SetInFront(pTarget);
|
||||
DoCast(pTarget, SPELL_DEVOURINGFLAME);
|
||||
}
|
||||
|
||||
DevouringFlameTimer = 10000;
|
||||
} else DevouringFlameTimer -= diff;
|
||||
|
||||
if (SummonAddsTimer <= diff)
|
||||
SummonAdds();
|
||||
else SummonAddsTimer -= diff;
|
||||
}
|
||||
}
|
||||
|
||||
void SummonAdds()
|
||||
{
|
||||
// TODO: Adds will come in waves from mole machines. One mole can spawn a Dark Rune Watcher
|
||||
// with 1-2 Guardians, or a lone Sentinel. Up to 4 mole machines can spawn adds at any given time.
|
||||
uint8 random = urand(1,4);
|
||||
for (uint8 i = 0; i < random; ++i)
|
||||
{
|
||||
if (Unit *pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 200, true))
|
||||
{
|
||||
float x = std::max(500.0f, std::min(650.0f, pTarget->GetPositionX() + irand(-20,20))); // Safe range is between 500 and 650
|
||||
float y = std::max(-235.0f, std::min(-145.0f, pTarget->GetPositionY() + irand(-20,20))); // Safe range is between -235 and -145
|
||||
float z = m_creature->GetBaseMap()->GetHeight(x, y, MAX_HEIGHT); // Ground level
|
||||
// TODO: Spawn drillers, then spawn adds 5 seconds later
|
||||
if (Creature *pAdd = m_creature->SummonCreature(NPC_DARK_RUNE_SENTINEL, x, y, z, 0, TEMPSUMMON_TIMED_OR_CORPSE_DESPAWN, 30000))
|
||||
pAdd->AI()->AttackStart(pTarget);
|
||||
}
|
||||
}
|
||||
SummonAddsTimer = 45000;
|
||||
}
|
||||
|
||||
void FlyPhase(uint8 Phase, const uint32 diff)
|
||||
{
|
||||
const float x = 587.54;
|
||||
const float y = -174.92;
|
||||
const float GroundLevel = m_creature->GetBaseMap()->GetHeight(x, y, MAX_HEIGHT);
|
||||
const float FlightHeight = GroundLevel + 4.0f; // TODO: Fly out of range of attacks (442 is sufficient height for this), minus ~(10*number of harpoon gun chains attached to Razorscale)
|
||||
|
||||
if (Phase == 1) // Always flying during Phase 1
|
||||
IsFlying = true;
|
||||
|
||||
m_creature->SetFlying(IsFlying);
|
||||
m_creature->SendMovementFlagUpdate();
|
||||
m_creature->SetSpeed(MOVE_WALK, IsFlying ? 7.0f : 2.5f, IsFlying);
|
||||
|
||||
if (Phase == 1) // Flying Phase
|
||||
{
|
||||
if (m_creature->GetPositionZ() > FlightHeight) // Correct height, stop moving
|
||||
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
|
||||
else // Incorrect height
|
||||
{
|
||||
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
|
||||
m_creature->GetMotionMaster()->MovePoint(0, x, y, FlightHeight + 0.5f); // Fly to slightly above (x, y, FlightHeight)
|
||||
}
|
||||
}
|
||||
else // Ground Phases
|
||||
{
|
||||
const float CurrentGroundLevel = m_creature->GetBaseMap()->GetHeight(m_creature->GetPositionX(), m_creature->GetPositionY(), MAX_HEIGHT);
|
||||
//if (StunTimer == 30000) // Only fly around if not stunned.
|
||||
//{
|
||||
m_creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
|
||||
if (IsFlying && m_creature->GetPositionZ() > CurrentGroundLevel) // Fly towards the ground
|
||||
m_creature->GetMotionMaster()->MovePoint(0, m_creature->GetPositionX(), m_creature->GetPositionY(), CurrentGroundLevel);
|
||||
// TODO: Swoop up just before landing
|
||||
else
|
||||
IsFlying = false; // Landed, no longer flying
|
||||
//}
|
||||
|
||||
//if (!IsFlying &&Phase == 2 && CastSpellsTimer == 0 && StunTimer >= diff) // No longer flying, non-permanent ground phase, and not casting spells
|
||||
//{
|
||||
// TODO: Add stun here. 30 second stun after Razorscale is grounded by harpoon guns
|
||||
//StunTimer -= diff;
|
||||
//}
|
||||
//else if (StunTimer != 30000 && (StunTimer < 0 || Phase == 3)) // Stun is active, and needs to end. Note: Stun breaks instantly if Phase 3 starts
|
||||
//{
|
||||
// TODO: Remove stun here.
|
||||
//DoCast(SPELL_WINGBUFFET); // "Used in the beginning of the phase."
|
||||
//WingBuffetTimer = urand(7000,14000);
|
||||
//StunTimer = 30000; // Reinitialize the stun timer
|
||||
//if (Phase == 2) // Non-permanent ground phase
|
||||
// CastSpellsTimer = 5000; // Five seconds of casting before returning to Phase 1
|
||||
//}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_razorscale(Creature* pCreature)
|
||||
{
|
||||
return new boss_razorscaleAI (pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_razorscale()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_razorscale";
|
||||
newscript->GetAI = &GetAI_boss_razorscale;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
/*
|
||||
#define SAY_AGGRO -1
|
||||
#define SAY_SLAY -1
|
||||
*/
|
||||
|
||||
struct TRINITY_DLL_DECL boss_thorimAI : public BossAI
|
||||
{
|
||||
boss_thorimAI(Creature* pCreature) : BossAI(pCreature, TYPE_THORIM)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
Reset();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
}
|
||||
|
||||
void KilledUnit(Unit *victim)
|
||||
{
|
||||
}
|
||||
|
||||
void JustDied(Unit *victim)
|
||||
{
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_THORIM, DONE);
|
||||
}
|
||||
|
||||
void Aggro(Unit* pWho)
|
||||
{
|
||||
// DoScriptText(SAY_AGGRO, m_creature);
|
||||
m_creature->SetInCombatWithZone();
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_THORIM, IN_PROGRESS);
|
||||
}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
//SPELLS TODO:
|
||||
|
||||
//
|
||||
DoMeleeAttackIfReady();
|
||||
|
||||
EnterEvadeIfOutOfCombatArea(diff);
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_thorim(Creature* pCreature)
|
||||
{
|
||||
return new boss_thorimAI(pCreature);
|
||||
}
|
||||
|
||||
void AddSC_boss_thorim()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_thorim";
|
||||
newscript->GetAI = &GetAI_boss_thorim;
|
||||
newscript->RegisterSelf();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
#define SPELL_SEARING_LIGHT 63018
|
||||
#define SPELL_SONIC_BOOM 38897
|
||||
|
||||
#define SAY_AGGRO -1000000
|
||||
#define SAY_SLAY -1000001
|
||||
|
||||
struct TRINITY_DLL_DECL boss_xt002_AI : public BossAI
|
||||
{
|
||||
boss_xt002_AI(Creature *pCreature) : BossAI(pCreature, TYPE_XT002)
|
||||
{
|
||||
m_pInstance = pCreature->GetInstanceData();
|
||||
}
|
||||
|
||||
ScriptedInstance* m_pInstance;
|
||||
|
||||
uint32 SEARING_LIGHT_Timer;
|
||||
uint32 SONIC_BOOM_Timer;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
SEARING_LIGHT_Timer = 100;
|
||||
SONIC_BOOM_Timer = 20;
|
||||
}
|
||||
|
||||
void EnterCombat(Unit* who)
|
||||
{
|
||||
DoScriptText(SAY_AGGRO,m_creature);
|
||||
}
|
||||
void KilledUnit(Unit* victim)
|
||||
{
|
||||
DoScriptText(SAY_SLAY, m_creature);
|
||||
}
|
||||
|
||||
void JustDied(Unit *victim)
|
||||
{
|
||||
DoScriptText(SAY_SLAY, m_creature);
|
||||
|
||||
if (m_pInstance)
|
||||
m_pInstance->SetData(TYPE_XT002, DONE);
|
||||
}
|
||||
|
||||
void MoveInLineOfSight(Unit* who) {}
|
||||
|
||||
void UpdateAI(const uint32 diff)
|
||||
{
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
if(m_creature->GetPositionX() < 700) // Not Blizzlike, anti-exploit to prevent players from pulling bosses to vehicles.
|
||||
{
|
||||
m_creature->RemoveAllAuras();
|
||||
m_creature->DeleteThreatList();
|
||||
m_creature->CombatStop(false);
|
||||
m_creature->GetMotionMaster()->MoveTargetedHome();
|
||||
}
|
||||
|
||||
if (SEARING_LIGHT_Timer <= diff)
|
||||
{
|
||||
DoCast(m_creature, SPELL_SEARING_LIGHT);
|
||||
DoScriptText(SAY_SLAY, m_creature);
|
||||
SEARING_LIGHT_Timer = 50000;
|
||||
} else SEARING_LIGHT_Timer -= diff;
|
||||
|
||||
if (SONIC_BOOM_Timer <= diff)
|
||||
{
|
||||
DoCast(m_creature->getVictim(), SPELL_SONIC_BOOM);
|
||||
SONIC_BOOM_Timer = 20000;
|
||||
} else SONIC_BOOM_Timer -= diff;
|
||||
|
||||
DoMeleeAttackIfReady();
|
||||
}
|
||||
};
|
||||
|
||||
CreatureAI* GetAI_boss_xt002(Creature* pCreature)
|
||||
{
|
||||
return new boss_xt002_AI (pCreature);
|
||||
}
|
||||
void AddSC_boss_xt002()
|
||||
{
|
||||
Script *newscript;
|
||||
|
||||
newscript = new Script;
|
||||
newscript->Name = "boss_xt002";
|
||||
newscript->GetAI = &GetAI_boss_xt002;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
@@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
enum eGameObjects
|
||||
{
|
||||
GO_Kologarn_CHEST_HERO = 195047,
|
||||
GO_Kologarn_CHEST = 195046,
|
||||
GO_Thorim_CHEST_HERO = 194315,
|
||||
GO_Thorim_CHEST = 194314,
|
||||
GO_Hodir_CHEST_HERO = 194308,
|
||||
GO_Hodir_CHEST = 194307,
|
||||
GO_Freya_CHEST_HERO = 194325,
|
||||
GO_Freya_CHEST = 194324,
|
||||
};
|
||||
|
||||
struct TRINITY_DLL_DECL instance_ulduar : public ScriptedInstance
|
||||
{
|
||||
instance_ulduar(Map* pMap) : ScriptedInstance(pMap), KologarnChest(NULL), ThorimChest(NULL), HodirChest(NULL), FreyaChest(NULL) { Initialize(); };
|
||||
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
std::string m_strInstData;
|
||||
|
||||
uint64 m_uiLeviathanGUID;
|
||||
uint64 m_uiIgnisGUID;
|
||||
uint64 m_uiRazorscaleGUID;
|
||||
uint64 m_uiXT002GUID;
|
||||
uint64 m_auiAssemblyGUIDs[3];
|
||||
uint64 m_uiKologarnGUID;
|
||||
uint64 m_uiAuriayaGUID;
|
||||
uint64 m_uiMimironGUID;
|
||||
uint64 m_uiHodirGUID;
|
||||
uint64 m_uiThorimGUID;
|
||||
uint64 m_uiFreyaGUID;
|
||||
uint64 m_uiVezaxGUID;
|
||||
uint64 m_uiYoggSaronGUID;
|
||||
uint64 m_uiAlgalonGUID;
|
||||
|
||||
GameObject* KologarnChest, *ThorimChest, *HodirChest, *FreyaChest;
|
||||
|
||||
void Initialize()
|
||||
{
|
||||
m_uiLeviathanGUID = 0;
|
||||
m_uiIgnisGUID = 0;
|
||||
m_uiRazorscaleGUID = 0;
|
||||
m_uiXT002GUID = 0;
|
||||
m_uiKologarnGUID = 0;
|
||||
m_uiAuriayaGUID = 0;
|
||||
m_uiMimironGUID = 0;
|
||||
m_uiHodirGUID = 0;
|
||||
m_uiThorimGUID = 0;
|
||||
m_uiFreyaGUID = 0;
|
||||
m_uiVezaxGUID = 0;
|
||||
m_uiYoggSaronGUID = 0;
|
||||
m_uiAlgalonGUID = 0;
|
||||
KologarnChest = 0;
|
||||
ThorimChest = 0;
|
||||
HodirChest = 0;
|
||||
FreyaChest = 0;
|
||||
|
||||
memset(&m_auiEncounter, 0, sizeof(m_auiEncounter));
|
||||
memset(&m_auiAssemblyGUIDs, 0, sizeof(m_auiAssemblyGUIDs));
|
||||
}
|
||||
|
||||
bool IsEncounterInProgress() const
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* pCreature, bool add)
|
||||
{
|
||||
switch(pCreature->GetEntry())
|
||||
{
|
||||
case NPC_LEVIATHAN:
|
||||
m_uiLeviathanGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_IGNIS:
|
||||
m_uiIgnisGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_RAZORSCALE:
|
||||
m_uiRazorscaleGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_XT002:
|
||||
m_uiXT002GUID = pCreature->GetGUID();
|
||||
break;
|
||||
|
||||
// Assembly of Iron
|
||||
case NPC_STEELBREAKER:
|
||||
m_auiAssemblyGUIDs[0] = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_MOLGEIM:
|
||||
m_auiAssemblyGUIDs[1] = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_BRUNDIR:
|
||||
m_auiAssemblyGUIDs[2] = pCreature->GetGUID();
|
||||
break;
|
||||
|
||||
case NPC_KOLOGARN:
|
||||
m_uiKologarnGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_AURIAYA:
|
||||
m_uiAuriayaGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_MIMIRON:
|
||||
m_uiMimironGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_HODIR:
|
||||
m_uiHodirGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_THORIM:
|
||||
m_uiThorimGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_FREYA:
|
||||
m_uiFreyaGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_VEZAX:
|
||||
m_uiVezaxGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_YOGGSARON:
|
||||
m_uiYoggSaronGUID = pCreature->GetGUID();
|
||||
break;
|
||||
case NPC_ALGALON:
|
||||
m_uiAlgalonGUID = pCreature->GetGUID();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* pGo, bool add)
|
||||
{
|
||||
switch(pGo->GetEntry())
|
||||
{
|
||||
case GO_Kologarn_CHEST_HERO: KologarnChest = add ? pGo : NULL; break;
|
||||
case GO_Kologarn_CHEST: KologarnChest = add ? pGo : NULL; break;
|
||||
case GO_Thorim_CHEST_HERO: ThorimChest = add ? pGo : NULL; break;
|
||||
case GO_Thorim_CHEST: ThorimChest = add ? pGo : NULL; break;
|
||||
case GO_Hodir_CHEST_HERO: HodirChest = add ? pGo : NULL; break;
|
||||
case GO_Hodir_CHEST: HodirChest = add ? pGo : NULL; break;
|
||||
case GO_Freya_CHEST_HERO: FreyaChest = add ? pGo : NULL; break;
|
||||
case GO_Freya_CHEST: FreyaChest = add ? pGo : NULL; break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TYPE_LEVIATHAN:
|
||||
case TYPE_IGNIS:
|
||||
case TYPE_RAZORSCALE:
|
||||
case TYPE_XT002:
|
||||
case TYPE_ASSEMBLY:
|
||||
case TYPE_KOLOGARN:
|
||||
m_auiEncounter[TYPE_KOLOGARN] = data;
|
||||
if (data == DONE && KologarnChest)
|
||||
KologarnChest->SetRespawnTime(KologarnChest->GetRespawnDelay());
|
||||
case TYPE_AURIAYA:
|
||||
case TYPE_MIMIRON:
|
||||
case TYPE_HODIR:
|
||||
m_auiEncounter[TYPE_HODIR] = data;
|
||||
if (data == DONE && HodirChest)
|
||||
HodirChest->SetRespawnTime(HodirChest->GetRespawnDelay());
|
||||
case TYPE_THORIM:
|
||||
m_auiEncounter[TYPE_THORIM] = data;
|
||||
if (data == DONE && ThorimChest)
|
||||
ThorimChest->SetRespawnTime(ThorimChest->GetRespawnDelay());
|
||||
case TYPE_FREYA:
|
||||
m_auiEncounter[TYPE_FREYA] = data;
|
||||
if (data == DONE && FreyaChest)
|
||||
FreyaChest->SetRespawnTime(FreyaChest->GetRespawnDelay());
|
||||
case TYPE_VEZAX:
|
||||
case TYPE_YOGGSARON:
|
||||
case TYPE_ALGALON:
|
||||
m_auiEncounter[type] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE)
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
saveStream << m_auiEncounter[i] << " ";
|
||||
|
||||
m_strInstData = saveStream.str();
|
||||
|
||||
SaveToDB();
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
}
|
||||
}
|
||||
|
||||
uint64 GetData64(uint32 data)
|
||||
{
|
||||
switch(data)
|
||||
{
|
||||
case TYPE_LEVIATHAN:
|
||||
return m_uiLeviathanGUID;
|
||||
case TYPE_IGNIS:
|
||||
return m_uiIgnisGUID;
|
||||
case TYPE_RAZORSCALE:
|
||||
return m_uiRazorscaleGUID;
|
||||
case TYPE_XT002:
|
||||
return m_uiXT002GUID;
|
||||
case TYPE_KOLOGARN:
|
||||
return m_uiKologarnGUID;
|
||||
case TYPE_AURIAYA:
|
||||
return m_uiAuriayaGUID;
|
||||
case TYPE_MIMIRON:
|
||||
return m_uiMimironGUID;
|
||||
case TYPE_HODIR:
|
||||
return m_uiMimironGUID;
|
||||
case TYPE_THORIM:
|
||||
return m_uiThorimGUID;
|
||||
case TYPE_FREYA:
|
||||
return m_uiFreyaGUID;
|
||||
case TYPE_VEZAX:
|
||||
return m_uiVezaxGUID;
|
||||
case TYPE_YOGGSARON:
|
||||
return m_uiYoggSaronGUID;
|
||||
case TYPE_ALGALON:
|
||||
return m_uiAlgalonGUID;
|
||||
|
||||
// Assembly of Iron
|
||||
case DATA_STEELBREAKER:
|
||||
return m_auiAssemblyGUIDs[0];
|
||||
case DATA_MOLGEIM:
|
||||
return m_auiAssemblyGUIDs[1];
|
||||
case DATA_BRUNDIR:
|
||||
return m_auiAssemblyGUIDs[2];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 GetData(uint32 type)
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case TYPE_LEVIATHAN:
|
||||
case TYPE_IGNIS:
|
||||
case TYPE_RAZORSCALE:
|
||||
case TYPE_XT002:
|
||||
case TYPE_ASSEMBLY:
|
||||
case TYPE_KOLOGARN:
|
||||
case TYPE_AURIAYA:
|
||||
case TYPE_MIMIRON:
|
||||
case TYPE_HODIR:
|
||||
case TYPE_THORIM:
|
||||
case TYPE_FREYA:
|
||||
case TYPE_VEZAX:
|
||||
case TYPE_YOGGSARON:
|
||||
case TYPE_ALGALON:
|
||||
return m_auiEncounter[type];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetSaveData()
|
||||
{
|
||||
OUT_SAVE_INST_DATA;
|
||||
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "U U " << 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] << " " << m_auiEncounter[9] << " " << m_auiEncounter[10] << " " << m_auiEncounter[11]
|
||||
<< m_auiEncounter[12] << " " << m_auiEncounter[13];
|
||||
|
||||
m_strInstData = saveStream.str();
|
||||
|
||||
OUT_SAVE_INST_DATA_COMPLETE;
|
||||
return m_strInstData;
|
||||
}
|
||||
|
||||
void Load(const char* strIn)
|
||||
{
|
||||
if (!strIn)
|
||||
{
|
||||
OUT_LOAD_INST_DATA_FAIL;
|
||||
return;
|
||||
}
|
||||
|
||||
OUT_LOAD_INST_DATA(strIn);
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
uint32 data0, data1, data2, data3, data4, data5, data6,
|
||||
data7, data8, data9, data10, data11, data12, data13;
|
||||
|
||||
std::istringstream loadStream(strIn);
|
||||
loadStream >> dataHead1 >> dataHead2 >> data0 >> data1 >> data2 >> data3 >> data4 >> data5 >> data6
|
||||
>> data7 >> data8 >> data9 >> data10 >> data11 >> data12 >> data13;
|
||||
|
||||
if (dataHead1 == 'U' && dataHead2 == 'U')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
|
||||
{
|
||||
loadStream >> m_auiEncounter[i];
|
||||
|
||||
if (m_auiEncounter[i] == IN_PROGRESS)
|
||||
m_auiEncounter[i] = NOT_STARTED;
|
||||
}
|
||||
}
|
||||
OUT_LOAD_INST_DATA_COMPLETE;
|
||||
}
|
||||
};
|
||||
|
||||
InstanceData* GetInstanceData_instance_ulduar(Map* pMap)
|
||||
{
|
||||
return new instance_ulduar(pMap);
|
||||
}
|
||||
|
||||
void AddSC_instance_ulduar()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "instance_ulduar";
|
||||
newscript->GetInstanceData = &GetInstanceData_instance_ulduar;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
||||
*
|
||||
* 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
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef DEF_ULDUAR_H
|
||||
#define DEF_ULDUAR_H
|
||||
|
||||
enum eTypes
|
||||
{
|
||||
MAX_ENCOUNTER = 14,
|
||||
|
||||
TYPE_LEVIATHAN = 0,
|
||||
TYPE_IGNIS = 1,
|
||||
TYPE_RAZORSCALE = 2,
|
||||
TYPE_XT002 = 3,
|
||||
TYPE_ASSEMBLY = 4,
|
||||
TYPE_KOLOGARN = 5,
|
||||
TYPE_AURIAYA = 6,
|
||||
TYPE_MIMIRON = 7,
|
||||
TYPE_HODIR = 8,
|
||||
TYPE_THORIM = 9,
|
||||
TYPE_FREYA = 10,
|
||||
TYPE_VEZAX = 11,
|
||||
TYPE_YOGGSARON = 12,
|
||||
TYPE_ALGALON = 13,
|
||||
|
||||
DATA_STEELBREAKER = 20,
|
||||
DATA_MOLGEIM = 21,
|
||||
DATA_BRUNDIR = 22,
|
||||
DATA_RUNEMASTER_MOLGEIM = 23,
|
||||
DATA_STORMCALLER_BRUNDIR = 24,
|
||||
|
||||
NPC_LEVIATHAN = 33113,
|
||||
NPC_IGNIS = 33118,
|
||||
NPC_RAZORSCALE = 33186,
|
||||
NPC_XT002 = 33293,
|
||||
NPC_STEELBREAKER = 32867,
|
||||
NPC_MOLGEIM = 32927,
|
||||
NPC_BRUNDIR = 32857,
|
||||
NPC_KOLOGARN = 32930,
|
||||
NPC_AURIAYA = 33515,
|
||||
NPC_MIMIRON = 33350,
|
||||
NPC_HODIR = 32845,
|
||||
NPC_THORIM = 32865,
|
||||
NPC_FREYA = 32906,
|
||||
NPC_VEZAX = 33271,
|
||||
NPC_YOGGSARON = 33288,
|
||||
NPC_ALGALON = 32871
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,92 @@
|
||||
#include "ScriptedPch.h"
|
||||
#include "ulduar.h"
|
||||
|
||||
/*
|
||||
The teleporter appears to be active and stable.
|
||||
|
||||
- Expedition Base Camp
|
||||
- Formation Grounds
|
||||
- Colossal Forge
|
||||
- Scrapyard
|
||||
- Antechamber of Ulduar
|
||||
- Shattered Walkway
|
||||
- Conservatory of Life
|
||||
*/
|
||||
|
||||
#define BASE_CAMP 200
|
||||
#define GROUNDS 201
|
||||
#define FORGE 202
|
||||
#define SCRAPYARD 203
|
||||
#define ANTECHAMBER 204
|
||||
#define WALKWAY 205
|
||||
#define CONSERVATORY 206
|
||||
|
||||
bool GoHello_ulduar_teleporter( Player *pPlayer, GameObject *pGO )
|
||||
{
|
||||
ScriptedInstance *pInstance = (ScriptedInstance *) pGO->GetInstanceData();
|
||||
if(!pInstance) return true;
|
||||
|
||||
pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Expedition Base Camp", GOSSIP_SENDER_MAIN, BASE_CAMP);
|
||||
pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Formation Grounds", GOSSIP_SENDER_MAIN, GROUNDS);
|
||||
if(pInstance->GetData(TYPE_LEVIATHAN) == DONE)
|
||||
{
|
||||
pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Colossal Forge", GOSSIP_SENDER_MAIN, FORGE);
|
||||
if(pInstance->GetData(TYPE_XT002) == DONE)
|
||||
{
|
||||
pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Scrapyard", GOSSIP_SENDER_MAIN, SCRAPYARD);
|
||||
pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Antechamber of Ulduar", GOSSIP_SENDER_MAIN, ANTECHAMBER);
|
||||
if(pInstance->GetData(TYPE_KOLOGARN) == DONE)
|
||||
{
|
||||
pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Shattered Walkway", GOSSIP_SENDER_MAIN, WALKWAY);
|
||||
if(pInstance->GetData(TYPE_AURIAYA) == DONE)
|
||||
pPlayer->ADD_GOSSIP_ITEM(0, "Teleport to the Conservatory of Life", GOSSIP_SENDER_MAIN, CONSERVATORY);
|
||||
}
|
||||
}
|
||||
}
|
||||
pPlayer->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, pGO->GetGUID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GOSelect_ulduar_teleporter( Player *pPlayer, GameObject *pGO, uint32 sender, uint32 action )
|
||||
{
|
||||
if(sender != GOSSIP_SENDER_MAIN) return true;
|
||||
if(!pPlayer->getAttackers().empty()) return true;
|
||||
|
||||
switch(action)
|
||||
{
|
||||
case BASE_CAMP:
|
||||
pPlayer->TeleportTo(603, -706.122, -92.6024, 429.876, 0);
|
||||
pPlayer->CLOSE_GOSSIP_MENU(); break;
|
||||
case GROUNDS:
|
||||
pPlayer->TeleportTo(603, 131.248, -35.3802, 409.804, 0);
|
||||
pPlayer->CLOSE_GOSSIP_MENU(); break;
|
||||
case FORGE:
|
||||
pPlayer->TeleportTo(603, 553.233, -12.3247, 409.679, 0);
|
||||
pPlayer->CLOSE_GOSSIP_MENU(); break;
|
||||
case SCRAPYARD:
|
||||
pPlayer->TeleportTo(603, 926.292, -11.4635, 418.595, 0);
|
||||
pPlayer->CLOSE_GOSSIP_MENU(); break;
|
||||
case ANTECHAMBER:
|
||||
pPlayer->TeleportTo(603, 1498.09, -24.246, 420.967, 0);
|
||||
pPlayer->CLOSE_GOSSIP_MENU(); break;
|
||||
case WALKWAY:
|
||||
pPlayer->TeleportTo(603, 1859.45, -24.1, 448.9, 0);
|
||||
pPlayer->CLOSE_GOSSIP_MENU(); break;
|
||||
case CONSERVATORY:
|
||||
pPlayer->TeleportTo(603, 2086.27, -24.3134, 421.239, 0);
|
||||
pPlayer->CLOSE_GOSSIP_MENU(); break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void AddSC_ulduar_teleporter()
|
||||
{
|
||||
Script *newscript;
|
||||
newscript = new Script;
|
||||
newscript->Name = "ulduar_teleporter";
|
||||
newscript->pGOHello = &GoHello_ulduar_teleporter;
|
||||
newscript->pGOSelect = &GOSelect_ulduar_teleporter;
|
||||
newscript->RegisterSelf();
|
||||
}
|
||||
Reference in New Issue
Block a user