Skip to content

Commit

Permalink
Chromaggus adjustments and bug fixes (#2169)
Browse files Browse the repository at this point in the history
* Adjust ability timers + affliction targeting

Shimmer 45 to 20 secs
Affliction 4 to 7.5 secs
Change application behavior to attempt cast at a random unit 15 times
Removed pointless code to change health at time lapse fade out.

* Handle CC spells that force target swap in spellauras.cpp

Instead of doing them in the script file of individual mobs

* Affliction wave number of casts

On top of the randomness of hitting one unit more than once per wave, there's also the randomness of how many attempts is made per wave. Warcraft logs shows 11 to 15
  • Loading branch information
balakethelock authored Nov 11, 2023
1 parent 5f2d7d6 commit d63c885
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 73 deletions.
9 changes: 9 additions & 0 deletions src/game/Spells/SpellAuras.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6866,6 +6866,15 @@ SpellAuraHolder::SpellAuraHolder(SpellEntry const* spellproto, Unit* target, Uni
m_makesTargetSecondaryFocus = !GetSpellProto()->IsPositiveSpell() && (GetSpellProto()->HasAuraInterruptFlag(AURA_INTERRUPT_DAMAGE_CANCELS)
|| m_spellProto->HasAura(SPELL_AURA_MOD_CONFUSE)
|| m_spellProto->HasAura(SPELL_AURA_MOD_FEAR));
// Exception spells for targetsecondaryfocus:
switch (m_spellProto->Id)
{
case 23310: // Chromaggus Time Lapse
case 23312: // Chromaggus Time Lapse
m_makesTargetSecondaryFocus = true;
break;

}
}

void SpellAuraHolder::AddAura(Aura* aura, SpellEffectIndex index)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,6 @@ enum

static uint32 const aPossibleBreaths[MAX_BREATHS] = {SPELL_INCINERATE, SPELL_TIME_LAPSE, SPELL_CORROSIVE_ACID, SPELL_IGNITE_FLESH, SPELL_FROST_BURN};

struct TimeLapseInfo
{
TimeLapseInfo(ObjectGuid const targetGuid, float const targetThreat, uint32 const targetHealth) : m_targetGuid(targetGuid), m_targetThreat(targetThreat), m_targetHealth(targetHealth) { }
ObjectGuid const m_targetGuid;
float const m_targetThreat;
uint32 const m_targetHealth;
};

struct boss_chromaggusAI : public ScriptedAI
{
boss_chromaggusAI(Creature* pCreature) : ScriptedAI(pCreature), m_uiBreathOneSpell(0), m_uiBreathTwoSpell(0)
Expand Down Expand Up @@ -110,7 +102,6 @@ struct boss_chromaggusAI : public ScriptedAI
bool m_bEnraged;
bool m_bEngagedOnce;

std::vector<TimeLapseInfo*> m_vTimeLapseInfo;
typedef std::vector<ObjectGuid> AfflictionGuids;
AfflictionGuids m_lRedAfflictionPlayerGUID;
AfflictionGuids m_lChromaticPlayerGUID;
Expand All @@ -121,11 +112,11 @@ struct boss_chromaggusAI : public ScriptedAI

m_uiCurrentVulnerabilitySpell = 0; // We use this to store our last vulnerability spell so we can remove it later

m_uiShimmerTimer = 0; // Time till we change vurlnerabilites
m_uiBreathOneTimer = 30000; // First breath is 30 seconds
m_uiBreathTwoTimer = 60000; // Second is 1 minute so that we can alternate
m_uiAfflictionTimer = 4000; // This is special - 5 seconds means that we cast this on 1 pPlayer every 5 sconds
m_uiFrenzyTimer = 15000;
m_uiShimmerTimer = 0; // Vulnurability is applied at pull. Changes every 20 secs.
m_uiBreathOneTimer = 30000; // First breath happens in 30 secs. Repeats every 60 secs.
m_uiBreathTwoTimer = 60000; // Second breath happens in 60 secs. Repeats every 60 secs.
m_uiAfflictionTimer = 7500; // Afflictions are applied every 7.5 secs.
m_uiFrenzyTimer = 15000; // Frenzy happens every 15 secs.

m_bEnraged = false;
m_lRedAfflictionPlayerGUID.clear();
Expand All @@ -148,10 +139,6 @@ struct boss_chromaggusAI : public ScriptedAI
else
m_creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_SPAWNING | UNIT_FLAG_IMMUNE_TO_NPC);
}

for (const auto& itr : m_vTimeLapseInfo)
delete itr;
m_vTimeLapseInfo.clear();
}

void MoveInLineOfSight(Unit *pUnit) override
Expand All @@ -177,9 +164,6 @@ struct boss_chromaggusAI : public ScriptedAI
{
if (m_pInstance)
m_pInstance->SetData(TYPE_CHROMAGGUS, DONE);
for (const auto& itr : m_vTimeLapseInfo)
delete itr;
m_vTimeLapseInfo.clear();
}

void JustReachedHome() override
Expand All @@ -193,14 +177,13 @@ struct boss_chromaggusAI : public ScriptedAI
if (!pTarget)
return;

/* Better to do this in SpellAuras.cpp
if (pSpell->Id == SPELL_TIME_LAPSE)
{
if (SpellAuraHolder* holder = pTarget->GetSpellAuraHolder(SPELL_TIME_LAPSE))
holder->SetTargetSecondaryThreatFocus(true);
if (pTarget->GetTypeId() != TYPEID_PLAYER)
return;
m_vTimeLapseInfo.push_back(new TimeLapseInfo(pTarget->GetObjectGuid(), m_creature->GetThreatManager().getThreat(pTarget), pTarget->GetHealth()));
}
*/
}

void MovementInform(uint32 uiType, uint32 uiPointId) override
Expand Down Expand Up @@ -255,20 +238,6 @@ struct boss_chromaggusAI : public ScriptedAI
if (!m_creature->SelectHostileTarget() || !m_creature->GetVictim())
return;

for (std::vector<TimeLapseInfo*>::iterator itr = m_vTimeLapseInfo.begin(); itr != m_vTimeLapseInfo.end(); ++itr)
if (Player* pTarget = m_creature->GetMap()->GetPlayer((*itr)->m_targetGuid))
{
if (!pTarget->HasAura(SPELL_TIME_LAPSE) && pTarget->IsAlive())
{
if ((*itr)->m_targetHealth >= (pTarget->GetMaxHealth() / 2))
pTarget->SetHealth(pTarget->GetMaxHealth());
delete *itr;
m_vTimeLapseInfo.erase(itr--);
}
}
else
m_vTimeLapseInfo.erase(itr--);

// Shimmer Timer Timer
if (m_uiShimmerTimer < uiDiff)
{
Expand Down Expand Up @@ -302,7 +271,7 @@ struct boss_chromaggusAI : public ScriptedAI
m_uiCurrentVulnerabilitySpell = uiSpell;

DoScriptText(EMOTE_SHIMMER, m_creature);
m_uiShimmerTimer = 45000;
m_uiShimmerTimer = 20000;
}
}
else
Expand Down Expand Up @@ -351,56 +320,51 @@ struct boss_chromaggusAI : public ScriptedAI
break;
}

std::vector<ObjectGuid> m_vPossibleVictim;
ThreatList const& tList = m_creature->GetThreatManager().getThreatList();
for (const auto itr : tList)
if (Player* target = m_creature->GetMap()->GetPlayer(itr->getUnitGuid()))
m_vPossibleVictim.push_back(target->GetObjectGuid());

int affli_rand = urand(0, 18);
for (int i = 0; i < affli_rand; ++i)
for (int i = 0; i < urand(11, 15); ++i) // Affliction is applied 11-15 times per cast. Creatures such as pets can be targetted
{
if (m_vPossibleVictim.empty())
break;
std::vector<ObjectGuid>::iterator it = m_vPossibleVictim.begin() + urand(0, m_vPossibleVictim.size() - 1);
if (Player* pPlayer = m_creature->GetMap()->GetPlayer(*it))
if (Unit* afflictionTarget = m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0))
{
if (afflictionTarget->HasAura(SPELL_CHROMATIC_MUT_1)) // To make sure mutated players are not being targeted with affliction.
continue;

// Cast affliction
if (DoCastSpellIfCan(pPlayer, m_uiSpellAfflict, CF_TRIGGERED) == CAST_OK)
if (DoCastSpellIfCan(afflictionTarget, m_uiSpellAfflict, CF_TRIGGERED) == CAST_OK)
{
if (m_uiSpellAfflict == SPELL_BROODAF_RED)
m_lRedAfflictionPlayerGUID.push_back(pPlayer->GetObjectGuid());
if (m_uiSpellAfflict == SPELL_BROODAF_RED && afflictionTarget->GetTypeId() == TYPEID_PLAYER)
m_lRedAfflictionPlayerGUID.push_back(afflictionTarget->GetObjectGuid());
}
// Chromatic mutation if target is effected by all afflictions
if (pPlayer->HasAura(SPELL_BROODAF_BLUE)
&& pPlayer->HasAura(SPELL_BROODAF_BLACK)
&& pPlayer->HasAura(SPELL_BROODAF_RED)
&& pPlayer->HasAura(SPELL_BROODAF_BRONZE)
&& pPlayer->HasAura(SPELL_BROODAF_GREEN))
if (afflictionTarget->HasAura(SPELL_BROODAF_BLUE)
&& afflictionTarget->HasAura(SPELL_BROODAF_BLACK)
&& afflictionTarget->HasAura(SPELL_BROODAF_RED)
&& afflictionTarget->HasAura(SPELL_BROODAF_BRONZE)
&& afflictionTarget->HasAura(SPELL_BROODAF_GREEN))
{
pPlayer->RemoveAurasDueToSpell(SPELL_BROODAF_BLUE);
pPlayer->RemoveAurasDueToSpell(SPELL_BROODAF_BLACK);
pPlayer->RemoveAurasDueToSpell(SPELL_BROODAF_RED);
pPlayer->RemoveAurasDueToSpell(SPELL_BROODAF_BRONZE);
pPlayer->RemoveAurasDueToSpell(SPELL_BROODAF_GREEN);
afflictionTarget->RemoveAurasDueToSpell(SPELL_BROODAF_BLUE);
afflictionTarget->RemoveAurasDueToSpell(SPELL_BROODAF_BLACK);
afflictionTarget->RemoveAurasDueToSpell(SPELL_BROODAF_RED);
afflictionTarget->RemoveAurasDueToSpell(SPELL_BROODAF_BRONZE);
afflictionTarget->RemoveAurasDueToSpell(SPELL_BROODAF_GREEN);

if (DoCastSpellIfCan(pPlayer, SPELL_CHROMATIC_MUT_1) == CAST_OK)
if (afflictionTarget->GetTypeId() == TYPEID_PLAYER) // Only players are mutated
{
// More Chromatic Mutation buffs
pPlayer->AddAura(23175); //Mod DMG 500% + Mod Haste Melee 100 + Mod Haste Spell 300
pPlayer->AddAura(23177); //Max Health 10000 + Mod healing 1000%
m_lChromaticPlayerGUID.push_back(pPlayer->GetObjectGuid());
afflictionTarget->AddAura(SPELL_CHROMATIC_MUT_1, ADD_AURA_NO_OPTION, m_creature); // Main MC aura
afflictionTarget->AddAura(23175); // Mod DMG 500% + Mod Haste Melee 100 + Mod Haste Spell 300
afflictionTarget->AddAura(23177); // Max Health 10000 + Mod healing 1000%
m_lChromaticPlayerGUID.push_back(afflictionTarget->GetObjectGuid());
}
else // Pets die instantly
afflictionTarget->DealDamage(afflictionTarget, afflictionTarget->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false);

}
}
m_vPossibleVictim.erase(it);
}
m_uiAfflictionTimer = 4000;
m_uiAfflictionTimer = 7500;
}
else
m_uiAfflictionTimer -= uiDiff;

// If player dies from a direct hit or dot while he had the aura SPELL_BROODAF_RED
// If player dies while he had the aura SPELL_BROODAF_RED
for (AfflictionGuids::iterator itr = m_lRedAfflictionPlayerGUID.begin(); itr != m_lRedAfflictionPlayerGUID.end();)
{
Player* pTarget = m_creature->GetMap()->GetPlayer(*itr);
Expand All @@ -419,7 +383,7 @@ struct boss_chromaggusAI : public ScriptedAI
++itr;
}

// If player dies from a direct hit or dot while he had the aura SPELL_CHROMATIC_MUT_1
// If player dies while he had the aura SPELL_CHROMATIC_MUT_1
for (AfflictionGuids::iterator itr = m_lChromaticPlayerGUID.begin(); itr != m_lChromaticPlayerGUID.end();)
{
if (Player* pTarget = m_creature->GetMap()->GetPlayer(*itr))
Expand Down

0 comments on commit d63c885

Please sign in to comment.