diff options
Diffstat (limited to 'src/bindings/scripts')
9 files changed, 289 insertions, 620 deletions
diff --git a/src/bindings/scripts/include/sc_creature.cpp b/src/bindings/scripts/include/sc_creature.cpp index e22157cd28c..3e7a1a39878 100644 --- a/src/bindings/scripts/include/sc_creature.cpp +++ b/src/bindings/scripts/include/sc_creature.cpp @@ -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); diff --git a/src/bindings/scripts/include/sc_creature.h b/src/bindings/scripts/include/sc_creature.h index 7ce9e7e18ff..95bcadaceeb 100644 --- a/src/bindings/scripts/include/sc_creature.h +++ b/src/bindings/scripts/include/sc_creature.h @@ -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); diff --git a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp index d26b724cdbf..2189cf60c6f 100644 --- a/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp +++ b/src/bindings/scripts/scripts/creature/mob_generic_creature.cpp @@ -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(); } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_four_horsemen.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_four_horsemen.cpp index 7e77afa7167..d7969431511 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_four_horsemen.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_four_horsemen.cpp @@ -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 - */ - - /* ScriptData - SDName: Boss_Four_Horsemen - SD%Complete: 75 - SDComment: Lady Blaumeux, Thane Korthazz, Sir Zeliek, Baron Rivendare - SDCategory: Naxxramas - EndScriptData */ - - #include "precompiled.h" - - //all horsemen - #define SPELL_SHIELDWALL 29061 - #define SPELL_BESERK 26662 - - //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 - - #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 +/* 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 + */ + +#include "precompiled.h" +#include "def_naxxramas.h" + +enum Horsemen +{ + HORSEMEN_THANE, + HORSEMEN_LADY, + HORSEMEN_BARON, + HORSEMEN_SIR, +}; + +enum Events +{ + EVENT_MARK = 1, + EVENT_CAST, + EVENT_BERSERK, +}; + +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 + +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 SAY_BARON_AGGRO RAND(-1533065,-1533066,-1533067) +#define SAY_BARON_SLAY RAND(-1533068,-1533069) + +struct TRINITY_DLL_DECL boss_four_horsemenAI : public BossAI +{ + boss_four_horsemenAI(Creature *c) : BossAI(c, BOSS_HORSEMEN) + { + 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); + } - #define C_SPIRIT_OF_BLAUMEUX 16776 + Horsemen id; + bool caster; - struct TRINITY_DLL_DECL boss_lady_blaumeuxAI : public ScriptedAI + void MoveInLineOfSight(Unit *who) { - boss_lady_blaumeuxAI(Creature *c) : ScriptedAI(c) {} - - uint32 Mark_Timer; - uint32 VoidZone_Timer; - bool ShieldWall1; - bool ShieldWall2; + BossAI::MoveInLineOfSight(who); + if(caster) + SelectNearestTarget(who); + } - void Reset() - { - Mark_Timer = 20000; // First Horsemen Mark is applied at 20 sec. - VoidZone_Timer = 12000; // right - ShieldWall1 = true; - ShieldWall2 = true; - } + void AttackStart(Unit *who) + { + if(caster) + AttackStartCaster(who, 20); + else + BossAI::AttackStart(who); + } - void EnterCombat(Unit *who) + void KilledUnit(Unit* victim) + { + if(!(rand()%5)) { - DoScriptText(SAY_BLAU_AGGRO, m_creature); + if(id == HORSEMEN_BARON) + DoScriptText(SAY_BARON_SLAY, me); + else + DoScriptText(SAY_SLAY[id], me); } + } - void KilledUnit(Unit* Victim) - { - DoScriptText(SAY_BLAU_SLAY, m_creature); - } + void JustDied(Unit* killer) + { + _JustDied(); + DoScriptText(SAY_DEATH[id], me); + } - void JustDied(Unit* Killer) - { - DoScriptText(SAY_BLAU_DEATH, m_creature); - } + 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; - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + events.Update(diff); - // Mark of Blaumeux - if (Mark_Timer < diff) - { - DoCast(m_creature->getVictim(),SPELL_MARK_OF_BLAUMEUX); - Mark_Timer = 12000; - }else Mark_Timer -= diff; + if(me->hasUnitState(UNIT_STAT_CASTING)) + 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) + while(uint32 eventId = events.ExecuteEvent()) + { + switch(eventId) { - 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; - } - } - - // 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(); - } + 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; + } + } + if(!caster) + DoMeleeAttackIfReady(); + else if(!DoSpellAttackIfReady(SPELL_SECONDARY(id))) + DoCastAOE(SPELL_PUNISH[id]); + } +}; + +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(); +} diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp index e84374432ca..ff23e77a673 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_maexxna.cpp @@ -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_SUMMON_SPIDERLING 29434 - -#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 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 LOC_X3 3497.067 -#define LOC_Y3 -3843.384 -#define LOC_Z3 302.384 +#define MOB_WEB_WRAP 16486 +#define MOB_SPIDERLING 17055 -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) {} - - uint64 victimGUID; - - void Reset() - { - victimGUID = 0; - } - - 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); - } - } - } - - void EnterCombat(Unit *who) - { - } - - void MoveInLineOfSight(Unit *who) - { - } - - void UpdateAI(const uint32 diff) - { - } + {3546.796, -3869.082, 296.450+20}, + {3531.271, -3847.424, 299.450+20}, + {3497.067, -3843.384, 302.384+20}, }; -struct TRINITY_DLL_DECL boss_maexxnaAI : public ScriptedAI +enum Events { - boss_maexxnaAI(Creature *c) : ScriptedAI(c) {} + EVENT_SPRAY = 1, + EVENT_SHOCK, + EVENT_POISON, + EVENT_WRAP, + EVENT_SUMMON, +}; - uint32 WebTrap_Timer; - uint32 WebSpray_Timer; - uint32 PoisonShock_Timer; - uint32 NecroticPoison_Timer; - uint32 SummonSpiderling_Timer; - bool Enraged; +struct TRINITY_DLL_DECL boss_maexxnaAI : public BossAI +{ + boss_maexxnaAI(Creature *c) : BossAI(c, BOSS_MAEXXNA) {} - 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; - } + bool enraged; void EnterCombat(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 DoCastWebWrap() + void UpdateAI(const uint32 diff) { - 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; } } - } - } - - void UpdateAI(const uint32 diff) - { - if (!UpdateVictim()) - return; + } - //WebTrap_Timer - if (WebTrap_Timer < diff) + if(!enraged && HealthBelowPct(30)) { - 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; + DoCast(me, 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(); } diff --git a/src/bindings/scripts/scripts/zone/naxxramas/boss_thaddius.cpp b/src/bindings/scripts/scripts/zone/naxxramas/boss_thaddius.cpp index 40404b8adc3..f9f4d7edacc 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/boss_thaddius.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/boss_thaddius.cpp @@ -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) diff --git a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp index d9a2c80064d..f2ba97d2858 100644 --- a/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp +++ b/src/bindings/scripts/scripts/zone/naxxramas/instance_naxxramas.cpp @@ -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) diff --git a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp index 5f1d92beaf1..132747a31bd 100644 --- a/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp +++ b/src/bindings/scripts/scripts/zone/tempest_keep/the_eye/boss_alar.cpp @@ -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; diff --git a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp index 68b92590025..1f810059997 100644 --- a/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp +++ b/src/bindings/scripts/scripts/zone/zulaman/boss_nalorakk.cpp @@ -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; |
