Fix Script Naxxramass Thaddius/Stalagg/Feugen
- Stalagg and Feugen respawn if the other adds not dead within 5 sec. - Thaddius start combat timers as soon as both are killed. - Fix Thaddius flags after a crash - Fix global variables used for adds alive flag. --HG-- branch : trunk
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
* Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "ScriptedPch.h"
|
#include "ScriptedPch.h"
|
||||||
#include "naxxramas.h"
|
#include "naxxramas.h"
|
||||||
|
#include "SpellId.h"
|
||||||
|
|
||||||
//Stalagg
|
//Stalagg
|
||||||
enum StalaggYells
|
enum StalaggYells
|
||||||
@@ -29,8 +30,10 @@ enum StalaggYells
|
|||||||
|
|
||||||
enum StalagSpells
|
enum StalagSpells
|
||||||
{
|
{
|
||||||
SPELL_POWERSURGE = 54529,
|
SPELL_POWERSURGE = SPELL_POWER_SURGE_28134,
|
||||||
H_SPELL_POWERSURGE = 28134
|
H_SPELL_POWERSURGE = SPELL_POWER_SURGE_54529,
|
||||||
|
SPELL_MAGNETIC_PULL = SPELL_MAGNETIC_PULL_28338,
|
||||||
|
SPELL_STALAGG_TESLA = SPELL_STALAGG_TESLA_PASSIVE_28097
|
||||||
};
|
};
|
||||||
|
|
||||||
//Feugen
|
//Feugen
|
||||||
@@ -43,8 +46,18 @@ enum FeugenYells
|
|||||||
|
|
||||||
enum FeugenSpells
|
enum FeugenSpells
|
||||||
{
|
{
|
||||||
SPELL_STATICFIELD = 28135,
|
SPELL_STATICFIELD = SPELL_STATIC_FIELD_28135,
|
||||||
H_SPELL_STATICFIELD = 54528
|
H_SPELL_STATICFIELD = SPELL_STATIC_FIELD_54528,
|
||||||
|
SPELL_FEUGEN_TESLA = SPELL_FEUGEN_TESLA_PASSIVE_28109
|
||||||
|
};
|
||||||
|
|
||||||
|
// Thaddius DoAction
|
||||||
|
enum ThaddiusActions
|
||||||
|
{
|
||||||
|
ACTION_FEUGEN_RESET,
|
||||||
|
ACTION_FEUGEN_DIED,
|
||||||
|
ACTION_STALAGG_RESET,
|
||||||
|
ACTION_STALAGG_DIED
|
||||||
};
|
};
|
||||||
|
|
||||||
//generic
|
//generic
|
||||||
@@ -68,11 +81,11 @@ enum ThaddiusYells
|
|||||||
|
|
||||||
enum ThaddiusSpells
|
enum ThaddiusSpells
|
||||||
{
|
{
|
||||||
SPELL_POLARITY_SHIFT = 28089,
|
SPELL_POLARITY_SHIFT = SPELL_POLARITY_SHIFT_28089,
|
||||||
SPELL_BALL_LIGHTNING = 28299,
|
SPELL_BALL_LIGHTNING = SPELL_BALL_LIGHTNING_28299,
|
||||||
SPELL_CHAIN_LIGHTNING = 28167,
|
SPELL_CHAIN_LIGHTNING = SPELL_CHAIN_LIGHTNING_28167,
|
||||||
H_SPELL_CHAIN_LIGHTNING = 54531,
|
H_SPELL_CHAIN_LIGHTNING = SPELL_CHAIN_LIGHTNING_54531,
|
||||||
SPELL_BERSERK = 27680
|
SPELL_BERSERK = SPELL_BERSERK_27680
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Events
|
enum Events
|
||||||
@@ -83,16 +96,38 @@ enum Events
|
|||||||
EVENT_BERSERK,
|
EVENT_BERSERK,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool CheckStalaggAlive = true;
|
|
||||||
bool CheckFeugenAlive = true;
|
|
||||||
|
|
||||||
struct TRINITY_DLL_DECL boss_thaddiusAI : public BossAI
|
struct TRINITY_DLL_DECL boss_thaddiusAI : public BossAI
|
||||||
{
|
{
|
||||||
boss_thaddiusAI(Creature *c) : BossAI(c, BOSS_THADDIUS)
|
boss_thaddiusAI(Creature *c) : BossAI(c, BOSS_THADDIUS)
|
||||||
|
{
|
||||||
|
// init is a bit tricky because thaddius shall track the life of both adds, but not if there was a wipe
|
||||||
|
// and, in particular, if there was a crash after both adds were killed (should not respawn)
|
||||||
|
|
||||||
|
// Moreover, the adds may not yet be spawn. So just track down the status if mob is spawn
|
||||||
|
// and each mob will send its status at reset (meaning that it is alive)
|
||||||
|
checkFeugenAlive = false;
|
||||||
|
if (Creature *pFeugen = m_creature->GetCreature(*m_creature, instance->GetData64(DATA_FEUGEN)))
|
||||||
|
checkFeugenAlive = pFeugen->isAlive();
|
||||||
|
|
||||||
|
checkStalaggAlive = false;
|
||||||
|
if (Creature *pStalagg = m_creature->GetCreature(*m_creature, instance->GetData64(DATA_STALAGG)))
|
||||||
|
checkStalaggAlive = pStalagg->isAlive();
|
||||||
|
|
||||||
|
if (!checkFeugenAlive && !checkStalaggAlive)
|
||||||
|
{
|
||||||
|
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
|
||||||
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
|
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
|
||||||
me->SetReactState(REACT_PASSIVE);
|
me->SetReactState(REACT_PASSIVE);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool checkStalaggAlive;
|
||||||
|
bool checkFeugenAlive;
|
||||||
|
uint32 uiAddsTimer;
|
||||||
|
|
||||||
void KilledUnit(Unit* victim)
|
void KilledUnit(Unit* victim)
|
||||||
{
|
{
|
||||||
@@ -106,6 +141,37 @@ struct TRINITY_DLL_DECL boss_thaddiusAI : public BossAI
|
|||||||
DoScriptText(SAY_DEATH, me);
|
DoScriptText(SAY_DEATH, me);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DoAction(const int32 action)
|
||||||
|
{
|
||||||
|
switch(action)
|
||||||
|
{
|
||||||
|
case ACTION_FEUGEN_RESET:
|
||||||
|
checkFeugenAlive = true;
|
||||||
|
break;
|
||||||
|
case ACTION_FEUGEN_DIED:
|
||||||
|
checkFeugenAlive = false;
|
||||||
|
break;
|
||||||
|
case ACTION_STALAGG_RESET:
|
||||||
|
checkStalaggAlive = true;
|
||||||
|
break;
|
||||||
|
case ACTION_STALAGG_DIED:
|
||||||
|
checkStalaggAlive = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checkFeugenAlive && !checkStalaggAlive)
|
||||||
|
{
|
||||||
|
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
|
||||||
|
// REACT_AGGRESSIVE only reset when he takes damage.
|
||||||
|
DoZoneInCombat();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
|
||||||
|
me->SetReactState(REACT_PASSIVE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void EnterCombat(Unit *who)
|
void EnterCombat(Unit *who)
|
||||||
{
|
{
|
||||||
_EnterCombat();
|
_EnterCombat();
|
||||||
@@ -115,11 +181,34 @@ struct TRINITY_DLL_DECL boss_thaddiusAI : public BossAI
|
|||||||
events.ScheduleEvent(EVENT_BERSERK, 360000);
|
events.ScheduleEvent(EVENT_BERSERK, 360000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DamageTaken(Unit *pDoneBy, uint32 &uiDamage)
|
||||||
|
{
|
||||||
|
me->SetReactState(REACT_AGGRESSIVE);
|
||||||
|
}
|
||||||
|
|
||||||
void UpdateAI(const uint32 diff)
|
void UpdateAI(const uint32 diff)
|
||||||
{
|
{
|
||||||
if (CheckStalaggAlive == false && CheckFeugenAlive == false) {
|
if (checkFeugenAlive && checkStalaggAlive)
|
||||||
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
|
uiAddsTimer = 0;
|
||||||
me->SetReactState(REACT_AGGRESSIVE);
|
|
||||||
|
if (checkStalaggAlive != checkFeugenAlive)
|
||||||
|
{
|
||||||
|
uiAddsTimer += diff;
|
||||||
|
if (uiAddsTimer > 5000)
|
||||||
|
{
|
||||||
|
if (!checkStalaggAlive)
|
||||||
|
{
|
||||||
|
if (instance)
|
||||||
|
if (Creature *pStalagg = m_creature->GetCreature(*m_creature, instance->GetData64(DATA_STALAGG)))
|
||||||
|
pStalagg->Respawn();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (instance)
|
||||||
|
if (Creature *pFeugen = m_creature->GetCreature(*m_creature, instance->GetData64(DATA_FEUGEN)))
|
||||||
|
pFeugen->Respawn();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!UpdateVictim())
|
if (!UpdateVictim())
|
||||||
@@ -162,27 +251,74 @@ CreatureAI* GetAI_boss_thaddius(Creature* pCreature)
|
|||||||
|
|
||||||
struct TRINITY_DLL_DECL mob_stalaggAI : public ScriptedAI
|
struct TRINITY_DLL_DECL mob_stalaggAI : public ScriptedAI
|
||||||
{
|
{
|
||||||
mob_stalaggAI(Creature *c) : ScriptedAI(c) {}
|
mob_stalaggAI(Creature *c) : ScriptedAI(c)
|
||||||
|
|
||||||
uint32 PowerSurgeTimer;
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
{
|
||||||
PowerSurgeTimer = urand(20000,25000);
|
pInstance = c->GetInstanceData();
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptedInstance* pInstance;
|
||||||
|
|
||||||
|
uint32 powerSurgeTimer;
|
||||||
|
uint32 magneticPullTimer;
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
if (pInstance)
|
||||||
|
if (Creature *pThaddius = m_creature->GetCreature(*m_creature, pInstance->GetData64(DATA_THADDIUS)))
|
||||||
|
if (pThaddius->AI())
|
||||||
|
pThaddius->AI()->DoAction(ACTION_STALAGG_RESET);
|
||||||
|
powerSurgeTimer = urand(20000,25000);
|
||||||
|
magneticPullTimer = 20000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnterCombat(Unit *pWho)
|
||||||
|
{
|
||||||
|
DoCast(SPELL_STALAGG_TESLA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit *killer)
|
void JustDied(Unit *killer)
|
||||||
{
|
{
|
||||||
CheckStalaggAlive = false;
|
if (pInstance)
|
||||||
|
if (Creature *pThaddius = m_creature->GetCreature(*m_creature, pInstance->GetData64(DATA_THADDIUS)))
|
||||||
|
if (pThaddius->AI())
|
||||||
|
pThaddius->AI()->DoAction(ACTION_STALAGG_DIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(const uint32 uiDiff)
|
void UpdateAI(const uint32 uiDiff)
|
||||||
{
|
{
|
||||||
if (PowerSurgeTimer <= uiDiff)
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (magneticPullTimer <= uiDiff)
|
||||||
|
{
|
||||||
|
if (Creature *pFeugen = m_creature->GetCreature(*m_creature, pInstance->GetData64(DATA_FEUGEN)))
|
||||||
|
{
|
||||||
|
Unit* pStalaggVictim = m_creature->getVictim();
|
||||||
|
Unit* pFeugenVictim = pFeugen->getVictim();
|
||||||
|
|
||||||
|
if (pFeugenVictim && pStalaggVictim)
|
||||||
|
{
|
||||||
|
// magnetic pull is not working. So just jump.
|
||||||
|
|
||||||
|
// reset aggro to be sure that feugen will not follow the jump
|
||||||
|
pFeugen->getThreatManager().modifyThreatPercent(pFeugenVictim, -100);
|
||||||
|
pFeugenVictim->JumpTo(m_creature, 0.3f);
|
||||||
|
|
||||||
|
m_creature->getThreatManager().modifyThreatPercent(pStalaggVictim, -100);
|
||||||
|
pStalaggVictim->JumpTo(pFeugen, 0.3f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
magneticPullTimer = 20000;
|
||||||
|
}
|
||||||
|
else magneticPullTimer -= uiDiff;
|
||||||
|
|
||||||
|
if (powerSurgeTimer <= uiDiff)
|
||||||
{
|
{
|
||||||
DoCast(m_creature, RAID_MODE(SPELL_POWERSURGE, H_SPELL_POWERSURGE));
|
DoCast(m_creature, RAID_MODE(SPELL_POWERSURGE, H_SPELL_POWERSURGE));
|
||||||
PowerSurgeTimer = urand(15000,20000);
|
powerSurgeTimer = urand(15000,20000);
|
||||||
} else PowerSurgeTimer -= uiDiff;
|
} else powerSurgeTimer -= uiDiff;
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -194,28 +330,48 @@ CreatureAI* GetAI_mob_stalagg(Creature* pCreature)
|
|||||||
|
|
||||||
struct TRINITY_DLL_DECL mob_feugenAI : public ScriptedAI
|
struct TRINITY_DLL_DECL mob_feugenAI : public ScriptedAI
|
||||||
{
|
{
|
||||||
mob_feugenAI(Creature *c) : ScriptedAI(c) {}
|
mob_feugenAI(Creature *c) : ScriptedAI(c)
|
||||||
|
|
||||||
uint32 StaticFieldTimer;
|
|
||||||
uint32 Checktimer;
|
|
||||||
|
|
||||||
void reset()
|
|
||||||
{
|
{
|
||||||
StaticFieldTimer = 5000;
|
pInstance = c->GetInstanceData();
|
||||||
|
}
|
||||||
|
|
||||||
|
ScriptedInstance* pInstance;
|
||||||
|
|
||||||
|
uint32 staticFieldTimer;
|
||||||
|
|
||||||
|
void Reset()
|
||||||
|
{
|
||||||
|
if (pInstance)
|
||||||
|
if (Creature *pThaddius = m_creature->GetCreature(*m_creature, pInstance->GetData64(DATA_THADDIUS)))
|
||||||
|
if (pThaddius->AI())
|
||||||
|
pThaddius->AI()->DoAction(ACTION_FEUGEN_RESET);
|
||||||
|
staticFieldTimer = 5000;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EnterCombat(Unit *pWho)
|
||||||
|
{
|
||||||
|
DoCast(SPELL_FEUGEN_TESLA);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JustDied(Unit *killer)
|
void JustDied(Unit *killer)
|
||||||
{
|
{
|
||||||
CheckFeugenAlive = false;
|
if (pInstance)
|
||||||
|
if (Creature *pThaddius = m_creature->GetCreature(*m_creature, pInstance->GetData64(DATA_THADDIUS)))
|
||||||
|
if (pThaddius->AI())
|
||||||
|
pThaddius->AI()->DoAction(ACTION_FEUGEN_DIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UpdateAI(const uint32 uiDiff)
|
void UpdateAI(const uint32 uiDiff)
|
||||||
{
|
{
|
||||||
if (StaticFieldTimer <= uiDiff)
|
if (!UpdateVictim())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (staticFieldTimer <= uiDiff)
|
||||||
{
|
{
|
||||||
DoCast(m_creature, RAID_MODE(SPELL_STATICFIELD, H_SPELL_STATICFIELD));
|
DoCast(m_creature, RAID_MODE(SPELL_STATICFIELD, H_SPELL_STATICFIELD));
|
||||||
StaticFieldTimer = 5000;
|
staticFieldTimer = 5000;
|
||||||
} else StaticFieldTimer -= uiDiff;
|
} else staticFieldTimer -= uiDiff;
|
||||||
|
|
||||||
DoMeleeAttackIfReady();
|
DoMeleeAttackIfReady();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
/* Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
@@ -115,6 +115,9 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData
|
|||||||
uint64 uiBaron;
|
uint64 uiBaron;
|
||||||
uint64 uiSir;
|
uint64 uiSir;
|
||||||
|
|
||||||
|
uint64 uiThaddius;
|
||||||
|
uint64 uiFeugen;
|
||||||
|
uint64 uiStalagg;
|
||||||
|
|
||||||
void OnCreatureCreate(Creature* pCreature, bool add)
|
void OnCreatureCreate(Creature* pCreature, bool add)
|
||||||
{
|
{
|
||||||
@@ -126,6 +129,9 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData
|
|||||||
case 16065: uiLady = pCreature->GetGUID(); return;
|
case 16065: uiLady = pCreature->GetGUID(); return;
|
||||||
case 30549: uiBaron = pCreature->GetGUID(); return;
|
case 30549: uiBaron = pCreature->GetGUID(); return;
|
||||||
case 16063: uiSir = pCreature->GetGUID(); return;
|
case 16063: uiSir = pCreature->GetGUID(); return;
|
||||||
|
case 15928: uiThaddius = pCreature->GetGUID(); return;
|
||||||
|
case 15930: uiFeugen = pCreature->GetGUID(); return;
|
||||||
|
case 15929: uiStalagg = pCreature->GetGUID(); return;
|
||||||
}
|
}
|
||||||
|
|
||||||
AddMinion(pCreature, add);
|
AddMinion(pCreature, add);
|
||||||
@@ -180,6 +186,12 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData
|
|||||||
return uiBaron;
|
return uiBaron;
|
||||||
if (id == DATA_SIR)
|
if (id == DATA_SIR)
|
||||||
return uiSir;
|
return uiSir;
|
||||||
|
if (id == DATA_THADDIUS)
|
||||||
|
return uiThaddius;
|
||||||
|
if (id == DATA_FEUGEN)
|
||||||
|
return uiFeugen;
|
||||||
|
if (id == DATA_STALAGG)
|
||||||
|
return uiStalagg;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
|
* Copyright (C) 2008 - 2010 Trinity <http://www.trinitycore.org/>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -44,11 +44,18 @@ enum Data
|
|||||||
DATA_HEIGAN_ERUPT,
|
DATA_HEIGAN_ERUPT,
|
||||||
DATA_GOTHIK_GATE,
|
DATA_GOTHIK_GATE,
|
||||||
DATA_SAPPHIRON_BIRTH,
|
DATA_SAPPHIRON_BIRTH,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Data64
|
||||||
|
{
|
||||||
DATA_FAERLINA,
|
DATA_FAERLINA,
|
||||||
DATA_THANE,
|
DATA_THANE,
|
||||||
DATA_LADY,
|
DATA_LADY,
|
||||||
DATA_BARON,
|
DATA_BARON,
|
||||||
DATA_SIR
|
DATA_SIR,
|
||||||
|
DATA_THADDIUS,
|
||||||
|
DATA_FEUGEN,
|
||||||
|
DATA_STALAGG
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GO_BIRTH 181356
|
#define GO_BIRTH 181356
|
||||||
|
|||||||
Reference in New Issue
Block a user