[SD2] Massive improvements on Garr encounter
This commit is contained in:
parent
bdd3dc43a3
commit
654968ad81
@ -40,13 +40,13 @@ enum
|
|||||||
// Garr spells
|
// Garr spells
|
||||||
SPELL_ANTIMAGICPULSE = 19492,
|
SPELL_ANTIMAGICPULSE = 19492,
|
||||||
SPELL_MAGMASHACKLES = 19496,
|
SPELL_MAGMASHACKLES = 19496,
|
||||||
SPELL_ENRAGE = 19516, // TODO Stacking enrage (stacks to 10 times)
|
SPELL_ERUPTION_TRIGGER = 20482, // target script, dispel and permanent immune to banish anywhere on map
|
||||||
|
SPELL_ENRAGE_TRIGGER = 19515, // target script, effect dummy anywhere on map
|
||||||
|
|
||||||
// Add spells
|
// Add spells
|
||||||
SPELL_ERUPTION = 19497,
|
SPELL_ERUPTION = 19497,
|
||||||
SPELL_MASSIVE_ERUPTION = 20483, // TODO possible on death
|
SPELL_MASSIVE_ERUPTION = 20483, // TODO possible on death
|
||||||
SPELL_IMMOLATE = 20294,
|
SPELL_IMMOLATE = 20294,
|
||||||
SPELL_SEPARATION_ANXIETY = 23492, // Used if separated too far from Garr, 21095 use unknown.
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct boss_garr : public CreatureScript
|
struct boss_garr : public CreatureScript
|
||||||
@ -64,11 +64,15 @@ struct boss_garr : public CreatureScript
|
|||||||
|
|
||||||
uint32 m_uiAntiMagicPulseTimer;
|
uint32 m_uiAntiMagicPulseTimer;
|
||||||
uint32 m_uiMagmaShacklesTimer;
|
uint32 m_uiMagmaShacklesTimer;
|
||||||
|
uint32 m_uiExplodeAddTimer;
|
||||||
|
bool m_bHasFreed;
|
||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
m_uiAntiMagicPulseTimer = 25000;
|
m_uiAntiMagicPulseTimer = 25 * IN_MILLISECONDS;
|
||||||
m_uiMagmaShacklesTimer = 15000;
|
m_uiMagmaShacklesTimer = 15 * IN_MILLISECONDS;
|
||||||
|
m_uiExplodeAddTimer = 60 * IN_MILLISECONDS;
|
||||||
|
m_bHasFreed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Aggro(Unit* /*pWho*/) override
|
void Aggro(Unit* /*pWho*/) override
|
||||||
@ -95,6 +99,25 @@ struct boss_garr : public CreatureScript
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DamageTaken(Unit *damager, uint32 &damage) override
|
||||||
|
{
|
||||||
|
if (!m_bHasFreed && m_creature->HealthBelowPctDamaged(50, damage))
|
||||||
|
{
|
||||||
|
m_pInstance->SetData(TYPE_DO_FREE_GARR_ADDS, 0);
|
||||||
|
m_bHasFreed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveAIEvent(AIEventType type, Creature* pSender, Unit* /*pInvoker*/, uint32 /*uiData*/) override
|
||||||
|
{
|
||||||
|
if (type == AI_EVENT_CUSTOM_B && pSender == m_creature)
|
||||||
|
{
|
||||||
|
if (Creature* spawn = m_creature->SummonCreature(NPC_FIRESWORN, m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), m_creature->GetOrientation(), TEMPSUMMON_CORPSE_DESPAWN, true))
|
||||||
|
spawn->SetOwnerGuid(ObjectGuid()); // trying to prevent despawn of the summon at Garr death
|
||||||
|
m_uiExplodeAddTimer = 25 * IN_MILLISECONDS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateAI(const uint32 uiDiff) override
|
void UpdateAI(const uint32 uiDiff) override
|
||||||
{
|
{
|
||||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||||
@ -107,26 +130,33 @@ struct boss_garr : public CreatureScript
|
|||||||
{
|
{
|
||||||
if (DoCastSpellIfCan(m_creature, SPELL_ANTIMAGICPULSE) == CAST_OK)
|
if (DoCastSpellIfCan(m_creature, SPELL_ANTIMAGICPULSE) == CAST_OK)
|
||||||
{
|
{
|
||||||
m_uiAntiMagicPulseTimer = urand(10000, 15000);
|
m_uiAntiMagicPulseTimer = urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else m_uiAntiMagicPulseTimer -= uiDiff;
|
||||||
{
|
|
||||||
m_uiAntiMagicPulseTimer -= uiDiff;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MagmaShackles_Timer
|
// MagmaShackles_Timer
|
||||||
if (m_uiMagmaShacklesTimer < uiDiff)
|
if (m_uiMagmaShacklesTimer < uiDiff)
|
||||||
{
|
{
|
||||||
if (DoCastSpellIfCan(m_creature, SPELL_MAGMASHACKLES) == CAST_OK)
|
if (DoCastSpellIfCan(m_creature, SPELL_MAGMASHACKLES) == CAST_OK)
|
||||||
{
|
{
|
||||||
m_uiMagmaShacklesTimer = urand(8000, 12000);
|
m_uiMagmaShacklesTimer = urand(8 * IN_MILLISECONDS, 12 * IN_MILLISECONDS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else m_uiMagmaShacklesTimer -= uiDiff;
|
||||||
|
|
||||||
|
// Explode an add
|
||||||
|
if (m_uiExplodeAddTimer < uiDiff)
|
||||||
{
|
{
|
||||||
m_uiMagmaShacklesTimer -= uiDiff;
|
if (urand(0, 1)) // 50% chance to explode, is it too much?
|
||||||
|
{
|
||||||
|
ObjectGuid guid = m_pInstance->GetGuid(NPC_FIRESWORN);
|
||||||
|
if (Creature* firesworn = m_pInstance->instance->GetCreature(guid))
|
||||||
|
SendAIEvent(AI_EVENT_CUSTOM_A, firesworn, firesworn, SPELL_MASSIVE_ERUPTION); // this is an instant explosion with no SPELL_ERUPTION_TRIGGER
|
||||||
|
}
|
||||||
|
m_uiExplodeAddTimer = 15 * IN_MILLISECONDS;
|
||||||
}
|
}
|
||||||
|
else m_uiExplodeAddTimer -= uiDiff;
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
@ -156,30 +186,37 @@ struct mob_firesworn : public CreatureScript
|
|||||||
|
|
||||||
void Reset() override
|
void Reset() override
|
||||||
{
|
{
|
||||||
m_uiImmolateTimer = urand(4000, 8000); // These times are probably wrong
|
m_uiImmolateTimer = urand(4 * IN_MILLISECONDS, 8 * IN_MILLISECONDS); // These times are probably wrong
|
||||||
m_uiSeparationCheckTimer = 5000;
|
m_uiSeparationCheckTimer = 5 * IN_MILLISECONDS;
|
||||||
|
m_bExploding = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DamageTaken(Unit* /*pDealer*/, uint32& uiDamage) override
|
||||||
|
{
|
||||||
|
if (!m_bExploding && m_creature->HealthBelowPctDamaged(10, uiDamage))
|
||||||
|
{
|
||||||
|
ReceiveAIEvent(AI_EVENT_CUSTOM_A, m_creature, m_creature, SPELL_ERUPTION);
|
||||||
|
uiDamage = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReceiveAIEvent(AIEventType type, Creature* /*pSender*/, Unit* pInvoker, uint32 uiData) override
|
||||||
|
{
|
||||||
|
if (type == AI_EVENT_CUSTOM_A && pInvoker == m_creature)
|
||||||
|
{
|
||||||
|
m_creature->CastSpell(m_creature, uiData, true);
|
||||||
|
m_creature->ForcedDespawn(100);
|
||||||
|
m_bExploding = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(const uint32 uiDiff) override
|
void UpdateAI(const uint32 uiDiff) override
|
||||||
{
|
{
|
||||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() || m_bExploding)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Immolate_Timer
|
|
||||||
if (m_uiImmolateTimer < uiDiff)
|
|
||||||
{
|
|
||||||
if (Unit* pTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
|
|
||||||
{
|
|
||||||
if (DoCastSpellIfCan(pTarget, SPELL_IMMOLATE) == CAST_OK)
|
|
||||||
{
|
|
||||||
m_uiImmolateTimer = urand(5000, 10000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else { m_uiImmolateTimer -= uiDiff; }
|
|
||||||
|
|
||||||
if (m_uiSeparationCheckTimer < uiDiff)
|
if (m_uiSeparationCheckTimer < uiDiff)
|
||||||
{
|
{
|
||||||
// Distance guesswork, but should be ok
|
// Distance guesswork, but should be ok
|
||||||
@ -191,10 +228,20 @@ struct mob_firesworn : public CreatureScript
|
|||||||
|
|
||||||
m_uiSeparationCheckTimer = 5000;
|
m_uiSeparationCheckTimer = 5000;
|
||||||
}
|
}
|
||||||
else
|
else m_uiSeparationCheckTimer -= uiDiff;
|
||||||
|
|
||||||
|
// Immolate_Timer
|
||||||
|
if (m_uiImmolateTimer < uiDiff)
|
||||||
{
|
{
|
||||||
m_uiSeparationCheckTimer -= uiDiff;
|
if (Unit* pTarget = SelectAttackTarget(ATTACKING_TARGET_RANDOM, 0, SPELL_IMMOLATE))
|
||||||
|
{
|
||||||
|
if (DoCastSpellIfCan(pTarget, SPELL_IMMOLATE, CAST_TRIGGERED) == CAST_OK)
|
||||||
|
{
|
||||||
|
m_uiImmolateTimer = urand(5 * IN_MILLISECONDS, 10 * IN_MILLISECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else m_uiImmolateTimer -= uiDiff;
|
||||||
|
|
||||||
// Cast Erruption and let them die
|
// Cast Erruption and let them die
|
||||||
if (m_creature->GetHealthPercent() <= 10.0f)
|
if (m_creature->GetHealthPercent() <= 10.0f)
|
||||||
|
@ -89,6 +89,48 @@ struct is_molten_core : public InstanceScript
|
|||||||
case NPC_MAJORDOMO:
|
case NPC_MAJORDOMO:
|
||||||
m_mNpcEntryGuidStore[pCreature->GetEntry()] = pCreature->GetObjectGuid();
|
m_mNpcEntryGuidStore[pCreature->GetEntry()] = pCreature->GetObjectGuid();
|
||||||
break;
|
break;
|
||||||
|
case NPC_FIRESWORN:
|
||||||
|
m_sFireswornGUID.insert(pCreature->GetObjectGuid());
|
||||||
|
break;
|
||||||
|
case NPC_LAVA_SURGER:
|
||||||
|
if (GetData(TYPE_GARR) == DONE)
|
||||||
|
pCreature->ForcedDespawn(500);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCreatureDeath(Creature* pCreature) override
|
||||||
|
{
|
||||||
|
switch (pCreature->GetEntry())
|
||||||
|
{
|
||||||
|
case NPC_FIRESWORN:
|
||||||
|
m_sFireswornGUID.erase(pCreature->GetObjectGuid());
|
||||||
|
if (Creature* pGarr = GetSingleCreatureFromStorage(NPC_GARR))
|
||||||
|
{
|
||||||
|
if (pGarr->IsAlive())
|
||||||
|
{
|
||||||
|
pGarr->CastSpell(pGarr, SPELL_GARR_ENRAGE, true);
|
||||||
|
pGarr->CastSpell(pGarr, SPELL_GARR_ARMOR_DEBUFF, true);
|
||||||
|
|
||||||
|
if (!m_sFireswornGUID.size())
|
||||||
|
pGarr->AI()->ReceiveAIEvent(AI_EVENT_CUSTOM_B, pGarr, pGarr, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void OnCreatureDespawn(Creature* pCreature) override
|
||||||
|
{
|
||||||
|
switch (pCreature->GetEntry())
|
||||||
|
{
|
||||||
|
case NPC_FIRESWORN:
|
||||||
|
OnCreatureDeath(pCreature);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +201,16 @@ struct is_molten_core : public InstanceScript
|
|||||||
case TYPE_RAGNAROS:
|
case TYPE_RAGNAROS:
|
||||||
m_auiEncounter[uiType] = uiData;
|
m_auiEncounter[uiType] = uiData;
|
||||||
break;
|
break;
|
||||||
|
case TYPE_DO_FREE_GARR_ADDS:
|
||||||
|
for (std::set<ObjectGuid>::const_iterator it = m_sFireswornGUID.begin(); it != m_sFireswornGUID.end(); ++it)
|
||||||
|
{
|
||||||
|
ObjectGuid guid = *it;
|
||||||
|
int32 bp0 = 0;
|
||||||
|
if (Creature* firesworn = instance->GetCreature(guid))
|
||||||
|
if (firesworn->IsAlive())
|
||||||
|
firesworn->CastCustomSpell(firesworn, SPELL_SEPARATION_ANXIETY, &bp0, NULL, NULL, true);
|
||||||
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if Majordomo can be summoned
|
// Check if Majordomo can be summoned
|
||||||
@ -194,6 +246,28 @@ struct is_molten_core : public InstanceScript
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint64 GetData64(uint32 uiType) const override
|
||||||
|
{
|
||||||
|
switch (uiType)
|
||||||
|
{
|
||||||
|
case NPC_FIRESWORN:
|
||||||
|
{
|
||||||
|
Creature* garr = GetSingleCreatureFromStorage(NPC_GARR);
|
||||||
|
for (std::set<ObjectGuid>::const_iterator it = m_sFireswornGUID.begin(); it != m_sFireswornGUID.end(); ++it)
|
||||||
|
{
|
||||||
|
ObjectGuid guid = *it;
|
||||||
|
if (Creature* firesworn = instance->GetCreature(guid))
|
||||||
|
if (firesworn->IsAlive() && firesworn->IsWithinDistInMap(garr, 20.0f, false))
|
||||||
|
return guid.GetRawValue();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
const char* Save() const override { return m_strInstData.c_str(); }
|
const char* Save() const override { return m_strInstData.c_str(); }
|
||||||
void Load(const char* chrIn) override
|
void Load(const char* chrIn) override
|
||||||
{
|
{
|
||||||
@ -280,6 +354,8 @@ struct is_molten_core : public InstanceScript
|
|||||||
|
|
||||||
std::string m_strInstData;
|
std::string m_strInstData;
|
||||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||||
|
uint32 m_auiRuneState[MAX_MOLTEN_RUNES];
|
||||||
|
std::set<ObjectGuid> m_sFireswornGUID;
|
||||||
};
|
};
|
||||||
|
|
||||||
InstanceData* GetInstanceData(Map* pMap) override
|
InstanceData* GetInstanceData(Map* pMap) override
|
||||||
|
@ -40,6 +40,18 @@ enum
|
|||||||
TYPE_SULFURON = 7,
|
TYPE_SULFURON = 7,
|
||||||
TYPE_MAJORDOMO = 8,
|
TYPE_MAJORDOMO = 8,
|
||||||
TYPE_RAGNAROS = 9,
|
TYPE_RAGNAROS = 9,
|
||||||
|
TYPE_FLAME_DOSED = MAX_ENCOUNTER,
|
||||||
|
TYPE_DO_FREE_GARR_ADDS = MAX_ENCOUNTER+1,
|
||||||
|
|
||||||
|
MAX_MOLTEN_RUNES = 7,
|
||||||
|
|
||||||
|
TYPE_RUNE_KRESS = 0,
|
||||||
|
TYPE_RUNE_MOHN = 1,
|
||||||
|
TYPE_RUNE_BLAZ = 2,
|
||||||
|
TYPE_RUNE_MAZJ = 3,
|
||||||
|
TYPE_RUNE_ZETH = 4,
|
||||||
|
TYPE_RUNE_THERI = 5,
|
||||||
|
TYPE_RUNE_KORO = 6,
|
||||||
|
|
||||||
NPC_LUCIFRON = 12118,
|
NPC_LUCIFRON = 12118,
|
||||||
NPC_MAGMADAR = 11982,
|
NPC_MAGMADAR = 11982,
|
||||||
@ -61,6 +73,7 @@ enum
|
|||||||
NPC_FLAMEWAKER_PRIEST = 11662, // Sulfuron
|
NPC_FLAMEWAKER_PRIEST = 11662, // Sulfuron
|
||||||
NPC_FLAMEWAKER_HEALER = 11663, // Majordomo
|
NPC_FLAMEWAKER_HEALER = 11663, // Majordomo
|
||||||
NPC_FLAMEWAKER_ELITE = 11664, // Majordomo
|
NPC_FLAMEWAKER_ELITE = 11664, // Majordomo
|
||||||
|
NPC_LAVA_SURGER = 12101,
|
||||||
|
|
||||||
GO_LAVA_STEAM = 178107,
|
GO_LAVA_STEAM = 178107,
|
||||||
GO_LAVA_SPLASH = 178108,
|
GO_LAVA_SPLASH = 178108,
|
||||||
@ -77,6 +90,11 @@ enum
|
|||||||
MAX_MAJORDOMO_ADDS = 8,
|
MAX_MAJORDOMO_ADDS = 8,
|
||||||
FACTION_MAJORDOMO_FRIENDLY = 1080,
|
FACTION_MAJORDOMO_FRIENDLY = 1080,
|
||||||
SAY_MAJORDOMO_SPAWN = -1409004,
|
SAY_MAJORDOMO_SPAWN = -1409004,
|
||||||
|
|
||||||
|
// Garr encounter spells
|
||||||
|
SPELL_GARR_ENRAGE = 19516,
|
||||||
|
SPELL_GARR_ARMOR_DEBUFF = 20481,
|
||||||
|
SPELL_SEPARATION_ANXIETY = 23492, // selfcast, for 5 sec: dmg +300% and banish immunity
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sSpawnLocation
|
struct sSpawnLocation
|
||||||
|
Loading…
x
Reference in New Issue
Block a user