*Update Naxx scripts. Now only Kelthuzad is incompleted

--HG--
branch : trunk
This commit is contained in:
megamage
2009-05-20 11:44:38 -05:00
parent d1d194b4c7
commit 6473e94358
26 changed files with 855 additions and 917 deletions
+2 -26
View File
@@ -134,23 +134,6 @@ void ScriptedAI::DoStopAttack()
}
}
void ScriptedAI::DoCast(Unit* victim, uint32 spellId, bool triggered)
{
if (!victim || m_creature->hasUnitState(UNIT_STAT_CASTING) && !triggered)
return;
//m_creature->StopMoving();
m_creature->CastSpell(victim, spellId, triggered);
}
void ScriptedAI::DoCastAOE(uint32 spellId, bool triggered)
{
if(!triggered && m_creature->hasUnitState(UNIT_STAT_CASTING))
return;
m_creature->CastSpell((Unit*)NULL, spellId, triggered);
}
void ScriptedAI::DoCastSpell(Unit* who,SpellEntry const *spellInfo, bool triggered)
{
if (!who || m_creature->IsNonMeleeSpellCasted(false))
@@ -370,15 +353,6 @@ bool ScriptedAI::CanCast(Unit* Target, SpellEntry const *Spell, bool Triggered)
return true;
}
float GetSpellMaxRangeForHostile(uint32 id)
{
SpellEntry const *spellInfo = GetSpellStore()->LookupEntry(id);
if(!spellInfo) return 0;
SpellRangeEntry const *range = GetSpellRangeStore()->LookupEntry(spellInfo->rangeIndex);
if(!range) return 0;
return range->maxRangeHostile;
}
void FillSpellSummary()
{
SpellSummary = new TSpellSummary[GetSpellStore()->GetNumRows()];
@@ -647,6 +621,7 @@ BossAI::BossAI(Creature *c, uint32 id) : ScriptedAI(c)
void BossAI::_Reset()
{
me->setActive(false);
events.Reset();
summons.DespawnAll();
if(instance)
@@ -663,6 +638,7 @@ void BossAI::_JustDied()
void BossAI::_EnterCombat()
{
me->setActive(true);
DoZoneInCombat();
if(instance)
instance->SetBossState(bossId, IN_PROGRESS);
@@ -29,7 +29,6 @@ class SummonList : private std::list<uint64>
Creature *m_creature;
};
float GetSpellMaxRangeForHostile(uint32 id);
//Get a single creature of given entry
Unit* FindCreature(uint32 entry, float range, Unit* Finder);
@@ -123,10 +122,6 @@ struct TRINITY_DLL_DECL ScriptedAI : public CreatureAI
//Stop attack of current victim
void DoStopAttack();
//Cast spell by Id
void DoCast(Unit* victim, uint32 spellId, bool triggered = false);
void DoCastAOE(uint32 spellId, bool triggered = false);
//Cast spell by spell info
void DoCastSpell(Unit* who,SpellEntry const *spellInfo, bool triggered = false);
@@ -167,7 +167,7 @@ struct TRINITY_DLL_DECL trigger_periodicAI : public NullCreatureAI
trigger_periodicAI(Creature* c) : NullCreatureAI(c)
{
spell = me->m_spells[0] ? GetSpellStore()->LookupEntry(me->m_spells[0]) : NULL;
interval = spell ? GetAISpellInfo(me->m_spells[0])->cooldown : 100000; //me->m_spells[1] ? me->m_spells[1] : 1000;
interval = me->GetAttackTime(BASE_ATTACK);
timer = interval;
}
@@ -197,6 +197,28 @@ struct TRINITY_DLL_DECL trigger_deathAI : public NullCreatureAI
}
};
struct TRINITY_DLL_DECL mob_webwrapAI : public NullCreatureAI
{
mob_webwrapAI(Creature *c) : NullCreatureAI(c), victimGUID(0) {}
uint64 victimGUID;
void SetGUID(const uint64 &guid, const int32 param)
{
victimGUID = guid;
if(me->m_spells[0] && victimGUID)
if(Unit *victim = Unit::GetUnit(*me, victimGUID))
victim->CastSpell(victim, me->m_spells[0], true, NULL, NULL, me->GetGUID());
}
void JustDied(Unit *killer)
{
if(me->m_spells[0] && victimGUID)
if(Unit *victim = Unit::GetUnit(*me, victimGUID))
victim->RemoveAurasDueToSpell(me->m_spells[0], me->GetGUID());
}
};
CreatureAI* GetAI_trigger_periodic(Creature *_Creature)
{
return new trigger_periodicAI (_Creature);
@@ -207,6 +229,11 @@ CreatureAI* GetAI_trigger_death(Creature *_Creature)
return new trigger_deathAI (_Creature);
}
CreatureAI* GetAI_mob_webwrap(Creature* _Creature)
{
return new mob_webwrapAI (_Creature);
}
void AddSC_generic_creature()
{
Script *newscript;
@@ -224,5 +251,10 @@ void AddSC_generic_creature()
newscript->Name="trigger_death";
newscript->GetAI = &GetAI_trigger_death;
newscript->RegisterSelf();*/
newscript = new Script;
newscript->Name="mob_webwrap";
newscript->GetAI = &GetAI_mob_webwrap;
newscript->RegisterSelf();
}
@@ -1,402 +1,167 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
* 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Four_Horsemen
SD%Complete: 75
SDComment: Lady Blaumeux, Thane Korthazz, Sir Zeliek, Baron Rivendare
SDCategory: Naxxramas
EndScriptData */
#include "precompiled.h"
#include "def_naxxramas.h"
#include "precompiled.h"
enum Horsemen
{
HORSEMEN_THANE,
HORSEMEN_LADY,
HORSEMEN_BARON,
HORSEMEN_SIR,
};
//all horsemen
#define SPELL_SHIELDWALL 29061
#define SPELL_BESERK 26662
enum Events
{
EVENT_MARK = 1,
EVENT_CAST,
EVENT_BERSERK,
};
//lady blaumeux
#define SAY_BLAU_AGGRO -1533044
#define SAY_BLAU_TAUNT1 -1533045
#define SAY_BLAU_TAUNT2 -1533046
#define SAY_BLAU_TAUNT3 -1533047
#define SAY_BLAU_SPECIAL -1533048
#define SAY_BLAU_SLAY -1533049
#define SAY_BLAU_DEATH -1533050
const uint32 MOB_HORSEMEN[] = {16064, 16065, 30549, 16063};
const uint32 SPELL_MARK[] = {28832, 28833, 28834, 28835};
#define SPELL_PRIMARY(i) HEROIC(SPELL_PRIMARY_N[i],SPELL_PRIMARY_H[i])
const uint32 SPELL_PRIMARY_N[] = {28884, 28863, 28882, 28883};
const uint32 SPELL_PRIMARY_H[] = {57467, 57463, 57369, 57466};
#define SPELL_SECONDARY(i) HEROIC(SPELL_SECONDARY_N[i],SPELL_SECONDARY_H[i])
const uint32 SPELL_SECONDARY_N[]= {0, 57374, 0, 57376};
const uint32 SPELL_SECONDARY_H[]= {0, 57464, 0, 57465};
const uint32 SPELL_PUNISH[] = {0, 57381, 0, 57377};
#define SPELL_BERSERK 26662
#define SPELL_MARK_OF_BLAUMEUX 28833
#define SPELL_UNYILDING_PAIN 57381
#define SPELL_VOIDZONE 28863
#define H_SPELL_VOIDZONE 57463
#define SPELL_SHADOW_BOLT 57374
#define H_SPELL_SHADOW_BOLT 57464
const int32 SAY_AGGRO[] = {-1533051, -1533044, -1533065, -1533058};
const int32 SAY_TAUNT[3][4] ={ {-1533052, -1533045, -1533071, -1533059},
{-1533053, -1533046, -1533072, -1533060},
{-1533054, -1533047, -1533073, -1533061},};
const int32 SAY_SPECIAL[] = {-1533055, -1533048, -1533070, -1533062};
const int32 SAY_SLAY[] = {-1533056, -1533049, -1533068, -1533063};
const int32 SAY_DEATH[] = {-1533057, -1533050, -1533074, -1533064};
#define C_SPIRIT_OF_BLAUMEUX 16776
#define SAY_BARON_AGGRO RAND(-1533065,-1533066,-1533067)
#define SAY_BARON_SLAY RAND(-1533068,-1533069)
struct TRINITY_DLL_DECL boss_lady_blaumeuxAI : public ScriptedAI
struct TRINITY_DLL_DECL boss_four_horsemenAI : public BossAI
{
boss_four_horsemenAI(Creature *c) : BossAI(c, BOSS_HORSEMEN)
{
boss_lady_blaumeuxAI(Creature *c) : ScriptedAI(c) {}
id = Horsemen(0);
for(uint32 i = 1; i < 4; ++i)
if(me->GetEntry() == MOB_HORSEMEN[i])
id = Horsemen(i);
caster = (id == HORSEMEN_LADY || id == HORSEMEN_SIR);
}
uint32 Mark_Timer;
uint32 VoidZone_Timer;
bool ShieldWall1;
bool ShieldWall2;
Horsemen id;
bool caster;
void Reset()
void MoveInLineOfSight(Unit *who)
{
BossAI::MoveInLineOfSight(who);
if(caster)
SelectNearestTarget(who);
}
void AttackStart(Unit *who)
{
if(caster)
AttackStartCaster(who, 20);
else
BossAI::AttackStart(who);
}
void KilledUnit(Unit* victim)
{
if(!(rand()%5))
{
Mark_Timer = 20000; // First Horsemen Mark is applied at 20 sec.
VoidZone_Timer = 12000; // right
ShieldWall1 = true;
ShieldWall2 = true;
if(id == HORSEMEN_BARON)
DoScriptText(SAY_BARON_SLAY, me);
else
DoScriptText(SAY_SLAY[id], me);
}
}
void EnterCombat(Unit *who)
void JustDied(Unit* killer)
{
_JustDied();
DoScriptText(SAY_DEATH[id], me);
}
void EnterCombat(Unit *who)
{
_EnterCombat();
if(id == HORSEMEN_BARON)
DoScriptText(SAY_BARON_AGGRO, me);
else
DoScriptText(SAY_AGGRO[id], me);
events.ScheduleEvent(EVENT_MARK, 15000);
events.ScheduleEvent(EVENT_CAST, 20000+rand()%5000);
events.ScheduleEvent(EVENT_BERSERK, 15*100*1000);
}
void UpdateAI(const uint32 diff)
{
if(!UpdateVictim() || !CheckInRoom())
return;
events.Update(diff);
if(me->hasUnitState(UNIT_STAT_CASTING))
return;
while(uint32 eventId = events.ExecuteEvent())
{
DoScriptText(SAY_BLAU_AGGRO, m_creature);
}
void KilledUnit(Unit* Victim)
{
DoScriptText(SAY_BLAU_SLAY, m_creature);
}
void JustDied(Unit* Killer)
{
DoScriptText(SAY_BLAU_DEATH, m_creature);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
// Mark of Blaumeux
if (Mark_Timer < diff)
switch(eventId)
{
DoCast(m_creature->getVictim(),SPELL_MARK_OF_BLAUMEUX);
Mark_Timer = 12000;
}else Mark_Timer -= diff;
case EVENT_MARK:
if(!(rand()%5))
DoScriptText(SAY_SPECIAL[id], me);
DoCastAOE(SPELL_MARK[id]);
events.ScheduleEvent(EVENT_MARK, 15000);
return;
case EVENT_CAST:
if(!(rand()%5))
DoScriptText(SAY_TAUNT[rand()%3][id], me);
DoCast(SPELL_PRIMARY(id));
events.ScheduleEvent(EVENT_CAST, 15000);
return;
case EVENT_BERSERK:
DoScriptText(SAY_SPECIAL[id], me);
DoCast(me, EVENT_BERSERK);
return;
}
}
// Shield Wall - All 4 horsemen will shield wall at 50% hp and 20% hp for 20 seconds
if (ShieldWall1 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 50)
{
if(ShieldWall1)
{
DoCast(m_creature,SPELL_SHIELDWALL);
ShieldWall1 = false;
}
}
if (ShieldWall2 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20)
{
if (ShieldWall2)
{
DoCast(m_creature,SPELL_SHIELDWALL);
ShieldWall2 = false;
}
}
if(!caster)
DoMeleeAttackIfReady();
else if(!DoSpellAttackIfReady(SPELL_SECONDARY(id)))
DoCastAOE(SPELL_PUNISH[id]);
}
};
// Void Zone
if (VoidZone_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_VOIDZONE);
VoidZone_Timer = 12000;
}else VoidZone_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_lady_blaumeux(Creature *_Creature)
{
return new boss_lady_blaumeuxAI (_Creature);
}
//baron rivendare
#define SAY_RIVE_AGGRO1 -1533065
#define SAY_RIVE_AGGRO2 -1533066
#define SAY_RIVE_AGGRO3 -1533067
#define SAY_RIVE_SLAY1 -1533068
#define SAY_RIVE_SLAY2 -1533069
#define SAY_RIVE_SPECIAL -1533070
#define SAY_RIVE_TAUNT1 -1533071
#define SAY_RIVE_TAUNT2 -1533072
#define SAY_RIVE_TAUNT3 -1533073
#define SAY_RIVE_DEATH -1533074
#define SPELL_MARK_OF_RIVENDARE 28834
#define SPELL_UNHOLY_SHADOW 28882
#define H_SPELL_UNHOLY_SHADOW 57369
#define C_SPIRIT_OF_RIVENDARE 0 //creature entry not known yet
struct TRINITY_DLL_DECL boss_rivendare_naxxAI : public ScriptedAI
{
boss_rivendare_naxxAI(Creature *c) : ScriptedAI(c) {}
void Reset()
{
}
void EnterCombat(Unit *who)
{
switch(rand()%3)
{
case 0: DoScriptText(SAY_RIVE_AGGRO1, m_creature); break;
case 1: DoScriptText(SAY_RIVE_AGGRO2, m_creature); break;
case 2: DoScriptText(SAY_RIVE_AGGRO3, m_creature); break;
}
}
void KilledUnit(Unit* Victim)
{
switch(rand()%2)
{
case 0: DoScriptText(SAY_RIVE_SLAY1, m_creature); break;
case 1: DoScriptText(SAY_RIVE_SLAY2, m_creature); break;
}
}
void JustDied(Unit* Killer)
{
DoScriptText(SAY_RIVE_DEATH, m_creature);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_rivendare_naxx(Creature *_Creature)
{
return new boss_rivendare_naxxAI (_Creature);
}
//thane korthazz
#define SAY_KORT_AGGRO -1533051
#define SAY_KORT_TAUNT1 -1533052
#define SAY_KORT_TAUNT2 -1533053
#define SAY_KORT_TAUNT3 -1533054
#define SAY_KORT_SPECIAL -1533055
#define SAY_KORT_SLAY -1533056
#define SAY_KORT_DEATH -1533057
#define SPELL_MARK_OF_KORTHAZZ 28832
#define SPELL_METEOR 26558 // m_creature->getVictim() auto-area spell but with a core problem
#define C_SPIRIT_OF_KORTHAZZ 16778
struct TRINITY_DLL_DECL boss_thane_korthazzAI : public ScriptedAI
{
boss_thane_korthazzAI(Creature *c) : ScriptedAI(c) {}
uint32 Mark_Timer;
uint32 Meteor_Timer;
bool ShieldWall1;
bool ShieldWall2;
void Reset()
{
Mark_Timer = 20000; // First Horsemen Mark is applied at 20 sec.
Meteor_Timer = 30000; // wrong
ShieldWall1 = true;
ShieldWall2 = true;
}
void EnterCombat(Unit *who)
{
DoScriptText(SAY_KORT_AGGRO, m_creature);
}
void KilledUnit(Unit* Victim)
{
DoScriptText(SAY_KORT_SLAY, m_creature);
}
void JustDied(Unit* Killer)
{
DoScriptText(SAY_KORT_DEATH, m_creature);
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
// Mark of Korthazz
if (Mark_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_MARK_OF_KORTHAZZ);
Mark_Timer = 12000;
}else Mark_Timer -= diff;
// Shield Wall - All 4 horsemen will shield wall at 50% hp and 20% hp for 20 seconds
if (ShieldWall1 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 50)
{
if (ShieldWall1)
{
DoCast(m_creature,SPELL_SHIELDWALL);
ShieldWall1 = false;
}
}
if (ShieldWall2 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20)
{
if (ShieldWall2)
{
DoCast(m_creature,SPELL_SHIELDWALL);
ShieldWall2 = false;
}
}
// Meteor
if (Meteor_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_METEOR);
Meteor_Timer = 20000; // wrong
}else Meteor_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_thane_korthazz(Creature *_Creature)
{
return new boss_thane_korthazzAI (_Creature);
}
//sir zeliek
#define SAY_ZELI_AGGRO -1533058
#define SAY_ZELI_TAUNT1 -1533059
#define SAY_ZELI_TAUNT2 -1533060
#define SAY_ZELI_TAUNT3 -1533061
#define SAY_ZELI_SPECIAL -1533062
#define SAY_ZELI_SLAY -1533063
#define SAY_ZELI_DEATH -1533064
#define SPELL_MARK_OF_ZELIEK 28835
#define SPELL_HOLY_WRATH 28883
#define H_SPELL_HOLY_WRATH 57466
#define SPELL_HOLY_BOLT 57376
#define H_SPELL_HOLY_BOLT 57465
#define C_SPIRIT_OF_ZELIREK 16777
struct TRINITY_DLL_DECL boss_sir_zeliekAI : public ScriptedAI
{
boss_sir_zeliekAI(Creature *c) : ScriptedAI(c) {}
uint32 Mark_Timer;
uint32 HolyWrath_Timer;
bool ShieldWall1;
bool ShieldWall2;
void Reset()
{
Mark_Timer = 20000; // First Horsemen Mark is applied at 20 sec.
HolyWrath_Timer = 12000; // right
ShieldWall1 = true;
ShieldWall2 = true;
}
void EnterCombat(Unit *who)
{
DoScriptText(SAY_ZELI_AGGRO, m_creature);
}
void KilledUnit(Unit* Victim)
{
DoScriptText(SAY_ZELI_SLAY, m_creature);
}
void JustDied(Unit* Killer)
{
DoScriptText(SAY_ZELI_DEATH, m_creature);
}
void UpdateAI(const uint32 diff)
{
//Return since we have no target
if (!UpdateVictim())
return;
// Mark of Zeliek
if (Mark_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_MARK_OF_ZELIEK);
Mark_Timer = 12000;
}else Mark_Timer -= diff;
// Shield Wall - All 4 horsemen will shield wall at 50% hp and 20% hp for 20 seconds
if (ShieldWall1 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 50)
{
if (ShieldWall1)
{
DoCast(m_creature,SPELL_SHIELDWALL);
ShieldWall1 = false;
}
}
if (ShieldWall2 && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 20)
{
if (ShieldWall2)
{
DoCast(m_creature,SPELL_SHIELDWALL);
ShieldWall2 = false;
}
}
// Holy Wrath
if (HolyWrath_Timer < diff)
{
DoCast(m_creature->getVictim(),SPELL_HOLY_WRATH);
HolyWrath_Timer = 12000;
}else HolyWrath_Timer -= diff;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_boss_sir_zeliek(Creature *_Creature)
{
return new boss_sir_zeliekAI (_Creature);
}
void AddSC_boss_four_horsemen()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_lady_blaumeux";
newscript->GetAI = &GetAI_boss_lady_blaumeux;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_rivendare_naxx";
newscript->GetAI = &GetAI_boss_rivendare_naxx;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_thane_korthazz";
newscript->GetAI = &GetAI_boss_thane_korthazz;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name = "boss_sir_zeliek";
newscript->GetAI = &GetAI_boss_sir_zeliek;
newscript->RegisterSelf();
}
CreatureAI* GetAI_four_horsemen(Creature *_Creature)
{
return new boss_four_horsemenAI (_Creature);
}
void AddSC_boss_four_horsemen()
{
Script *newscript;
newscript = new Script;
newscript->Name = "boss_four_horsemen";
newscript->GetAI = &GetAI_four_horsemen;
newscript->RegisterSelf();
}
@@ -1,4 +1,6 @@
/* Copyright (C) 2006 - 2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
/*
* Copyright (C) 2008 - 2009 Trinity <http://www.trinitycore.org/>
*
* 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
* the Free Software Foundation; either version 2 of the License, or
@@ -14,223 +16,113 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/* ScriptData
SDName: Boss_Maexxna
SD%Complete: 60
SDComment: this needs review, and rewrite of the webwrap ability
SDCategory: Naxxramas
EndScriptData */
#include "precompiled.h"
#include "def_naxxramas.h"
#define SPELL_WEBTRAP 28622 //Spell is normally used by the webtrap on the wall NOT by Maexxna
#define SPELL_WEBSPRAY 29484
#define H_SPELL_WEBSPRAY 54125
#define SPELL_POISONSHOCK 28741
#define H_SPELL_POISONSHOCK 54122
#define SPELL_NECROTICPOISON 28776
#define H_SPELL_NECROTICPOISON 54121
#define SPELL_FRENZY 54123
#define H_SPELL_FRENZY 54124
#define SPELL_WEB_WRAP 28622
#define SPELL_WEB_SPRAY HEROIC(29484,54125)
#define SPELL_POISON_SHOCK HEROIC(28741,54122)
#define SPELL_NECROTIC_POISON HEROIC(54121,28776)
#define SPELL_FRENZY HEROIC(54123,54124)
#define SPELL_SUMMON_SPIDERLING 29434
#define MOB_WEB_WRAP 16486
#define MOB_SPIDERLING 17055
#define LOC_X1 3546.796
#define LOC_Y1 -3869.082
#define LOC_Z1 296.450
#define LOC_X2 3531.271
#define LOC_Y2 -3847.424
#define LOC_Z2 299.450
#define LOC_X3 3497.067
#define LOC_Y3 -3843.384
#define LOC_Z3 302.384
struct TRINITY_DLL_DECL mob_webwrapAI : public ScriptedAI
#define MAX_POS_WRAP 3
const float PosWrap[MAX_POS_WRAP][3] =
{
mob_webwrapAI(Creature *c) : ScriptedAI(c) {}
{3546.796, -3869.082, 296.450+20},
{3531.271, -3847.424, 299.450+20},
{3497.067, -3843.384, 302.384+20},
};
uint64 victimGUID;
enum Events
{
EVENT_SPRAY = 1,
EVENT_SHOCK,
EVENT_POISON,
EVENT_WRAP,
EVENT_SUMMON,
};
void Reset()
{
victimGUID = 0;
}
struct TRINITY_DLL_DECL boss_maexxnaAI : public BossAI
{
boss_maexxnaAI(Creature *c) : BossAI(c, BOSS_MAEXXNA) {}
void SetVictim(Unit* victim)
{
if(victim)
{
victimGUID = victim->GetGUID();
victim->CastSpell(victim, SPELL_WEBTRAP, true);
}
}
void DamageTaken(Unit *done_by, uint32 &damage)
{
if(damage > m_creature->GetHealth())
{
if(victimGUID)
{
Unit* victim = NULL;
victim = Unit::GetUnit((*m_creature), victimGUID);
if(victim)
victim->RemoveAurasDueToSpell(SPELL_WEBTRAP);
}
}
}
bool enraged;
void EnterCombat(Unit *who)
{
}
void MoveInLineOfSight(Unit *who)
{
_EnterCombat();
enraged = false;
events.ScheduleEvent(EVENT_WRAP, 20000);
events.ScheduleEvent(EVENT_SPRAY, 40000);
events.ScheduleEvent(EVENT_SHOCK, 10000);
events.ScheduleEvent(EVENT_POISON, 5000);
events.ScheduleEvent(EVENT_SUMMON, 40000);
}
void UpdateAI(const uint32 diff)
{
}
};
struct TRINITY_DLL_DECL boss_maexxnaAI : public ScriptedAI
{
boss_maexxnaAI(Creature *c) : ScriptedAI(c) {}
uint32 WebTrap_Timer;
uint32 WebSpray_Timer;
uint32 PoisonShock_Timer;
uint32 NecroticPoison_Timer;
uint32 SummonSpiderling_Timer;
bool Enraged;
void Reset()
{
WebTrap_Timer = 20000; //20 sec init, 40 sec normal
WebSpray_Timer = 40000; //40 seconds
PoisonShock_Timer = 20000; //20 seconds
NecroticPoison_Timer = 30000; //30 seconds
SummonSpiderling_Timer = 30000; //30 sec init, 40 sec normal
Enraged = false;
}
void EnterCombat(Unit *who)
{
}
void DoCastWebWrap()
{
std::list<HostilReference *> t_list = m_creature->getThreatManager().getThreatList();
std::vector<Unit *> targets;
//This spell doesn't work if we only have 1 player on threat list
if(t_list.size() < 2)
if(!UpdateVictim() || !CheckInRoom())
return;
//begin + 1 , so we don't target the one with the highest threat
std::list<HostilReference *>::iterator itr = t_list.begin();
std::advance(itr, 1);
for( ; itr!= t_list.end(); ++itr) //store the threat list in a different container
{
Unit *target = Unit::GetUnit(*m_creature, (*itr)->getUnitGuid());
//only on alive players
if(target && target->isAlive() && target->GetTypeId() == TYPEID_PLAYER )
targets.push_back( target);
}
events.Update(diff);
while(targets.size() > 3)
//cut down to size if we have more than 3 targets
targets.erase(targets.begin()+rand()%targets.size());
int i = 0;
for(std::vector<Unit *>::iterator itr = targets.begin(); itr!= targets.end(); ++itr, ++i)
while(uint32 eventId = events.ExecuteEvent())
{
// Teleport the 3 targets to a location on the wall and summon a Web Wrap on them
Unit *target = *itr;
Creature* Wrap = NULL;
if(target)
switch(eventId)
{
switch(i)
case EVENT_WRAP:
for(uint32 i = 0; i < HEROIC(1,2); ++i)
{
if(Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 1, 0, true, -SPELL_WEB_WRAP))
{
target->RemoveAura(SPELL_WEB_SPRAY);
uint32 pos = rand()%MAX_POS_WRAP;
target->GetMotionMaster()->MoveJump(PosWrap[pos][0], PosWrap[pos][1], PosWrap[pos][2], 20, 20);
if(Creature *wrap = DoSummon(MOB_WEB_WRAP, target, 0, 60000))
{
wrap->AI()->SetGUID(target->GetGUID());
wrap->GetMotionMaster()->MoveJump(PosWrap[pos][0], PosWrap[pos][1], PosWrap[pos][2], 20, 20);
}
}
}
events.ScheduleEvent(EVENT_WRAP, 40000);
return;
case EVENT_SPRAY:
DoCastAOE(SPELL_WEB_SPRAY);
events.ScheduleEvent(EVENT_SPRAY, 40000);
return;
case EVENT_SHOCK:
DoCastAOE(SPELL_POISON_SHOCK);
events.ScheduleEvent(EVENT_SHOCK, 10000);
return;
case EVENT_POISON:
DoCast(me->getVictim(), SPELL_NECROTIC_POISON);
events.ScheduleEvent(EVENT_POISON, 30000);
return;
case EVENT_SUMMON:
{
case 0:
DoTeleportPlayer(target, LOC_X1, LOC_Y1, LOC_Z1, target->GetOrientation());
Wrap = m_creature->SummonCreature(16486, LOC_X1, LOC_Y1, LOC_Z1, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
break;
case 1:
DoTeleportPlayer(target, LOC_X2, LOC_Y2, LOC_Z2, target->GetOrientation());
Wrap = m_creature->SummonCreature(16486, LOC_X2, LOC_Y2, LOC_Z2, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
break;
case 2:
DoTeleportPlayer(target, LOC_X3, LOC_Y3, LOC_Z3, target->GetOrientation());
Wrap = m_creature->SummonCreature(16486, LOC_X3, LOC_Y3, LOC_Z3, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120000);
break;
}
if(Wrap)
{
Wrap->setFaction(m_creature->getFaction());
((mob_webwrapAI*)Wrap->AI())->SetVictim(target);
uint32 amount = 8+rand()%2;
for(uint32 i = 0; i < amount; ++i)
DoSummon(MOB_SPIDERLING, me);
events.ScheduleEvent(EVENT_SUMMON, 40000);
break;
}
}
}
if(!enraged && HealthBelowPct(30))
{
DoCast(me, SPELL_FRENZY);
enraged = true;
}
}
void UpdateAI(const uint32 diff)
{
if (!UpdateVictim())
return;
//WebTrap_Timer
if (WebTrap_Timer < diff)
{
DoCastWebWrap();
WebTrap_Timer = 40000;
}else WebTrap_Timer -= diff;
//WebSpray_Timer
if (WebSpray_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_WEBSPRAY);
WebSpray_Timer = 40000;
}else WebSpray_Timer -= diff;
//PoisonShock_Timer
if (PoisonShock_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_POISONSHOCK);
PoisonShock_Timer = 20000;
}else PoisonShock_Timer -= diff;
//NecroticPoison_Timer
if (NecroticPoison_Timer < diff)
{
DoCast(m_creature->getVictim(), SPELL_NECROTICPOISON);
NecroticPoison_Timer = 30000;
}else NecroticPoison_Timer -= diff;
//SummonSpiderling_Timer
if (SummonSpiderling_Timer < diff)
{
DoCast(m_creature, SPELL_SUMMON_SPIDERLING);
SummonSpiderling_Timer = 40000;
}else SummonSpiderling_Timer -= diff;
//Enrage if not already enraged and below 30%
if (!Enraged && (m_creature->GetHealth()*100 / m_creature->GetMaxHealth()) < 30)
{
DoCast(m_creature,SPELL_FRENZY);
Enraged = true;
}
DoMeleeAttackIfReady();
else
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI_mob_webwrap(Creature* _Creature)
{
return new mob_webwrapAI (_Creature);
}
CreatureAI* GetAI_boss_maexxna(Creature *_Creature)
{
return new boss_maexxnaAI (_Creature);
@@ -244,10 +136,5 @@ void AddSC_boss_maexxna()
newscript->Name="boss_maexxna";
newscript->GetAI = &GetAI_boss_maexxna;
newscript->RegisterSelf();
newscript = new Script;
newscript->Name="mob_webwrap";
newscript->GetAI = &GetAI_mob_webwrap;
newscript->RegisterSelf();
}
@@ -52,14 +52,14 @@
#define SAY_SCREAM3 -1533038
#define SAY_SCREAM4 -1533039
#define SPELL_POLARITY_SHIFT HEROIC(39096,28089)
#define SPELL_POLARITY_SHIFT 28089
#define SPELL_BALL_LIGHTNING 28299
#define SPELL_CHAIN_LIGHTNING HEROIC(28167,54531)
#define SPELL_BERSERK 27680
enum Events
{
EVENT_SHIFT,
EVENT_SHIFT = 1,
EVENT_CHAIN,
EVENT_BERSERK,
};
@@ -69,7 +69,7 @@ struct TRINITY_DLL_DECL boss_thaddiusAI : public BossAI
boss_thaddiusAI(Creature *c) : BossAI(c, BOSS_THADDIUS)
{
// temp
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE);
me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_ATTACKABLE_2 | UNIT_FLAG_NOT_SELECTABLE | UNIT_FLAG_STUNNED);
}
void KilledUnit(Unit* victim)
@@ -57,6 +57,7 @@ const MinionData minionData[] =
};
#define GO_GOTHIK_GATE 181170
#define GO_HORSEMEN_CHEST 181366
#define SPELL_ERUPTION 29371
@@ -92,7 +93,7 @@ inline uint32 GetEruptionSection(float x, float y)
struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData
{
instance_naxxramas(Map *map) : InstanceData(map)
, Sapphiron(NULL)
, Sapphiron(NULL), GothikGate(NULL), HorsemenChest(NULL), HorsemenNum(0)
{
SetBossNumber(MAX_BOSS_NUMBER);
LoadDoorData(doorData);
@@ -100,8 +101,9 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData
}
std::set<GameObject*> HeiganEruption[4];
GameObject *GothikGate;
GameObject *GothikGate, *HorsemenChest;
Creature *Sapphiron;
uint32 HorsemenNum;
void OnCreatureCreate(Creature *creature, bool add)
{
@@ -129,6 +131,7 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData
{
case GO_BIRTH: if(!add && Sapphiron) Sapphiron->AI()->DoAction(DATA_SAPPHIRON_BIRTH); return;
case GO_GOTHIK_GATE: GothikGate = add ? go : NULL; break;
case GO_HORSEMEN_CHEST: HorsemenChest = add ? go : NULL; break;
}
AddDoor(go, add);
@@ -148,6 +151,17 @@ struct TRINITY_DLL_DECL instance_naxxramas : public InstanceData
}
}
bool SetBossState(uint32 id, EncounterState state)
{
if(!InstanceData::SetBossState(id, state))
return false;
if(id == BOSS_HORSEMEN && state == DONE && HorsemenChest)
HorsemenChest->SetRespawnTime(HorsemenChest->GetRespawnDelay());
return true;
}
void HeiganErupt(uint32 section)
{
for(uint32 i = 0; i < 4; ++i)
@@ -352,7 +352,7 @@ struct TRINITY_DLL_DECL boss_alarAI : public ScriptedAI
if(Charge_Timer < diff)
{
Unit *target= SelectTarget(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_CHARGE), true);
Unit *target= SelectTarget(SELECT_TARGET_RANDOM, 1, 100, true);
if(target)
DoCast(target, SPELL_CHARGE);
Charge_Timer = 30000;
@@ -406,7 +406,7 @@ struct TRINITY_DLL_DECL boss_nalorakkAI : public ScriptedAI
{
DoYell(YELL_SURGE, LANG_UNIVERSAL, NULL);
DoPlaySoundToSet(m_creature, SOUND_YELL_SURGE);
Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 1, GetSpellMaxRangeForHostile(SPELL_SURGE), true);
Unit *target = SelectTarget(SELECT_TARGET_RANDOM, 1, 45, true);
if(target)
DoCast(target, SPELL_SURGE);
Surge_Timer = 15000 + rand()%5000;