[SD2] Massive improvements on Garr encounter

This commit is contained in:
stormrage-project 2015-09-07 14:44:19 +02:00 committed by Antz
parent bdd3dc43a3
commit 654968ad81
3 changed files with 171 additions and 30 deletions

View File

@ -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)

View File

@ -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

View File

@ -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