[SD2] Massive improvements on Garr encounter
This commit is contained in:
parent
bdd3dc43a3
commit
654968ad81
@ -40,13 +40,13 @@ enum
|
||||
// Garr spells
|
||||
SPELL_ANTIMAGICPULSE = 19492,
|
||||
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
|
||||
SPELL_ERUPTION = 19497,
|
||||
SPELL_MASSIVE_ERUPTION = 20483, // TODO possible on death
|
||||
SPELL_IMMOLATE = 20294,
|
||||
SPELL_SEPARATION_ANXIETY = 23492, // Used if separated too far from Garr, 21095 use unknown.
|
||||
};
|
||||
|
||||
struct boss_garr : public CreatureScript
|
||||
@ -64,11 +64,15 @@ struct boss_garr : public CreatureScript
|
||||
|
||||
uint32 m_uiAntiMagicPulseTimer;
|
||||
uint32 m_uiMagmaShacklesTimer;
|
||||
uint32 m_uiExplodeAddTimer;
|
||||
bool m_bHasFreed;
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiAntiMagicPulseTimer = 25000;
|
||||
m_uiMagmaShacklesTimer = 15000;
|
||||
m_uiAntiMagicPulseTimer = 25 * IN_MILLISECONDS;
|
||||
m_uiMagmaShacklesTimer = 15 * IN_MILLISECONDS;
|
||||
m_uiExplodeAddTimer = 60 * IN_MILLISECONDS;
|
||||
m_bHasFreed = false;
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
@ -107,26 +130,33 @@ struct boss_garr : public CreatureScript
|
||||
{
|
||||
if (DoCastSpellIfCan(m_creature, SPELL_ANTIMAGICPULSE) == CAST_OK)
|
||||
{
|
||||
m_uiAntiMagicPulseTimer = urand(10000, 15000);
|
||||
m_uiAntiMagicPulseTimer = urand(10 * IN_MILLISECONDS, 15 * IN_MILLISECONDS);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_uiAntiMagicPulseTimer -= uiDiff;
|
||||
}
|
||||
else m_uiAntiMagicPulseTimer -= uiDiff;
|
||||
|
||||
// MagmaShackles_Timer
|
||||
if (m_uiMagmaShacklesTimer < uiDiff)
|
||||
{
|
||||
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();
|
||||
}
|
||||
@ -156,30 +186,37 @@ struct mob_firesworn : public CreatureScript
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
m_uiImmolateTimer = urand(4000, 8000); // These times are probably wrong
|
||||
m_uiSeparationCheckTimer = 5000;
|
||||
m_uiImmolateTimer = urand(4 * IN_MILLISECONDS, 8 * IN_MILLISECONDS); // These times are probably wrong
|
||||
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
|
||||
{
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim())
|
||||
if (!m_creature->SelectHostileTarget() || !m_creature->getVictim() || m_bExploding)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// Distance guesswork, but should be ok
|
||||
@ -191,10 +228,20 @@ struct mob_firesworn : public CreatureScript
|
||||
|
||||
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
|
||||
if (m_creature->GetHealthPercent() <= 10.0f)
|
||||
|
@ -89,6 +89,48 @@ struct is_molten_core : public InstanceScript
|
||||
case NPC_MAJORDOMO:
|
||||
m_mNpcEntryGuidStore[pCreature->GetEntry()] = pCreature->GetObjectGuid();
|
||||
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:
|
||||
m_auiEncounter[uiType] = uiData;
|
||||
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
|
||||
@ -194,6 +246,28 @@ struct is_molten_core : public InstanceScript
|
||||
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(); }
|
||||
void Load(const char* chrIn) override
|
||||
{
|
||||
@ -280,6 +354,8 @@ struct is_molten_core : public InstanceScript
|
||||
|
||||
std::string m_strInstData;
|
||||
uint32 m_auiEncounter[MAX_ENCOUNTER];
|
||||
uint32 m_auiRuneState[MAX_MOLTEN_RUNES];
|
||||
std::set<ObjectGuid> m_sFireswornGUID;
|
||||
};
|
||||
|
||||
InstanceData* GetInstanceData(Map* pMap) override
|
||||
|
@ -40,6 +40,18 @@ enum
|
||||
TYPE_SULFURON = 7,
|
||||
TYPE_MAJORDOMO = 8,
|
||||
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_MAGMADAR = 11982,
|
||||
@ -61,6 +73,7 @@ enum
|
||||
NPC_FLAMEWAKER_PRIEST = 11662, // Sulfuron
|
||||
NPC_FLAMEWAKER_HEALER = 11663, // Majordomo
|
||||
NPC_FLAMEWAKER_ELITE = 11664, // Majordomo
|
||||
NPC_LAVA_SURGER = 12101,
|
||||
|
||||
GO_LAVA_STEAM = 178107,
|
||||
GO_LAVA_SPLASH = 178108,
|
||||
@ -77,6 +90,11 @@ enum
|
||||
MAX_MAJORDOMO_ADDS = 8,
|
||||
FACTION_MAJORDOMO_FRIENDLY = 1080,
|
||||
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
|
||||
|
Loading…
x
Reference in New Issue
Block a user