diff options
author | Vincent-Michael <Vincent_Michael@gmx.de> | 2013-06-14 23:38:15 +0200 |
---|---|---|
committer | Vincent-Michael <Vincent_Michael@gmx.de> | 2013-06-14 23:39:02 +0200 |
commit | 9aea25f06c4816117b586df6b447e406e9fd2e77 (patch) | |
tree | f9620f6cd7dce486e8d9847f1b9605ebe1a18a3f /src | |
parent | 87d9d1d7055fdda84d8f116041224ce0fb289b02 (diff) |
Scripts/ZulAman:
- Hard reset for old scripts
- Add pre Event (is not complete)
- Some cleanup
Diffstat (limited to 'src')
13 files changed, 586 insertions, 3930 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e8faa8e579a..b8bc07be33f 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -9849,6 +9849,16 @@ void Player::SendInitWorldStates(uint32 zoneid, uint32 areaid) data << uint32(4131) << uint32(0); // 10 WORLDSTATE_ALGALON_DESPAWN_TIMER } break; + // Zul Aman + case 3805: + if (instance && mapid == 568) + instance->FillInitialWorldStates(data); + else + { + data << uint32(3104) << uint32(0); // 9 WORLD_STATE_ZULAMAN_TIMER_ENABLED + data << uint32(3106) << uint32(0); // 10 WORLD_STATE_ZULAMAN_TIMER + } + break; // Twin Peaks case 5031: if (bg && bg->GetTypeID(true) == BATTLEGROUND_TP) diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index b566f9dabe1..3b3f3e45799 100644 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -234,7 +234,7 @@ void AddSC_boss_halazzi(); void AddSC_boss_hex_lord_malacrass(); void AddSC_boss_janalai(); void AddSC_boss_nalorakk(); -void AddSC_boss_zuljin(); +void AddSC_boss_daakara(); void AddSC_instance_zulaman(); void AddSC_zulaman(); void AddSC_boss_grilek(); // Zul'Gurub @@ -876,7 +876,7 @@ void AddEasternKingdomsScripts() AddSC_boss_hex_lord_malacrass(); AddSC_boss_janalai(); AddSC_boss_nalorakk(); - AddSC_boss_zuljin(); + AddSC_boss_daakara(); AddSC_instance_zulaman(); AddSC_zulaman(); AddSC_boss_grilek(); // Zul'Gurub diff --git a/src/server/scripts/EasternKingdoms/CMakeLists.txt b/src/server/scripts/EasternKingdoms/CMakeLists.txt index e782711bde2..0737972c5b3 100644 --- a/src/server/scripts/EasternKingdoms/CMakeLists.txt +++ b/src/server/scripts/EasternKingdoms/CMakeLists.txt @@ -176,7 +176,7 @@ set(scripts_STAT_SRCS EasternKingdoms/zone_stormwind_city.cpp EasternKingdoms/ZulAman/boss_halazzi.cpp EasternKingdoms/ZulAman/boss_hexlord.cpp - EasternKingdoms/ZulAman/boss_zuljin.cpp + EasternKingdoms/ZulAman/boss_daakara.cpp EasternKingdoms/ZulAman/boss_akilzon.cpp EasternKingdoms/ZulAman/instance_zulaman.cpp EasternKingdoms/ZulAman/boss_janalai.cpp diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp index 20d3df4b17f..564b2e5cfe2 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp @@ -27,217 +27,50 @@ EndScriptData */ #include "ScriptMgr.h" #include "ScriptedCreature.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "Cell.h" -#include "CellImpl.h" #include "zulaman.h" -#include "Weather.h" enum Spells { - SPELL_STATIC_DISRUPTION = 43622, - SPELL_STATIC_VISUAL = 45265, - SPELL_CALL_LIGHTNING = 43661, // Missing timer - SPELL_GUST_OF_WIND = 43621, - SPELL_ELECTRICAL_STORM = 43648, - SPELL_BERSERK = 45078, - SPELL_ELECTRICAL_OVERLOAD = 43658, - SPELL_EAGLE_SWOOP = 44732 }; enum Says { - SAY_AGGRO = 0, - SAY_SUMMON = 1, - SAY_INTRO = 2, // Not used in script - SAY_ENRAGE = 3, - SAY_KILL = 4, - SAY_DEATH = 5 }; -enum Misc +enum Events { - MOB_SOARING_EAGLE = 24858, - SE_LOC_X_MAX = 400, - SE_LOC_X_MIN = 335, - SE_LOC_Y_MAX = 1435, - SE_LOC_Y_MIN = 1370 }; class boss_akilzon : public CreatureScript { public: - boss_akilzon() - : CreatureScript("boss_akilzon") - { - } + boss_akilzon() : CreatureScript("boss_akilzon") { } - struct boss_akilzonAI : public ScriptedAI + struct boss_akilzonAI : public BossAI { - boss_akilzonAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - memset(BirdGUIDs, 0, sizeof(BirdGUIDs)); - } - - InstanceScript* instance; - - uint64 BirdGUIDs[8]; - uint64 TargetGUID; - uint64 CycloneGUID; - uint64 CloudGUID; - - uint32 StaticDisruption_Timer; - uint32 GustOfWind_Timer; - uint32 CallLighting_Timer; - uint32 ElectricalStorm_Timer; - uint32 SummonEagles_Timer; - uint32 Enrage_Timer; - - uint32 StormCount; - uint32 StormSequenceTimer; - - bool isRaining; + boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZON) { } void Reset() { - if (instance) - instance->SetData(DATA_AKILZONEVENT, NOT_STARTED); - - StaticDisruption_Timer = urand(10000, 20000); //10 to 20 seconds (bosskillers) - GustOfWind_Timer = urand(20000, 30000); //20 to 30 seconds(bosskillers) - CallLighting_Timer = urand(10000, 20000); //totaly random timer. can't find any info on this - ElectricalStorm_Timer = 60000; //60 seconds(bosskillers) - Enrage_Timer = 10*MINUTE*IN_MILLISECONDS; //10 minutes till enrage(bosskillers) - SummonEagles_Timer = 99999; - - TargetGUID = 0; - CloudGUID = 0; - CycloneGUID = 0; - DespawnSummons(); - memset(BirdGUIDs, 0, sizeof(BirdGUIDs)); - - StormCount = 0; - StormSequenceTimer = 0; - - isRaining = false; - - SetWeather(WEATHER_STATE_FINE, 0.0f); + _Reset(); } void EnterCombat(Unit* /*who*/) { - Talk(SAY_AGGRO); - //DoZoneInCombat(); - if (instance) - instance->SetData(DATA_AKILZONEVENT, IN_PROGRESS); + //Talk(SAY_AGGRO); + _EnterCombat(); } void JustDied(Unit* /*killer*/) { - Talk(SAY_DEATH); - if (instance) - instance->SetData(DATA_AKILZONEVENT, DONE); - DespawnSummons(); + //Talk(SAY_DEATH); + _JustDied(); } void KilledUnit(Unit* /*victim*/) { - Talk(SAY_KILL); - } - - void DespawnSummons() - { - for (uint8 i = 0; i < 8; ++i) - { - Unit* bird = Unit::GetUnit(*me, BirdGUIDs[i]); - if (bird && bird->IsAlive()) - { - bird->SetVisible(false); - bird->setDeathState(JUST_DIED); - } - } - } - - void SetWeather(uint32 weather, float grade) - { - Map* map = me->GetMap(); - if (!map->IsDungeon()) - return; - - WorldPacket data(SMSG_WEATHER, (4+4+4)); - data << uint32(weather) << float(grade) << uint8(0); - - map->SendToPlayers(&data); - } - - void HandleStormSequence(Unit* Cloud) // 1: begin, 2-9: tick, 10: end - { - if (StormCount < 10 && StormCount > 1) - { - // deal damage - int32 bp0 = 800; - for (uint8 i = 2; i < StormCount; ++i) - bp0 *= 2; - - CellCoord p(Trinity::ComputeCellCoord(me->GetPositionX(), me->GetPositionY())); - Cell cell(p); - cell.SetNoCreate(); - - std::list<Unit*> tempUnitMap; - - { - Trinity::AnyAoETargetUnitInObjectRangeCheck u_check(me, me, SIZE_OF_GRIDS); - Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck> searcher(me, tempUnitMap, u_check); - - TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher); - TypeContainerVisitor<Trinity::UnitListSearcher<Trinity::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher); - - cell.Visit(p, world_unit_searcher, *me->GetMap(), *me, SIZE_OF_GRIDS); - cell.Visit(p, grid_unit_searcher, *me->GetMap(), *me, SIZE_OF_GRIDS); - } - //dealdamege - for (std::list<Unit*>::const_iterator i = tempUnitMap.begin(); i != tempUnitMap.end(); ++i) - { - if (Unit* target = (*i)) - { - if (!Cloud->IsWithinDist(target, 6, false)) - Cloud->CastCustomSpell(target, 43137, &bp0, NULL, NULL, true, 0, 0, me->GetGUID()); - } - } - // visual - float x, y, z; - z = me->GetPositionZ(); - for (uint8 i = 0; i < 5+rand()%5; ++i) - { - x = 343.0f+rand()%60; - y = 1380.0f+rand()%60; - if (Unit* trigger = me->SummonTrigger(x, y, z, 0, 2000)) - { - trigger->setFaction(35); - trigger->SetMaxHealth(100000); - trigger->SetHealth(100000); - trigger->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - if (Cloud) - Cloud->CastCustomSpell(trigger, /*43661*/43137, &bp0, NULL, NULL, true, 0, 0, Cloud->GetGUID()); - } - } - } - ++StormCount; - if (StormCount > 10) - { - StormCount = 0; // finish - SummonEagles_Timer = 5000; - me->InterruptNonMeleeSpells(false); - CloudGUID = 0; - if (Cloud) - Cloud->DealDamage(Cloud, Cloud->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - SetWeather(WEATHER_STATE_FINE, 0.0f); - isRaining = false; - } - StormSequenceTimer = 1000; + //Talk(SAY_KILL); } void UpdateAI(uint32 diff) @@ -245,225 +78,17 @@ class boss_akilzon : public CreatureScript if (!UpdateVictim()) return; - if (StormCount) - { - Unit* target = Unit::GetUnit(*me, CloudGUID); - if (!target || !target->IsAlive()) - { - EnterEvadeMode(); - return; - } - else if (Unit* Cyclone = Unit::GetUnit(*me, CycloneGUID)) - Cyclone->CastSpell(target, 25160, true); // keep casting or... - - if (StormSequenceTimer <= diff) - HandleStormSequence(target); - else - StormSequenceTimer -= diff; - - return; - } - - if (Enrage_Timer <= diff) - { - Talk(SAY_ENRAGE); - DoCast(me, SPELL_BERSERK, true); - Enrage_Timer = 600000; - } else Enrage_Timer -= diff; - - if (StaticDisruption_Timer <= diff) - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); - if (!target) target = me->GetVictim(); - TargetGUID = target->GetGUID(); - DoCast(target, SPELL_STATIC_DISRUPTION, false); - me->SetInFront(me->GetVictim()); - StaticDisruption_Timer = (10+rand()%8)*1000; // < 20s - - /*if (float dist = me->IsWithinDist3d(target->GetPositionX(), target->GetPositionY(), target->GetPositionZ(), 5.0f) dist = 5.0f; - SDisruptAOEVisual_Timer = 1000 + floor(dist / 30 * 1000.0f);*/ - } else StaticDisruption_Timer -= diff; - - if (GustOfWind_Timer <= diff) - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1); - if (!target) target = me->GetVictim(); - DoCast(target, SPELL_GUST_OF_WIND); - GustOfWind_Timer = urand(20, 30) * 1000; //20 to 30 seconds(bosskillers) - } else GustOfWind_Timer -= diff; - - if (CallLighting_Timer <= diff) - { - DoCast(me->GetVictim(), SPELL_CALL_LIGHTNING); - CallLighting_Timer = urand(12, 17) * 1000; //totaly random timer. can't find any info on this - } else CallLighting_Timer -= diff; - - if (!isRaining && ElectricalStorm_Timer < uint32(8000 + rand() % 5000)) - { - SetWeather(WEATHER_STATE_HEAVY_RAIN, 0.9999f); - isRaining = true; - } - - if (ElectricalStorm_Timer <= diff) - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 50, true); - if (!target) - { - EnterEvadeMode(); - return; - } - target->CastSpell(target, 44007, true);//cloud visual - DoCast(target, SPELL_ELECTRICAL_STORM, false);//storm cyclon + visual - float x, y, z; - target->GetPosition(x, y, z); - if (target) - { - target->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY); - target->MonsterMoveWithSpeed(x, y, me->GetPositionZ()+15, 0); - } - Unit* Cloud = me->SummonTrigger(x, y, me->GetPositionZ()+16, 0, 15000); - if (Cloud) - { - CloudGUID = Cloud->GetGUID(); - Cloud->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY); - Cloud->StopMoving(); - Cloud->SetObjectScale(1.0f); - Cloud->setFaction(35); - Cloud->SetMaxHealth(9999999); - Cloud->SetHealth(9999999); - Cloud->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - ElectricalStorm_Timer = 60000; //60 seconds(bosskillers) - StormCount = 1; - StormSequenceTimer = 0; - } else ElectricalStorm_Timer -= diff; - - if (SummonEagles_Timer <= diff) - { - Talk(SAY_SUMMON); - - float x, y, z; - me->GetPosition(x, y, z); - - for (uint8 i = 0; i < 8; ++i) - { - Unit* bird = Unit::GetUnit(*me, BirdGUIDs[i]); - if (!bird) //they despawned on die - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - x = target->GetPositionX() + irand(-10, 10); - y = target->GetPositionY() + irand(-10, 10); - z = target->GetPositionZ() + urand(16, 20); - if (z > 95) - z = 95.0f - urand(0, 5); - } - Creature* creature = me->SummonCreature(MOB_SOARING_EAGLE, x, y, z, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); - if (creature) - { - creature->AddThreat(me->GetVictim(), 1.0f); - creature->AI()->AttackStart(me->GetVictim()); - BirdGUIDs[i] = creature->GetGUID(); - } - } - } - SummonEagles_Timer = 999999; - } else SummonEagles_Timer -= diff; - DoMeleeAttackIfReady(); } }; CreatureAI* GetAI(Creature* creature) const { - return new boss_akilzonAI(creature); - } -}; - -class mob_akilzon_eagle : public CreatureScript -{ - public: - mob_akilzon_eagle() : CreatureScript("mob_akilzon_eagle") { } - - struct mob_akilzon_eagleAI : public ScriptedAI - { - mob_akilzon_eagleAI(Creature* creature) : ScriptedAI(creature) { } - - uint32 EagleSwoop_Timer; - bool arrived; - uint64 TargetGUID; - - void Reset() - { - EagleSwoop_Timer = urand(5000, 10000); - arrived = true; - TargetGUID = 0; - me->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY); - } - - void EnterCombat(Unit* /*who*/) - { - DoZoneInCombat(); - } - - void MoveInLineOfSight(Unit* /*who*/) {} - - void MovementInform(uint32, uint32) - { - arrived = true; - if (TargetGUID) - { - if (Unit* target = Unit::GetUnit(*me, TargetGUID)) - DoCast(target, SPELL_EAGLE_SWOOP, true); - TargetGUID = 0; - me->SetSpeed(MOVE_RUN, 1.2f); - EagleSwoop_Timer = urand(5000, 10000); - } - } - - void UpdateAI(uint32 diff) - { - if (EagleSwoop_Timer <= diff) - EagleSwoop_Timer = 0; - else - EagleSwoop_Timer -= diff; - - if (arrived) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - float x, y, z; - if (EagleSwoop_Timer) - { - x = target->GetPositionX() + irand(-10, 10); - y = target->GetPositionY() + irand(-10, 10); - z = target->GetPositionZ() + urand(10, 15); - if (z > 95) - z = 95.0f - urand(0, 5); - } - else - { - target->GetContactPoint(me, x, y, z); - z += 2; - me->SetSpeed(MOVE_RUN, 5.0f); - TargetGUID = target->GetGUID(); - } - me->GetMotionMaster()->MovePoint(0, x, y, z); - arrived = false; - } - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_akilzon_eagleAI(creature); + return GetZulAmanAI<boss_akilzonAI>(creature); } }; void AddSC_boss_akilzon() { new boss_akilzon(); - new mob_akilzon_eagle(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_daakara.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_daakara.cpp new file mode 100644 index 00000000000..9ad6ae1cf61 --- /dev/null +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_daakara.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2008-2013 TrinityCore <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, see <http://www.gnu.org/licenses/>. + */ + +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "zulaman.h" + +enum Spells +{ +}; + +enum Says +{ +}; + +enum Events +{ +}; + +class boss_daakara : public CreatureScript +{ + public: + + boss_daakara() : CreatureScript("boss_daakara") { } + + struct boss_daakaraAI : public BossAI + { + boss_daakaraAI(Creature* creature) : BossAI(creature, DATA_DAAKARA) { } + + void Reset() + { + _Reset(); + } + + void EnterCombat(Unit* /*who*/) + { + _EnterCombat(); + } + + void KilledUnit(Unit* /*victim*/) + { + } + + void JustDied(Unit* /*killer*/) + { + _JustDied(); + } + + void UpdateAI(uint32 diff) + { + DoMeleeAttackIfReady(); + } + }; + + CreatureAI* GetAI(Creature* creature) const + { + return GetZulAmanAI<boss_daakaraAI>(creature); + } +}; + +void AddSC_boss_daakara() +{ + new boss_daakara(); +} diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp index 60e25af862b..0f81a3f39bd 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * 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 @@ -16,201 +15,40 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: boss_Halazzi -SD%Complete: 80 -SDComment: -SDCategory: Zul'Aman -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulaman.h" -#include "SpellInfo.h" - -#define YELL_AGGRO "Get on your knees and bow to da fang and claw!" -#define SOUND_AGGRO 12020 -#define YELL_SABER_ONE "You gonna leave in pieces!" -#define YELL_SABER_TWO "Me gonna carve ya now!" -#define YELL_SPLIT "Me gonna carve ya now!" -#define SOUND_SPLIT 12021 -#define YELL_MERGE "Spirit, come back to me!" -#define SOUND_MERGE 12022 -#define YELL_KILL_ONE "You cant fight the power!" -#define SOUND_KILL_ONE 12026 -#define YELL_KILL_TWO "You gonna fail!" -#define SOUND_KILL_TWO 12027 -#define YELL_DEATH "Chaga... choka'jinn." -#define SOUND_DEATH 12028 -#define YELL_BERSERK "Whatch you be doing? Pissin' yourselves..." -#define SOUND_BERSERK 12025 enum Spells { - SPELL_DUAL_WIELD = 29651, - SPELL_SABER_LASH = 43267, - SPELL_FRENZY = 43139, - SPELL_FLAMESHOCK = 43303, - SPELL_EARTHSHOCK = 43305, - SPELL_TRANSFORM_SPLIT = 43142, - SPELL_TRANSFORM_SPLIT2 = 43573, - SPELL_TRANSFORM_MERGE = 43271, - SPELL_SUMMON_LYNX = 43143, - SPELL_SUMMON_TOTEM = 43302, - SPELL_BERSERK = 45078, - SPELL_LYNX_FRENZY = 43290, // Used by Spirit Lynx - SPELL_SHRED_ARMOR = 43243 // Used by Spirit Lynx }; -enum Hal_CreatureIds +enum Says { - NPC_SPIRIT_LYNX = 24143, - NPC_TOTEM = 24224 }; -enum PhaseHalazzi +enum Events { - PHASE_NONE = 0, - PHASE_LYNX = 1, - PHASE_SPLIT = 2, - PHASE_HUMAN = 3, - PHASE_MERGE = 4, - PHASE_ENRAGE = 5 }; class boss_halazzi : public CreatureScript { public: - boss_halazzi() - : CreatureScript("boss_halazzi") - { - } + boss_halazzi() : CreatureScript("boss_halazzi") { } - struct boss_halazziAI : public ScriptedAI + struct boss_halazziAI : public BossAI { - boss_halazziAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 FrenzyTimer; - uint32 SaberlashTimer; - uint32 ShockTimer; - uint32 TotemTimer; - uint32 CheckTimer; - uint32 BerserkTimer; - - uint32 TransformCount; - - PhaseHalazzi Phase; - - uint64 LynxGUID; + boss_halazziAI(Creature* creature) : BossAI(creature, DATA_HALAZZI) { } void Reset() { - if (instance) - instance->SetData(DATA_HALAZZIEVENT, NOT_STARTED); - - LynxGUID = 0; - TransformCount = 0; - BerserkTimer = 600000; - CheckTimer = 1000; - - DoCast(me, SPELL_DUAL_WIELD, true); - - Phase = PHASE_NONE; - EnterPhase(PHASE_LYNX); + _Reset(); } void EnterCombat(Unit* /*who*/) { - if (instance) - instance->SetData(DATA_HALAZZIEVENT, IN_PROGRESS); - - me->MonsterYell(YELL_AGGRO, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_AGGRO); - - EnterPhase(PHASE_LYNX); - } - - void JustSummoned(Creature* summon) - { - summon->AI()->AttackStart(me->GetVictim()); - if (summon->GetEntry() == NPC_SPIRIT_LYNX) - LynxGUID = summon->GetGUID(); - } - - void DamageTaken(Unit* /*done_by*/, uint32 &damage) - { - if (damage >= me->GetHealth() && Phase != PHASE_ENRAGE) - damage = 0; - } - - void SpellHit(Unit*, const SpellInfo* spell) - { - if (spell->Id == SPELL_TRANSFORM_SPLIT2) - EnterPhase(PHASE_HUMAN); - } - - void AttackStart(Unit* who) - { - if (Phase != PHASE_MERGE) ScriptedAI::AttackStart(who); - } - - void EnterPhase(PhaseHalazzi NextPhase) - { - switch (NextPhase) - { - case PHASE_LYNX: - case PHASE_ENRAGE: - if (Phase == PHASE_MERGE) - { - DoCast(me, SPELL_TRANSFORM_MERGE, true); - me->Attack(me->GetVictim(), true); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - } - if (Creature* Lynx = Unit::GetCreature(*me, LynxGUID)) - Lynx->DisappearAndDie(); - me->SetMaxHealth(600000); - me->SetHealth(600000 - 150000 * TransformCount); - FrenzyTimer = 16000; - SaberlashTimer = 20000; - ShockTimer = 10000; - TotemTimer = 12000; - break; - case PHASE_SPLIT: - me->MonsterYell(YELL_SPLIT, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_SPLIT); - DoCast(me, SPELL_TRANSFORM_SPLIT, true); - break; - case PHASE_HUMAN: - //DoCast(me, SPELL_SUMMON_LYNX, true); - DoSpawnCreature(NPC_SPIRIT_LYNX, 5, 5, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); - me->SetMaxHealth(400000); - me->SetHealth(400000); - ShockTimer = 10000; - TotemTimer = 12000; - break; - case PHASE_MERGE: - if (Unit* pLynx = Unit::GetUnit(*me, LynxGUID)) - { - me->MonsterYell(YELL_MERGE, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_MERGE); - pLynx->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - pLynx->GetMotionMaster()->Clear(); - pLynx->GetMotionMaster()->MoveFollow(me, 0, 0); - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MoveFollow(pLynx, 0, 0); - ++TransformCount; - } - break; - default: - break; - } - Phase = NextPhase; + _EnterCombat(); } void UpdateAI(uint32 diff) @@ -218,204 +56,26 @@ class boss_halazzi : public CreatureScript if (!UpdateVictim()) return; - if (BerserkTimer <= diff) - { - me->MonsterYell(YELL_BERSERK, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_BERSERK); - DoCast(me, SPELL_BERSERK, true); - BerserkTimer = 60000; - } else BerserkTimer -= diff; - - if (Phase == PHASE_LYNX || Phase == PHASE_ENRAGE) - { - if (SaberlashTimer <= diff) - { - // A tank with more than 490 defense skills should receive no critical hit - //DoCast(me, 41296, true); - DoCast(me->GetVictim(), SPELL_SABER_LASH, true); - //me->RemoveAurasDueToSpell(41296); - SaberlashTimer = 30000; - } else SaberlashTimer -= diff; - - if (FrenzyTimer <= diff) - { - DoCast(me, SPELL_FRENZY); - FrenzyTimer = urand(10000, 15000); - } else FrenzyTimer -= diff; - - if (Phase == PHASE_LYNX) - { - if (CheckTimer <= diff) - { - if (HealthBelowPct(25 * (3 - TransformCount))) - EnterPhase(PHASE_SPLIT); - CheckTimer = 1000; - } else CheckTimer -= diff; - } - } - - if (Phase == PHASE_HUMAN || Phase == PHASE_ENRAGE) - { - if (TotemTimer <= diff) - { - DoCast(me, SPELL_SUMMON_TOTEM); - TotemTimer = 20000; - } else TotemTimer -= diff; - - if (ShockTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - if (target->IsNonMeleeSpellCasted(false)) - DoCast(target, SPELL_EARTHSHOCK); - else - DoCast(target, SPELL_FLAMESHOCK); - ShockTimer = urand(10000, 15000); - } - } else ShockTimer -= diff; - - if (Phase == PHASE_HUMAN) - { - if (CheckTimer <= diff) - { - if (!HealthAbovePct(20) /*HealthBelowPct(10)*/) - EnterPhase(PHASE_MERGE); - else - { - Unit* Lynx = Unit::GetUnit(*me, LynxGUID); - if (Lynx && !Lynx->HealthAbovePct(20) /*Lynx->HealthBelowPct(10)*/) - EnterPhase(PHASE_MERGE); - } - CheckTimer = 1000; - } else CheckTimer -= diff; - } - } - - if (Phase == PHASE_MERGE) - { - if (CheckTimer <= diff) - { - Unit* Lynx = Unit::GetUnit(*me, LynxGUID); - if (Lynx) - { - Lynx->GetMotionMaster()->MoveFollow(me, 0, 0); - me->GetMotionMaster()->MoveFollow(Lynx, 0, 0); - if (me->IsWithinDistInMap(Lynx, 6.0f)) - { - if (TransformCount < 3) - EnterPhase(PHASE_LYNX); - else - EnterPhase(PHASE_ENRAGE); - } - } - CheckTimer = 1000; - } else CheckTimer -= diff; - } - DoMeleeAttackIfReady(); } void KilledUnit(Unit* /*victim*/) { - switch (urand(0, 1)) - { - case 0: - me->MonsterYell(YELL_KILL_ONE, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_KILL_ONE); - break; - - case 1: - me->MonsterYell(YELL_KILL_TWO, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_KILL_TWO); - break; - } } void JustDied(Unit* /*killer*/) { - if (instance) - instance->SetData(DATA_HALAZZIEVENT, DONE); - - me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_DEATH); + _JustDied(); } }; CreatureAI* GetAI(Creature* creature) const { - return new boss_halazziAI(creature); - } -}; - -// Spirits Lynx AI -class mob_halazzi_lynx : public CreatureScript -{ - public: - - mob_halazzi_lynx() - : CreatureScript("mob_halazzi_lynx") - { - } - - struct mob_halazzi_lynxAI : public ScriptedAI - { - mob_halazzi_lynxAI(Creature* creature) : ScriptedAI(creature) {} - - uint32 FrenzyTimer; - uint32 shredder_timer; - - void Reset() - { - FrenzyTimer = urand(30000, 50000); //frenzy every 30-50 seconds - shredder_timer = 4000; - } - - void DamageTaken(Unit* /*done_by*/, uint32 &damage) - { - if (damage >= me->GetHealth()) - damage = 0; - } - - void AttackStart(Unit* who) - { - if (!me->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE)) - ScriptedAI::AttackStart(who); - } - - void EnterCombat(Unit* /*who*/) {/*DoZoneInCombat();*/} - - void UpdateAI(uint32 diff) - { - if (!UpdateVictim()) - return; - - if (FrenzyTimer <= diff) - { - DoCast(me, SPELL_LYNX_FRENZY); - FrenzyTimer = urand(30000, 50000); //frenzy every 30-50 seconds - } else FrenzyTimer -= diff; - - if (shredder_timer <= diff) - { - DoCast(me->GetVictim(), SPELL_SHRED_ARMOR); - shredder_timer = 4000; - } else shredder_timer -= diff; - - DoMeleeAttackIfReady(); - } - - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_halazzi_lynxAI(creature); + return GetZulAmanAI<boss_halazziAI>(creature); } }; void AddSC_boss_halazzi() { new boss_halazzi(); - new mob_halazzi_lynx(); } - - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp index 195e21ca102..5b13f4bdd45 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * Copyright (C) 2006-2007 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 @@ -16,339 +15,53 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Hex_Lord_Malacrass -SD%Complete: -SDComment: -SDCategory: Zul'Aman -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "SpellScript.h" #include "SpellAuraEffects.h" #include "zulaman.h" -#define YELL_AGGRO "Da shadow gonna fall on you... " -#define SOUND_YELL_AGGRO 12041 -#define YELL_SPIRIT_BOLTS "Your soul gonna bleed!" -#define SOUND_YELL_SPIRIT_BOLTS 12047 -#define YELL_DRAIN_POWER "Darkness comin\' for you" -#define SOUND_YELL_DRAIN_POWER 12046 -#define YELL_KILL_ONE "Dis a nightmare ya don\' wake up from!" -#define SOUND_YELL_KILL_ONE 12043 -#define YELL_KILL_TWO "Azzaga choogo zinn!" -#define SOUND_YELL_KILL_TWO 12044 -#define YELL_DEATH "Dis not... da end of me..." -#define SOUND_YELL_DEATH 12051 - -#define SPELL_SPIRIT_BOLTS 43383 -#define SPELL_DRAIN_POWER 44131 -#define SPELL_SIPHON_SOUL 43501 - -#define MOB_TEMP_TRIGGER 23920 - -//Defines for various powers he uses after using soul drain - enum Spells { - // Druid - SPELL_DR_THORNS = 43420, - SPELL_DR_LIFEBLOOM = 43421, - SPELL_DR_MOONFIRE = 43545, - - // Hunter - SPELL_HU_EXPLOSIVE_TRAP = 43444, - SPELL_HU_FREEZING_TRAP = 43447, - SPELL_HU_SNAKE_TRAP = 43449, - - // Mage - SPELL_MG_FIREBALL = 41383, - SPELL_MG_FROST_NOVA = 43426, - SPELL_MG_ICE_LANCE = 43427, - SPELL_MG_FROSTBOLT = 43428, - - // Paladin - SPELL_PA_CONSECRATION = 43429, - SPELL_PA_AVENGING_WRATH = 43430, - SPELL_PA_HOLY_LIGHT = 43451, - - // Priest - SPELL_PR_HEAL = 41372, - SPELL_PR_MIND_BLAST = 41374, - SPELL_PR_SW_DEATH = 41375, - SPELL_PR_PSYCHIC_SCREAM = 43432, - SPELL_PR_MIND_CONTROL = 43550, - SPELL_PR_PAIN_SUPP = 44416, - - // Rogue - SPELL_RO_BLIND = 43433, - SPELL_RO_SLICE_DICE = 43457, - SPELL_RO_WOUND_POISON = 43461, - - // Shaman - SPELL_SH_CHAIN_LIGHT = 43435, - SPELL_SH_FIRE_NOVA = 43436, - SPELL_SH_HEALING_WAVE = 43548, - - // Warlock - SPELL_WL_CURSE_OF_DOOM = 43439, - SPELL_WL_RAIN_OF_FIRE = 43440, SPELL_WL_UNSTABLE_AFFL = 43522, SPELL_WL_UNSTABLE_AFFL_DISPEL = 43523, - - // Warrior - SPELL_WR_MORTAL_STRIKE = 43441, - SPELL_WR_WHIRLWIND = 43442, - SPELL_WR_SPELL_REFLECT = 43443 -}; - -#define ORIENT 1.5696f -#define POS_Y 921.2795f -#define POS_Z 33.8883f - -static float Pos_X[4] = {112.8827f, 107.8827f, 122.8827f, 127.8827f}; - -static uint32 AddEntryList[8]= -{ - 24240, //Alyson Antille - 24241, //Thurg - 24242, //Slither - 24243, //Lord Raadan - 24244, //Gazakroth - 24245, //Fenstalker - 24246, //Darkheart - 24247 //Koragg -}; - -enum AbilityTarget -{ - ABILITY_TARGET_SELF = 0, - ABILITY_TARGET_VICTIM = 1, - ABILITY_TARGET_ENEMY = 2, - ABILITY_TARGET_HEAL = 3, - ABILITY_TARGET_BUFF = 4, - ABILITY_TARGET_SPECIAL = 5 }; -struct PlayerAbilityStruct +enum Says { - uint32 spell; - AbilityTarget target; - uint32 cooldown; //FIXME - it's never used }; -static PlayerAbilityStruct PlayerAbility[][3] = +enum Events { - // 1 warrior - {{SPELL_WR_SPELL_REFLECT, ABILITY_TARGET_SELF, 10000}, - {SPELL_WR_WHIRLWIND, ABILITY_TARGET_SELF, 10000}, - {SPELL_WR_MORTAL_STRIKE, ABILITY_TARGET_VICTIM, 6000}}, - // 2 paladin - {{SPELL_PA_CONSECRATION, ABILITY_TARGET_SELF, 10000}, - {SPELL_PA_HOLY_LIGHT, ABILITY_TARGET_HEAL, 10000}, - {SPELL_PA_AVENGING_WRATH, ABILITY_TARGET_SELF, 10000}}, - // 3 hunter - {{SPELL_HU_EXPLOSIVE_TRAP, ABILITY_TARGET_SELF, 10000}, - {SPELL_HU_FREEZING_TRAP, ABILITY_TARGET_SELF, 10000}, - {SPELL_HU_SNAKE_TRAP, ABILITY_TARGET_SELF, 10000}}, - // 4 rogue - {{SPELL_RO_WOUND_POISON, ABILITY_TARGET_VICTIM, 3000}, - {SPELL_RO_SLICE_DICE, ABILITY_TARGET_SELF, 10000}, - {SPELL_RO_BLIND, ABILITY_TARGET_ENEMY, 10000}}, - // 5 priest - {{SPELL_PR_PAIN_SUPP, ABILITY_TARGET_HEAL, 10000}, - {SPELL_PR_HEAL, ABILITY_TARGET_HEAL, 10000}, - {SPELL_PR_PSYCHIC_SCREAM, ABILITY_TARGET_SELF, 10000}}, - // 5* shadow priest - {{SPELL_PR_MIND_CONTROL, ABILITY_TARGET_ENEMY, 15000}, - {SPELL_PR_MIND_BLAST, ABILITY_TARGET_ENEMY, 5000}, - {SPELL_PR_SW_DEATH, ABILITY_TARGET_ENEMY, 10000}}, - // 7 shaman - {{SPELL_SH_FIRE_NOVA, ABILITY_TARGET_SELF, 10000}, - {SPELL_SH_HEALING_WAVE, ABILITY_TARGET_HEAL, 10000}, - {SPELL_SH_CHAIN_LIGHT, ABILITY_TARGET_ENEMY, 8000}}, - // 8 mage - {{SPELL_MG_FIREBALL, ABILITY_TARGET_ENEMY, 5000}, - {SPELL_MG_FROSTBOLT, ABILITY_TARGET_ENEMY, 5000}, - {SPELL_MG_ICE_LANCE, ABILITY_TARGET_SPECIAL, 2000}}, - // 9 warlock - {{SPELL_WL_CURSE_OF_DOOM, ABILITY_TARGET_ENEMY, 10000}, - {SPELL_WL_RAIN_OF_FIRE, ABILITY_TARGET_ENEMY, 10000}, - {SPELL_WL_UNSTABLE_AFFL, ABILITY_TARGET_ENEMY, 10000}}, - // 11 druid - {{SPELL_DR_LIFEBLOOM, ABILITY_TARGET_HEAL, 10000}, - {SPELL_DR_THORNS, ABILITY_TARGET_SELF, 10000}, - {SPELL_DR_MOONFIRE, ABILITY_TARGET_ENEMY, 8000}} -}; - -struct boss_hexlord_addAI : public ScriptedAI -{ - InstanceScript* instance; - - boss_hexlord_addAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - void Reset() {} - - void EnterCombat(Unit* /*who*/) - { - DoZoneInCombat(); - } - - void UpdateAI(uint32 /*diff*/) - { - if (instance && instance->GetData(DATA_HEXLORDEVENT) != IN_PROGRESS) - { - EnterEvadeMode(); - return; - } - - DoMeleeAttackIfReady(); - } }; class boss_hexlord_malacrass : public CreatureScript { public: - boss_hexlord_malacrass() - : CreatureScript("boss_hexlord_malacrass") - { - } + boss_hexlord_malacrass() : CreatureScript("boss_hexlord_malacrass") { } - struct boss_hex_lord_malacrassAI : public ScriptedAI + struct boss_hex_lord_malacrassAI : public BossAI { - boss_hex_lord_malacrassAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - SelectAddEntry(); - for (uint8 i = 0; i < 4; ++i) - AddGUID[i] = 0; - } - - InstanceScript* instance; - - uint64 AddGUID[4]; - uint32 AddEntry[4]; - - uint64 PlayerGUID; - - uint32 SpiritBolts_Timer; - uint32 DrainPower_Timer; - uint32 SiphonSoul_Timer; - uint32 PlayerAbility_Timer; - uint32 CheckAddState_Timer; - uint32 ResetTimer; - - uint32 PlayerClass; + boss_hex_lord_malacrassAI(Creature* creature) : BossAI(creature, DATA_HEXLORD) { } void Reset() { - if (instance) - instance->SetData(DATA_HEXLORDEVENT, NOT_STARTED); - - SpiritBolts_Timer = 20000; - DrainPower_Timer = 60000; - SiphonSoul_Timer = 100000; - PlayerAbility_Timer = 99999; - CheckAddState_Timer = 5000; - ResetTimer = 5000; - - SpawnAdds(); - - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 46916); - me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); + _Reset(); } void EnterCombat(Unit* /*who*/) { - if (instance) - instance->SetData(DATA_HEXLORDEVENT, IN_PROGRESS); - - DoZoneInCombat(); - me->MonsterYell(YELL_AGGRO, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_AGGRO); - - for (uint8 i = 0; i < 4; ++i) - { - Creature* creature = Unit::GetCreature(*me, AddGUID[i]); - if (creature && creature->IsAlive()) - creature->AI()->AttackStart(me->GetVictim()); - else - { - EnterEvadeMode(); - break; - } - } + _EnterCombat(); } void KilledUnit(Unit* /*victim*/) { - switch (urand(0, 1)) - { - case 0: - me->MonsterYell(YELL_KILL_ONE, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE); - break; - case 1: - me->MonsterYell(YELL_KILL_TWO, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO); - break; - } } void JustDied(Unit* /*killer*/) { - if (instance) - instance->SetData(DATA_HEXLORDEVENT, DONE); - - me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_DEATH); - - for (uint8 i = 0; i < 4; ++i) - { - Unit* Temp = Unit::GetUnit(*me, AddGUID[i]); - if (Temp && Temp->IsAlive()) - Temp->DealDamage(Temp, Temp->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false); - } - } - - void SelectAddEntry() - { - std::vector<uint32> AddList; - - for (uint8 i = 0; i < 8; ++i) - AddList.push_back(AddEntryList[i]); - - while (AddList.size() > 4) - AddList.erase(AddList.begin()+rand()%AddList.size()); - - uint8 i = 0; - for (std::vector<uint32>::const_iterator itr = AddList.begin(); itr != AddList.end(); ++itr, ++i) - AddEntry[i] = *itr; - } - - void SpawnAdds() - { - for (uint8 i = 0; i < 4; ++i) - { - Creature* creature = (Unit::GetCreature((*me), AddGUID[i])); - if (!creature || !creature->IsAlive()) - { - if (creature) creature->setDeathState(DEAD); - creature = me->SummonCreature(AddEntry[i], Pos_X[i], POS_Y, POS_Z, ORIENT, TEMPSUMMON_DEAD_DESPAWN, 0); - if (creature) AddGUID[i] = creature->GetGUID(); - } - else - { - creature->AI()->EnterEvadeMode(); - creature->SetPosition(Pos_X[i], POS_Y, POS_Z, ORIENT); - creature->StopMoving(); - } - } + _JustDied(); } void UpdateAI(uint32 diff) @@ -356,590 +69,13 @@ class boss_hexlord_malacrass : public CreatureScript if (!UpdateVictim()) return; - if (ResetTimer <= diff) - { - if (me->IsWithinDist3d(119.223f, 1035.45f, 29.4481f, 10)) - { - EnterEvadeMode(); - return; - } - ResetTimer = 5000; - } else ResetTimer -= diff; - - if (CheckAddState_Timer <= diff) - { - for (uint8 i = 0; i < 4; ++i) - if (Creature* temp = Unit::GetCreature(*me, AddGUID[i])) - if (temp->IsAlive() && !temp->GetVictim()) - temp->AI()->AttackStart(me->GetVictim()); - - CheckAddState_Timer = 5000; - } else CheckAddState_Timer -= diff; - - if (DrainPower_Timer <= diff) - { - DoCast(me, SPELL_DRAIN_POWER, true); - me->MonsterYell(YELL_DRAIN_POWER, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_DRAIN_POWER); - DrainPower_Timer = urand(40000, 55000); // must cast in 60 sec, or buff/debuff will disappear - } else DrainPower_Timer -= diff; - - if (SpiritBolts_Timer <= diff) - { - if (DrainPower_Timer < 12000) // channel 10 sec - SpiritBolts_Timer = 13000; // cast drain power first - else - { - DoCast(me, SPELL_SPIRIT_BOLTS, false); - me->MonsterYell(YELL_SPIRIT_BOLTS, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_SPIRIT_BOLTS); - SpiritBolts_Timer = 40000; - SiphonSoul_Timer = 10000; // ready to drain - PlayerAbility_Timer = 99999; - } - } else SpiritBolts_Timer -= diff; - - if (SiphonSoul_Timer <= diff) - { - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 70, true); - Unit* trigger = DoSpawnCreature(MOB_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000); - if (!target || !trigger) - { - EnterEvadeMode(); - return; - } - else - { - trigger->SetDisplayId(11686); - trigger->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - trigger->CastSpell(target, SPELL_SIPHON_SOUL, true); - trigger->GetMotionMaster()->MoveChase(me); - - //DoCast(target, SPELL_SIPHON_SOUL, true); - //me->SetUInt64Value(UNIT_FIELD_CHANNEL_OBJECT, target->GetGUID()); - //me->SetUInt32Value(UNIT_CHANNEL_SPELL, SPELL_SIPHON_SOUL); - - PlayerGUID = target->GetGUID(); - PlayerAbility_Timer = urand(8000, 10000); - PlayerClass = target->getClass() - 1; - - if (PlayerClass == CLASS_DRUID-1) - PlayerClass = CLASS_DRUID; - else if (PlayerClass == CLASS_PRIEST-1 && target->HasSpell(15473)) - PlayerClass = CLASS_PRIEST; // shadow priest - - SiphonSoul_Timer = 99999; // buff lasts 30 sec - } - } else SiphonSoul_Timer -= diff; - - if (PlayerAbility_Timer <= diff) - { - //Unit* target = Unit::GetUnit(*me, PlayerGUID); - //if (target && target->IsAlive()) - //{ - UseAbility(); - PlayerAbility_Timer = urand(8000, 10000); - //} - } else PlayerAbility_Timer -= diff; - DoMeleeAttackIfReady(); } - - void UseAbility() - { - uint8 random = urand(0, 2); - Unit* target = NULL; - switch (PlayerAbility[PlayerClass][random].target) - { - case ABILITY_TARGET_SELF: - target = me; - break; - case ABILITY_TARGET_VICTIM: - target = me->GetVictim(); - break; - case ABILITY_TARGET_ENEMY: - default: - target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true); - break; - case ABILITY_TARGET_HEAL: - target = DoSelectLowestHpFriendly(50, 0); - break; - case ABILITY_TARGET_BUFF: - { - std::list<Creature*> templist = DoFindFriendlyMissingBuff(50, PlayerAbility[PlayerClass][random].spell); - if (!templist.empty()) - target = *(templist.begin()); - } - break; - } - if (target) - DoCast(target, PlayerAbility[PlayerClass][random].spell, false); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_hex_lord_malacrassAI(creature); - } -}; - -#define SPELL_BLOODLUST 43578 -#define SPELL_CLEAVE 15496 - -class boss_thurg : public CreatureScript -{ - public: - - boss_thurg() - : CreatureScript("boss_thurg") - { - } - - struct boss_thurgAI : public boss_hexlord_addAI - { - - boss_thurgAI(Creature* creature) : boss_hexlord_addAI(creature) {} - - uint32 bloodlust_timer; - uint32 cleave_timer; - - void Reset() - { - bloodlust_timer = 15000; - cleave_timer = 10000; - - boss_hexlord_addAI::Reset(); - } - - void UpdateAI(uint32 diff) - { - if (!UpdateVictim()) - return; - - if (bloodlust_timer <= diff) - { - std::list<Creature*> templist = DoFindFriendlyMissingBuff(50, SPELL_BLOODLUST); - if (!templist.empty()) - { - if (Unit* target = *(templist.begin())) - DoCast(target, SPELL_BLOODLUST, false); - } - bloodlust_timer = 12000; - } else bloodlust_timer -= diff; - - if (cleave_timer <= diff) - { - DoCast(me->GetVictim(), SPELL_CLEAVE, false); - cleave_timer = 12000; //3 sec cast - } else cleave_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_thurgAI(creature); - } -}; - -#define SPELL_FLASH_HEAL 43575 -#define SPELL_DISPEL_MAGIC 43577 - -class boss_alyson_antille : public CreatureScript -{ - public: - - boss_alyson_antille() - : CreatureScript("boss_alyson_antille") - { - } - - struct boss_alyson_antilleAI : public boss_hexlord_addAI - { - //Holy Priest - boss_alyson_antilleAI(Creature* creature) : boss_hexlord_addAI(creature) {} - - uint32 flashheal_timer; - uint32 dispelmagic_timer; - - void Reset() - { - flashheal_timer = 2500; - dispelmagic_timer = 10000; - - //AcquireGUID(); - - boss_hexlord_addAI::Reset(); - } - - void AttackStart(Unit* who) - { - if (!who) - return; - - if (who->isTargetableForAttack()) - { - if (me->Attack(who, false)) - { - me->GetMotionMaster()->MoveChase(who, 20); - me->AddThreat(who, 0.0f); - } - } - } - - void UpdateAI(uint32 diff) - { - if (!UpdateVictim()) - return; - - if (flashheal_timer <= diff) - { - Unit* target = DoSelectLowestHpFriendly(99, 30000); - if (target) - { - if (target->IsWithinDistInMap(me, 50)) - DoCast(target, SPELL_FLASH_HEAL, false); - else - { - // bugged - //me->GetMotionMaster()->Clear(); - //me->GetMotionMaster()->MoveChase(target, 20); - } - } - else - { - if (urand(0, 1)) - target = DoSelectLowestHpFriendly(50, 0); - else - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) - DoCast(target, SPELL_DISPEL_MAGIC, false); - } - flashheal_timer = 2500; - } else flashheal_timer -= diff; - - /*if (dispelmagic_timer <= diff) - { - if (urand(0, 1)) - { - Unit* target = SelectTarget(); - - DoCast(target, SPELL_DISPEL_MAGIC, false); - } - else - me->CastSpell(SelectUnit(SELECT_TARGET_RANDOM, 0), SPELL_DISPEL_MAGIC, false); - - dispelmagic_timer = 12000; - } else dispelmagic_timer -= diff;*/ - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_alyson_antilleAI(creature); - } -}; - -#define SPELL_FIREBOLT 43584 - -struct boss_gazakrothAI : public boss_hexlord_addAI -{ - boss_gazakrothAI(Creature* creature) : boss_hexlord_addAI(creature) {} - - uint32 firebolt_timer; - - void Reset() - { - firebolt_timer = 2000; - boss_hexlord_addAI::Reset(); - } - - void AttackStart(Unit* who) - { - if (!who) - return; - - if (who->isTargetableForAttack()) - { - if (me->Attack(who, false)) - { - me->GetMotionMaster()->MoveChase(who, 20); - me->AddThreat(who, 0.0f); - } - } - } - - void UpdateAI(uint32 diff) - { - if (!UpdateVictim()) - return; - - if (firebolt_timer <= diff) - { - DoCast(me->GetVictim(), SPELL_FIREBOLT, false); - firebolt_timer = 700; - } else firebolt_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } -}; - -#define SPELL_FLAME_BREATH 43582 -#define SPELL_THUNDERCLAP 43583 - -class boss_lord_raadan : public CreatureScript -{ - public: - - boss_lord_raadan() - : CreatureScript("boss_lord_raadan") - { - } - - struct boss_lord_raadanAI : public boss_hexlord_addAI - { - boss_lord_raadanAI(Creature* creature) : boss_hexlord_addAI(creature) {} - - uint32 flamebreath_timer; - uint32 thunderclap_timer; - - void Reset() - { - flamebreath_timer = 8000; - thunderclap_timer = 13000; - - boss_hexlord_addAI::Reset(); - - } - void UpdateAI(uint32 diff) - { - if (!UpdateVictim()) - return; - - if (thunderclap_timer <= diff) - { - DoCast(me->GetVictim(), SPELL_THUNDERCLAP, false); - thunderclap_timer = 12000; - } else thunderclap_timer -= diff; - - if (flamebreath_timer <= diff) - { - DoCast(me->GetVictim(), SPELL_FLAME_BREATH, false); - flamebreath_timer = 12000; - } else flamebreath_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_lord_raadanAI(creature); - } -}; - -#define SPELL_PSYCHIC_WAIL 43590 - -class boss_darkheart : public CreatureScript -{ - public: - - boss_darkheart() - : CreatureScript("boss_darkheart") - { - } - - struct boss_darkheartAI : public boss_hexlord_addAI - { - boss_darkheartAI(Creature* creature) : boss_hexlord_addAI(creature) {} - - uint32 psychicwail_timer; - - void Reset() - { - psychicwail_timer = 8000; - boss_hexlord_addAI::Reset(); - } - void UpdateAI(uint32 diff) - { - if (!UpdateVictim()) - return; - - if (psychicwail_timer <= diff) - { - DoCast(me->GetVictim(), SPELL_PSYCHIC_WAIL, false); - psychicwail_timer = 12000; - } else psychicwail_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_darkheartAI(creature); - } -}; - -#define SPELL_VENOM_SPIT 43579 - -class boss_slither : public CreatureScript -{ - public: - - boss_slither() - : CreatureScript("boss_slither") - { - } - - struct boss_slitherAI : public boss_hexlord_addAI - { - boss_slitherAI(Creature* creature) : boss_hexlord_addAI(creature) {} - - uint32 venomspit_timer; - - void Reset() - { - venomspit_timer = 5000; - boss_hexlord_addAI::Reset(); - } - - void AttackStart(Unit* who) - { - if (!who) - return; - - if (who->isTargetableForAttack()) - { - if (me->Attack(who, false)) - { - me->GetMotionMaster()->MoveChase(who, 20); - me->AddThreat(who, 0.0f); - } - } - } - - void UpdateAI(uint32 diff) - { - if (!UpdateVictim()) - return; - - if (venomspit_timer <= diff) - { - if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(victim, SPELL_VENOM_SPIT, false); - venomspit_timer = 2500; - } else venomspit_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_slitherAI(creature); - } -}; - -//Fenstalker -#define SPELL_VOLATILE_INFECTION 43586 -class boss_fenstalker : public CreatureScript -{ - public: - - boss_fenstalker() - : CreatureScript("boss_fenstalker") - { - } - - struct boss_fenstalkerAI : public boss_hexlord_addAI - { - boss_fenstalkerAI(Creature* creature) : boss_hexlord_addAI(creature) {} - - uint32 volatileinf_timer; - - void Reset() - { - volatileinf_timer = 15000; - boss_hexlord_addAI::Reset(); - - } - void UpdateAI(uint32 diff) - { - if (!UpdateVictim()) - return; - - if (volatileinf_timer <= diff) - { - // core bug - me->GetVictim()->CastSpell(me->GetVictim(), SPELL_VOLATILE_INFECTION, false); - volatileinf_timer = 12000; - } else volatileinf_timer -= diff; - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_fenstalkerAI(creature); - } -}; - -//Koragg -#define SPELL_COLD_STARE 43593 -#define SPELL_MIGHTY_BLOW 43592 - -class boss_koragg : public CreatureScript -{ - public: - - boss_koragg() - : CreatureScript("boss_koragg") - { - } - - struct boss_koraggAI : public boss_hexlord_addAI - { - boss_koraggAI(Creature* creature) : boss_hexlord_addAI(creature) {} - - uint32 coldstare_timer; - uint32 mightyblow_timer; - - void Reset() - { - coldstare_timer = 15000; - mightyblow_timer = 10000; - boss_hexlord_addAI::Reset(); - - } - void UpdateAI(uint32 diff) - { - if (!UpdateVictim()) - return; - - if (mightyblow_timer <= diff) - { - DoCast(me->GetVictim(), SPELL_MIGHTY_BLOW, false); - mightyblow_timer = 12000; - } - if (coldstare_timer <= diff) - { - if (Unit* victim = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(victim, SPELL_COLD_STARE, false); - coldstare_timer = 12000; - } - - boss_hexlord_addAI::UpdateAI(diff); - } }; CreatureAI* GetAI(Creature* creature) const { - return new boss_koraggAI(creature); + return GetZulAmanAI<boss_hex_lord_malacrassAI>(creature); } }; @@ -980,14 +116,6 @@ class spell_hexlord_unstable_affliction : public SpellScriptLoader void AddSC_boss_hex_lord_malacrass() { new boss_hexlord_malacrass(); - new boss_thurg(); - // new boss_gazakroth(); - new boss_lord_raadan(); - new boss_darkheart(); - new boss_slither(); - new boss_fenstalker(); - new boss_koragg(); - new boss_alyson_antille(); new spell_hexlord_unstable_affliction(); } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp index 51645b07158..6be856733fb 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * 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 @@ -16,693 +15,72 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Janalai -SD%Complete: 100 -SDComment: -SDCategory: Zul'Aman -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulaman.h" -#include "GridNotifiers.h" -#include "CellImpl.h" -enum eEnums +enum Spells { - SAY_AGGRO = 0, - SAY_FIRE_BOMBS = 1, - SAY_SUMMON_HATCHER = 2, - SAY_ALL_EGGS = 3, - SAY_BERSERK = 4, - SAY_SLAY = 5, - SAY_DEATH = 6, - SAY_EVENT_STRANGERS = 7, - SAY_EVENT_FRIENDS = 8, - -// Jan'alai - SPELL_FLAME_BREATH = 43140, - SPELL_FIRE_WALL = 43113, - SPELL_ENRAGE = 44779, - SPELL_SUMMON_PLAYERS = 43097, - SPELL_TELE_TO_CENTER = 43098, // coord - SPELL_HATCH_ALL = 43144, - SPELL_BERSERK = 45078, - -// -- Fire Bob Spells - SPELL_FIRE_BOMB_CHANNEL = 42621, // last forever - SPELL_FIRE_BOMB_THROW = 42628, // throw visual - SPELL_FIRE_BOMB_DUMMY = 42629, // bomb visual - SPELL_FIRE_BOMB_DAMAGE = 42630, - -// --Summons - MOB_AMANI_HATCHER = 23818, - MOB_HATCHLING = 23598, // 42493 - MOB_EGG = 23817, - MOB_FIRE_BOMB = 23920, - -// -- Hatcher Spells - SPELL_HATCH_EGG = 42471, // 43734 - SPELL_SUMMON_HATCHLING = 42493, - -// -- Hatchling Spells - SPELL_FLAMEBUFFET = 43299 }; -const int area_dx = 44; -const int area_dy = 51; - -float JanalainPos[1][3] = +enum Says { - {-33.93f, 1149.27f, 19} }; -float FireWallCoords[4][4] = +enum Events { - {-10.13f, 1149.27f, 19, 3.1415f}, - {-33.93f, 1123.90f, 19, 0.5f*3.1415f}, - {-54.80f, 1150.08f, 19, 0}, - {-33.93f, 1175.68f, 19, 1.5f*3.1415f} }; -float hatcherway[2][5][3] = -{ - { - {-87.46f, 1170.09f, 6}, - {-74.41f, 1154.75f, 6}, - {-52.74f, 1153.32f, 19}, - {-33.37f, 1172.46f, 19}, - {-33.09f, 1203.87f, 19} - }, - { - {-86.57f, 1132.85f, 6}, - {-73.94f, 1146.00f, 6}, - {-52.29f, 1146.51f, 19}, - {-33.57f, 1125.72f, 19}, - {-34.29f, 1095.22f, 19} - } -}; class boss_janalai : public CreatureScript { public: - boss_janalai() - : CreatureScript("boss_janalai") - { - } + boss_janalai() : CreatureScript("boss_janalai") { } - struct boss_janalaiAI : public ScriptedAI + struct boss_janalaiAI : public BossAI { - boss_janalaiAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 FireBreathTimer; - uint32 BombTimer; - uint32 BombSequenceTimer; - uint32 BombCount; - uint32 HatcherTimer; - uint32 EnrageTimer; - - bool noeggs; - bool enraged; - bool isBombing; - - bool isFlameBreathing; - - uint64 FireBombGUIDs[40]; + boss_janalaiAI(Creature* creature) : BossAI(creature, DATA_JANALAI) { } void Reset() { - if (instance) - instance->SetData(DATA_JANALAIEVENT, NOT_STARTED); - - FireBreathTimer = 8000; - BombTimer = 30000; - BombSequenceTimer = 1000; - BombCount = 0; - HatcherTimer = 10000; - EnrageTimer = MINUTE*5*IN_MILLISECONDS; - - noeggs = false; - isBombing =false; - enraged = false; - - isFlameBreathing = false; - - for (uint8 i = 0; i < 40; ++i) - FireBombGUIDs[i] = 0; - - HatchAllEggs(1); + _Reset(); } void JustDied(Unit* /*killer*/) { - Talk(SAY_DEATH); + //Talk(SAY_DEATH); - if (instance) - instance->SetData(DATA_JANALAIEVENT, DONE); + _JustDied(); } void KilledUnit(Unit* /*victim*/) { - Talk(SAY_SLAY); + //Talk(SAY_KILL_PLAYER); } void EnterCombat(Unit* /*who*/) { - if (instance) - instance->SetData(DATA_JANALAIEVENT, IN_PROGRESS); + _EnterCombat(); - Talk(SAY_AGGRO); - // DoZoneInCombat(); - } - - void DamageDealt(Unit* target, uint32 &damage, DamageEffectType /*damagetype*/) - { - if (isFlameBreathing) - { - if (!me->HasInArc(M_PI/6, target)) - damage = 0; - } - } - - void FireWall() - { - uint8 WallNum; - Creature* wall = NULL; - for (uint8 i = 0; i < 4; ++i) - { - if (i == 0 || i == 2) - WallNum = 3; - else - WallNum = 2; - - for (uint8 j = 0; j < WallNum; j++) - { - if (WallNum == 3) - wall = me->SummonCreature(MOB_FIRE_BOMB, FireWallCoords[i][0], FireWallCoords[i][1]+5*(j-1), FireWallCoords[i][2], FireWallCoords[i][3], TEMPSUMMON_TIMED_DESPAWN, 15000); - else - wall = me->SummonCreature(MOB_FIRE_BOMB, FireWallCoords[i][0]-2+4*j, FireWallCoords[i][1], FireWallCoords[i][2], FireWallCoords[i][3], TEMPSUMMON_TIMED_DESPAWN, 15000); - if (wall) wall->CastSpell(wall, SPELL_FIRE_WALL, true); - } - } - } - - void SpawnBombs() - { - float dx, dy; - for (int i(0); i < 40; ++i) - { - dx = float(irand(-area_dx/2, area_dx/2)); - dy = float(irand(-area_dy/2, area_dy/2)); - - Creature* bomb = DoSpawnCreature(MOB_FIRE_BOMB, dx, dy, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 15000); - if (bomb) - FireBombGUIDs[i] = bomb->GetGUID(); - } - BombCount = 0; - } - - bool HatchAllEggs(uint32 action) //1: reset, 2: isHatching all - { - std::list<Creature*> templist; - float x, y, z; - me->GetPosition(x, y, z); - - { - CellCoord pair(Trinity::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Trinity::AllCreaturesOfEntryInRange check(me, MOB_EGG, 100); - Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, templist, check); - - TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *me->GetMap(), *me, me->GetGridActivationRange()); - } - - //TC_LOG_ERROR(LOG_FILTER_TSCR, "Eggs %d at middle", templist.size()); - if (templist.empty()) - return false; - - for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i) - { - if (action == 1) - (*i)->SetDisplayId(10056); - else if (action == 2 &&(*i)->GetDisplayId() != 11686) - (*i)->CastSpell(*i, SPELL_HATCH_EGG, false); - } - return true; - } - - void Boom() - { - std::list<Creature*> templist; - float x, y, z; - me->GetPosition(x, y, z); - - { - CellCoord pair(Trinity::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Trinity::AllCreaturesOfEntryInRange check(me, MOB_FIRE_BOMB, 100); - Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, templist, check); - - TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *me->GetMap(), *me, me->GetGridActivationRange()); - } - for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i) - { - (*i)->CastSpell(*i, SPELL_FIRE_BOMB_DAMAGE, true); - (*i)->RemoveAllAuras(); - } - } - - void HandleBombSequence() - { - if (BombCount < 40) - { - if (Unit* FireBomb = Unit::GetUnit(*me, FireBombGUIDs[BombCount])) - { - FireBomb->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - DoCast(FireBomb, SPELL_FIRE_BOMB_THROW, true); - FireBomb->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - } - ++BombCount; - if (BombCount == 40) - { - BombSequenceTimer = 5000; - } else BombSequenceTimer = 100; - } - else - { - Boom(); - isBombing = false; - BombTimer = urand(20000, 40000); - me->RemoveAurasDueToSpell(SPELL_FIRE_BOMB_CHANNEL); - if (EnrageTimer <= 10000) - EnrageTimer = 0; - else - EnrageTimer -= 10000; - } + //Talk(SAY_AGGRO); } void UpdateAI(uint32 diff) { - if (isFlameBreathing) - { - if (!me->IsNonMeleeSpellCasted(false)) - isFlameBreathing = false; - else - return; - } - - if (isBombing) - { - if (BombSequenceTimer <= diff) - HandleBombSequence(); - else - BombSequenceTimer -= diff; - return; - } - if (!UpdateVictim()) return; - //enrage if under 25% hp before 5 min. - if (!enraged && HealthBelowPct(25)) - EnrageTimer = 0; - - if (EnrageTimer <= diff) - { - if (!enraged) - { - DoCast(me, SPELL_ENRAGE, true); - enraged = true; - EnrageTimer = 300000; - } - else - { - Talk(SAY_BERSERK); - DoCast(me, SPELL_BERSERK, true); - EnrageTimer = 300000; - } - } else EnrageTimer -= diff; - - if (BombTimer <= diff) - { - Talk(SAY_FIRE_BOMBS); - - me->AttackStop(); - me->GetMotionMaster()->Clear(); - DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]); - me->StopMoving(); - DoCast(me, SPELL_FIRE_BOMB_CHANNEL, false); - //DoTeleportPlayer(me, JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2], 0); - //DoCast(me, SPELL_TELE_TO_CENTER, true); - - FireWall(); - SpawnBombs(); - isBombing = true; - BombSequenceTimer = 100; - - //Teleport every Player into the middle - Map* map = me->GetMap(); - if (!map->IsDungeon()) - return; - - Map::PlayerList const &PlayerList = map->GetPlayers(); - for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i) - if (Player* i_pl = i->GetSource()) - if (i_pl->IsAlive()) - DoTeleportPlayer(i_pl, JanalainPos[0][0]-5+rand()%10, JanalainPos[0][1]-5+rand()%10, JanalainPos[0][2], 0); - //DoCast(Temp, SPELL_SUMMON_PLAYERS, true) // core bug, spell does not work if too far - return; - } else BombTimer -= diff; - - if (!noeggs) - { - if (HealthBelowPct(35)) - { - Talk(SAY_ALL_EGGS); - - me->AttackStop(); - me->GetMotionMaster()->Clear(); - DoTeleportTo(JanalainPos[0][0], JanalainPos[0][1], JanalainPos[0][2]); - me->StopMoving(); - DoCast(me, SPELL_HATCH_ALL, false); - HatchAllEggs(2); - noeggs = true; - } - else if (HatcherTimer <= diff) - { - if (HatchAllEggs(0)) - { - Talk(SAY_SUMMON_HATCHER); - me->SummonCreature(MOB_AMANI_HATCHER, hatcherway[0][0][0], hatcherway[0][0][1], hatcherway[0][0][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - me->SummonCreature(MOB_AMANI_HATCHER, hatcherway[1][0][0], hatcherway[1][0][1], hatcherway[1][0][2], 0, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 10000); - HatcherTimer = 90000; - } - else - noeggs = true; - } else HatcherTimer -= diff; - } - - EnterEvadeIfOutOfCombatArea(diff); - DoMeleeAttackIfReady(); - - if (FireBreathTimer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - me->AttackStop(); - me->GetMotionMaster()->Clear(); - DoCast(target, SPELL_FLAME_BREATH, false); - me->StopMoving(); - isFlameBreathing = true; - } - FireBreathTimer = 8000; - } else FireBreathTimer -= diff; } }; CreatureAI* GetAI(Creature* creature) const { - return new boss_janalaiAI(creature); + return GetZulAmanAI<boss_janalaiAI>(creature); } }; -class mob_janalai_firebomb : public CreatureScript -{ - public: - - mob_janalai_firebomb() - : CreatureScript("mob_janalai_firebomb") - { - } - - struct mob_janalai_firebombAI : public ScriptedAI - { - mob_janalai_firebombAI(Creature* creature) : ScriptedAI(creature){} - - void Reset() {} - - void SpellHit(Unit* /*caster*/, const SpellInfo* spell) - { - if (spell->Id == SPELL_FIRE_BOMB_THROW) - DoCast(me, SPELL_FIRE_BOMB_DUMMY, true); - } - - void EnterCombat(Unit* /*who*/) {} - - void AttackStart(Unit* /*who*/) {} - - void MoveInLineOfSight(Unit* /*who*/) {} - - void UpdateAI(uint32 /*diff*/) {} - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_janalai_firebombAI(creature); - } -}; - -class mob_janalai_hatcher : public CreatureScript -{ - public: - - mob_janalai_hatcher() - : CreatureScript("mob_janalai_hatcher") - { - } - - struct mob_janalai_hatcherAI : public ScriptedAI - { - mob_janalai_hatcherAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 waypoint; - uint32 HatchNum; - uint32 WaitTimer; - - bool side; - bool hasChangedSide; - bool isHatching; - - void Reset() - { - me->SetWalk(true); - side =(me->GetPositionY() < 1150); - waypoint = 0; - isHatching = false; - hasChangedSide = false; - WaitTimer = 1; - HatchNum = 0; - } - - bool HatchEggs(uint32 num) - { - std::list<Creature*> templist; - float x, y, z; - me->GetPosition(x, y, z); - - { - CellCoord pair(Trinity::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Trinity::AllCreaturesOfEntryInRange check(me, 23817, 50); - Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange> searcher(me, templist, check); - - TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllCreaturesOfEntryInRange>, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange()); - } - - //TC_LOG_ERROR(LOG_FILTER_TSCR, "Eggs %d at %d", templist.size(), side); - - for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end() && num > 0; ++i) - if ((*i)->GetDisplayId() != 11686) - { - (*i)->CastSpell(*i, SPELL_HATCH_EGG, false); - num--; - } - - return num == 0; // if num == 0, no more templist - } - - void EnterCombat(Unit* /*who*/) {} - void AttackStart(Unit* /*who*/) {} - void MoveInLineOfSight(Unit* /*who*/) {} - void MovementInform(uint32, uint32) - { - if (waypoint == 5) - { - isHatching = true; - HatchNum = 1; - WaitTimer = 5000; - } - else - WaitTimer = 1; - } - - void UpdateAI(uint32 diff) - { - if (!instance || !(instance->GetData(DATA_JANALAIEVENT) == IN_PROGRESS)) - { - me->DisappearAndDie(); - return; - } - - if (!isHatching) - { - if (WaitTimer) - { - me->GetMotionMaster()->Clear(); - me->GetMotionMaster()->MovePoint(0, hatcherway[side][waypoint][0], hatcherway[side][waypoint][1], hatcherway[side][waypoint][2]); - ++waypoint; - WaitTimer = 0; - } - } - else - { - if (WaitTimer <= diff) - { - if (HatchEggs(HatchNum)) - { - ++HatchNum; - WaitTimer = 10000; - } - else if (!hasChangedSide) - { - side = side ? 0 : 1; - isHatching = false; - waypoint = 3; - WaitTimer = 1; - hasChangedSide = true; - } - else - me->DisappearAndDie(); - - } else WaitTimer -= diff; - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_janalai_hatcherAI(creature); - } -}; - -class mob_janalai_hatchling : public CreatureScript -{ - public: - - mob_janalai_hatchling() - : CreatureScript("mob_janalai_hatchling") - { - } - - struct mob_janalai_hatchlingAI : public ScriptedAI - { - mob_janalai_hatchlingAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - uint32 BuffetTimer; - - void Reset() - { - BuffetTimer = 7000; - if (me->GetPositionY() > 1150) - me->GetMotionMaster()->MovePoint(0, hatcherway[0][3][0]+rand()%4-2, 1150.0f+rand()%4-2, hatcherway[0][3][2]); - else - me->GetMotionMaster()->MovePoint(0, hatcherway[1][3][0]+rand()%4-2, 1150.0f+rand()%4-2, hatcherway[1][3][2]); - - me->SetUnitMovementFlags(MOVEMENTFLAG_DISABLE_GRAVITY); - } - - void EnterCombat(Unit* /*who*/) {/*DoZoneInCombat();*/} - - void UpdateAI(uint32 diff) - { - if (!instance || !(instance->GetData(DATA_JANALAIEVENT) == IN_PROGRESS)) - { - me->DisappearAndDie(); - return; - } - - if (!UpdateVictim()) - return; - - if (BuffetTimer <= diff) - { - DoCast(me->GetVictim(), SPELL_FLAMEBUFFET, false); - BuffetTimer = 10000; - } else BuffetTimer -= diff; - - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_janalai_hatchlingAI(creature); - } -}; - -class mob_janalai_egg : public CreatureScript -{ -public: - mob_janalai_egg(): CreatureScript("mob_janalai_egg") {} - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_janalai_eggAI(creature); - } - - struct mob_janalai_eggAI : public ScriptedAI - { - mob_janalai_eggAI(Creature* creature) : ScriptedAI(creature){} - - void Reset() {} - - void UpdateAI(uint32 /*diff*/) {} - - void SpellHit(Unit* /*caster*/, const SpellInfo* spell) - { - if (spell->Id == SPELL_HATCH_EGG) - { - DoCast(SPELL_SUMMON_HATCHLING); - } - } - }; - -}; - void AddSC_boss_janalai() { new boss_janalai(); - new mob_janalai_firebomb(); - new mob_janalai_hatcher(); - new mob_janalai_hatchling(); - new mob_janalai_egg(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp index e8e72fe9e10..8d52c63fe53 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * 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 @@ -16,433 +15,55 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Boss_Nalorakk -SD%Complete: 100 -SDComment: -SDCategory: Zul'Aman -EndScriptData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "zulaman.h" -#include "GridNotifiers.h" -#include "GridNotifiersImpl.h" -#include "CellImpl.h" -//Trash Waves -float NalorakkWay[8][3] = +enum Spells { - { 18.569f, 1414.512f, 11.42f}, // waypoint 1 - {-17.264f, 1419.551f, 12.62f}, - {-52.642f, 1419.357f, 27.31f}, // waypoint 2 - {-69.908f, 1419.721f, 27.31f}, - {-79.929f, 1395.958f, 27.31f}, - {-80.072f, 1374.555f, 40.87f}, // waypoint 3 - {-80.072f, 1314.398f, 40.87f}, - {-80.072f, 1295.775f, 48.60f} // waypoint 4 }; -#define YELL_NALORAKK_WAVE1 "Get da move on, guards! It be killin' time!" -#define SOUND_NALORAKK_WAVE1 12066 -#define YELL_NALORAKK_WAVE2 "Guards, go already! Who you more afraid of, dem... or me?" -#define SOUND_NALORAKK_WAVE2 12067 -#define YELL_NALORAKK_WAVE3 "Ride now! Ride out dere and bring me back some heads!" -#define SOUND_NALORAKK_WAVE3 12068 -#define YELL_NALORAKK_WAVE4 "I be losin' me patience! Go on: make dem wish dey was never born!" -#define SOUND_NALORAKK_WAVE4 12069 - -//Unimplemented SoundIDs -/* -#define SOUND_NALORAKK_EVENT1 12078 -#define SOUND_NALORAKK_EVENT2 12079 -*/ - -//General defines -#define YELL_AGGRO "You be dead soon enough!" -#define SOUND_YELL_AGGRO 12070 -#define YELL_KILL_ONE "Mua-ha-ha! Now whatchoo got to say?" -#define SOUND_YELL_KILL_ONE 12075 -#define YELL_KILL_TWO "Da Amani gonna rule again!" -#define SOUND_YELL_KILL_TWO 12076 -#define YELL_DEATH "I... be waitin' on da udda side...." -#define SOUND_YELL_DEATH 12077 -#define YELL_BERSERK "You had your chance, now it be too late!" //Never seen this being used, so just guessing from what I hear. -#define SOUND_YELL_BERSERK 12074 - -#define SPELL_BERSERK 45078 - -//Defines for Troll form -#define SPELL_BRUTALSWIPE 42384 -#define SPELL_MANGLE 42389 -#define SPELL_MANGLEEFFECT 44955 -#define SPELL_SURGE 42402 -#define SPELL_BEARFORM 42377 - -#define YELL_SURGE "I bring da pain!" -#define SOUND_YELL_SURGE 12071 - -#define YELL_SHIFTEDTOTROLL "Make way for Nalorakk!" -#define SOUND_YELL_TOTROLL 12073 - -//Defines for Bear form -#define SPELL_LACERATINGSLASH 42395 -#define SPELL_RENDFLESH 42397 -#define SPELL_DEAFENINGROAR 42398 +enum Says +{ +}; -#define YELL_SHIFTEDTOBEAR "You call on da beast, you gonna get more dan you bargain for!" -#define SOUND_YELL_TOBEAR 12072 +enum Events +{ +}; class boss_nalorakk : public CreatureScript { public: - boss_nalorakk() - : CreatureScript("boss_nalorakk") - { - } + boss_nalorakk() : CreatureScript("boss_nalorakk") { } - struct boss_nalorakkAI : public ScriptedAI + struct boss_nalorakkAI : public BossAI { - boss_nalorakkAI(Creature* creature) : ScriptedAI(creature) - { - MoveEvent = true; - MovePhase = 0; - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - uint32 BrutalSwipe_Timer; - uint32 Mangle_Timer; - uint32 Surge_Timer; - - uint32 LaceratingSlash_Timer; - uint32 RendFlesh_Timer; - uint32 DeafeningRoar_Timer; - - uint32 ShapeShift_Timer; - uint32 Berserk_Timer; - - bool inBearForm; - bool MoveEvent; - bool inMove; - uint32 MovePhase; - uint32 waitTimer; + boss_nalorakkAI(Creature* creature) : BossAI(creature, DATA_NALORAKK) { } void Reset() { - if (MoveEvent) - { - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - inMove = false; - waitTimer = 0; - me->SetSpeed(MOVE_RUN, 2); - me->SetWalk(false); - }else - { - (*me).GetMotionMaster()->MovePoint(0, NalorakkWay[7][0], NalorakkWay[7][1], NalorakkWay[7][2]); - } - - if (instance) - instance->SetData(DATA_NALORAKKEVENT, NOT_STARTED); - - Surge_Timer = urand(15000, 20000); - BrutalSwipe_Timer = urand(7000, 12000); - Mangle_Timer = urand(10000, 15000); - ShapeShift_Timer = urand(45000, 50000); - Berserk_Timer = 600000; - - inBearForm = false; - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); /// @todo find the correct equipment id - } - - void SendAttacker(Unit* target) - { - std::list<Creature*> templist; - float x, y, z; - me->GetPosition(x, y, z); - - { - CellCoord pair(Trinity::ComputeCellCoord(x, y)); - Cell cell(pair); - cell.SetNoCreate(); - - Trinity::AllFriendlyCreaturesInGrid check(me); - Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid> searcher(me, templist, check); - - TypeContainerVisitor<Trinity::CreatureListSearcher<Trinity::AllFriendlyCreaturesInGrid>, GridTypeMapContainer> cSearcher(searcher); - - cell.Visit(pair, cSearcher, *(me->GetMap()), *me, me->GetGridActivationRange()); - } - - if (templist.empty()) - return; - - for (std::list<Creature*>::const_iterator i = templist.begin(); i != templist.end(); ++i) - { - if ((*i) && me->IsWithinDistInMap((*i), 25)) - { - (*i)->SetNoCallAssistance(true); - (*i)->AI()->AttackStart(target); - } - } - } - - void AttackStart(Unit* who) - { - if (!MoveEvent) - ScriptedAI::AttackStart(who); + _Reset(); } - - void MoveInLineOfSight(Unit* who) - { - if (!MoveEvent) - { - ScriptedAI::MoveInLineOfSight(who); - } - else - { - if (me->IsHostileTo(who)) - { - if (!inMove) - { - switch (MovePhase) - { - case 0: - if (me->IsWithinDistInMap(who, 50)) - { - me->MonsterYell(YELL_NALORAKK_WAVE1, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE1); - - (*me).GetMotionMaster()->MovePoint(1, NalorakkWay[1][0], NalorakkWay[1][1], NalorakkWay[1][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 2: - if (me->IsWithinDistInMap(who, 40)) - { - me->MonsterYell(YELL_NALORAKK_WAVE2, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE2); - - (*me).GetMotionMaster()->MovePoint(3, NalorakkWay[3][0], NalorakkWay[3][1], NalorakkWay[3][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 5: - if (me->IsWithinDistInMap(who, 40)) - { - me->MonsterYell(YELL_NALORAKK_WAVE3, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE3); - - (*me).GetMotionMaster()->MovePoint(6, NalorakkWay[6][0], NalorakkWay[6][1], NalorakkWay[6][2]); - MovePhase ++; - inMove = true; - - SendAttacker(who); - } - break; - case 7: - if (me->IsWithinDistInMap(who, 50)) - { - SendAttacker(who); - - me->MonsterYell(YELL_NALORAKK_WAVE4, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_NALORAKK_WAVE4); - - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - - MoveEvent = false; - } - break; - } - } - } - } - } - void EnterCombat(Unit* /*who*/) { - if (instance) - instance->SetData(DATA_NALORAKKEVENT, IN_PROGRESS); - - me->MonsterYell(YELL_AGGRO, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_AGGRO); - DoZoneInCombat(); + _EnterCombat(); } void JustDied(Unit* /*killer*/) { - if (instance) - instance->SetData(DATA_NALORAKKEVENT, DONE); - - me->MonsterYell(YELL_DEATH, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_DEATH); + _JustDied(); } void KilledUnit(Unit* /*victim*/) { - switch (urand(0, 1)) - { - case 0: - me->MonsterYell(YELL_KILL_ONE, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_KILL_ONE); - break; - case 1: - me->MonsterYell(YELL_KILL_TWO, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_KILL_TWO); - break; - } - } - - void MovementInform(uint32 type, uint32 id) - { - if (MoveEvent) - { - if (type != POINT_MOTION_TYPE) - return; - - if (!inMove) - return; - - if (MovePhase != id) - return; - - switch (MovePhase) - { - case 2: - me->SetOrientation(3.1415f*2); - inMove = false; - return; - case 1: - case 3: - case 4: - case 6: - MovePhase ++; - waitTimer = 1; - inMove = true; - return; - case 5: - me->SetOrientation(3.1415f*0.5f); - inMove = false; - return; - case 7: - me->SetOrientation(3.1415f*0.5f); - inMove = false; - return; - } - - } } void UpdateAI(uint32 diff) { - if (waitTimer && inMove) - { - if (waitTimer <= diff) - { - (*me).GetMotionMaster()->MovementExpired(); - (*me).GetMotionMaster()->MovePoint(MovePhase, NalorakkWay[MovePhase][0], NalorakkWay[MovePhase][1], NalorakkWay[MovePhase][2]); - waitTimer = 0; - } else waitTimer -= diff; - } - if (!UpdateVictim()) return; - if (Berserk_Timer <= diff) - { - DoCast(me, SPELL_BERSERK, true); - me->MonsterYell(YELL_BERSERK, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_BERSERK); - Berserk_Timer = 600000; - } else Berserk_Timer -= diff; - - if (ShapeShift_Timer <= diff) - { - if (inBearForm) - { - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 5122); - me->MonsterYell(YELL_SHIFTEDTOTROLL, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_TOTROLL); - me->RemoveAurasDueToSpell(SPELL_BEARFORM); - Surge_Timer = urand(15000, 20000); - BrutalSwipe_Timer = urand(7000, 12000); - Mangle_Timer = urand(10000, 15000); - ShapeShift_Timer = urand(45000, 50000); - inBearForm = false; - } - else - { - // me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, 0); - me->MonsterYell(YELL_SHIFTEDTOBEAR, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_TOBEAR); - DoCast(me, SPELL_BEARFORM, true); - LaceratingSlash_Timer = 2000; // dur 18s - RendFlesh_Timer = 3000; // dur 5s - DeafeningRoar_Timer = urand(5000, 10000); // dur 2s - ShapeShift_Timer = urand(20000, 25000); // dur 30s - inBearForm = true; - } - } else ShapeShift_Timer -= diff; - - if (!inBearForm) - { - if (BrutalSwipe_Timer <= diff) - { - DoCast(me->GetVictim(), SPELL_BRUTALSWIPE); - BrutalSwipe_Timer = urand(7000, 12000); - } else BrutalSwipe_Timer -= diff; - - if (Mangle_Timer <= diff) - { - if (me->GetVictim() && !me->GetVictim()->HasAura(SPELL_MANGLEEFFECT)) - { - DoCast(me->GetVictim(), SPELL_MANGLE); - Mangle_Timer = 1000; - } - else Mangle_Timer = urand(10000, 15000); - } else Mangle_Timer -= diff; - - if (Surge_Timer <= diff) - { - me->MonsterYell(YELL_SURGE, LANG_UNIVERSAL, 0); - DoPlaySoundToSet(me, SOUND_YELL_SURGE); - Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 1, 45, true); - if (target) - DoCast(target, SPELL_SURGE); - Surge_Timer = urand(15000, 20000); - } else Surge_Timer -= diff; - } - else - { - if (LaceratingSlash_Timer <= diff) - { - DoCast(me->GetVictim(), SPELL_LACERATINGSLASH); - LaceratingSlash_Timer = urand(18000, 23000); - } else LaceratingSlash_Timer -= diff; - - if (RendFlesh_Timer <= diff) - { - DoCast(me->GetVictim(), SPELL_RENDFLESH); - RendFlesh_Timer = urand(5000, 10000); - } else RendFlesh_Timer -= diff; - - if (DeafeningRoar_Timer <= diff) - { - DoCast(me->GetVictim(), SPELL_DEAFENINGROAR); - DeafeningRoar_Timer = urand(15000, 20000); - } else DeafeningRoar_Timer -= diff; - } - DoMeleeAttackIfReady(); } }; @@ -457,4 +78,3 @@ void AddSC_boss_nalorakk() { new boss_nalorakk(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp deleted file mode 100644 index 9a3fbd0358f..00000000000 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp +++ /dev/null @@ -1,604 +0,0 @@ -/* - * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * 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, see <http://www.gnu.org/licenses/>. - */ - -/* ScriptData -SDName: Boss_ZulJin -SD%Complete: 85% -SDComment: -EndScriptData */ - -#include "ScriptMgr.h" -#include "ScriptedCreature.h" -#include "zulaman.h" -#include "SpellInfo.h" - -enum Says -{ - YELL_INTRO = 0, - YELL_AGGRO = 1, - YELL_TRANSFORM_TO_BEAR = 2, - YELL_TRANSFORM_TO_EAGLE = 3, - YELL_TRANSFORM_TO_LYNX = 4, - YELL_TRANSFORM_TO_DRAGONHAWK = 5, - YELL_FIRE_BREATH = 6, - YELL_BERSERK = 7, - YELL_KILL = 8, - YELL_DEATH = 9 -}; - -enum Spells -{ - // Troll Form - SPELL_WHIRLWIND = 17207, - SPELL_GRIEVOUS_THROW = 43093, // remove debuff after full healed - // Bear Form - SPELL_CREEPING_PARALYSIS = 43095, // should cast on the whole raid - SPELL_OVERPOWER = 43456, // use after melee attack dodged - // Eagle Form - SPELL_ENERGY_STORM = 43983, // enemy area aura, trigger 42577 - SPELL_ZAP_INFORM = 42577, - SPELL_ZAP_DAMAGE = 43137, // 1250 damage - SPELL_SUMMON_CYCLONE = 43112, // summon four feather vortex - CREATURE_FEATHER_VORTEX = 24136, - SPELL_CYCLONE_VISUAL = 43119, // trigger 43147 visual - SPELL_CYCLONE_PASSIVE = 43120, // trigger 43121 (4y aoe) every second - // Lynx Form - SPELL_CLAW_RAGE_HASTE = 42583, - SPELL_CLAW_RAGE_TRIGGER = 43149, - SPELL_CLAW_RAGE_DAMAGE = 43150, - SPELL_LYNX_RUSH_HASTE = 43152, - SPELL_LYNX_RUSH_DAMAGE = 43153, - // Dragonhawk Form - SPELL_FLAME_WHIRL = 43213, // trigger two spells - SPELL_FLAME_BREATH = 43215, - SPELL_SUMMON_PILLAR = 43216, // summon 24187 - CREATURE_COLUMN_OF_FIRE = 24187, - SPELL_PILLAR_TRIGGER = 43218, // trigger 43217 - // Cosmetic - SPELL_SPIRIT_AURA = 42466, - SPELL_SIPHON_SOUL = 43501, - // Transforms: - SPELL_SHAPE_OF_THE_BEAR = 42594, // 15% dmg - SPELL_SHAPE_OF_THE_EAGLE = 42606, - SPELL_SHAPE_OF_THE_LYNX = 42607, // haste melee 30% - SPELL_SHAPE_OF_THE_DRAGONHAWK = 42608, - - SPELL_BERSERK = 45078 -}; - -enum Phase -{ - PHASE_BEAR = 0, - PHASE_EAGLE = 1, - PHASE_LYNX = 2, - PHASE_DRAGONHAWK = 3, - PHASE_TROLL = 4 -}; - -//coords for going for changing form -#define CENTER_X 120.148811f -#define CENTER_Y 703.713684f -#define CENTER_Z 45.111477f - -struct SpiritInfoStruct -{ - uint32 entry; - float x, y, z, orient; -}; - -static SpiritInfoStruct SpiritInfo[4] = -{ - {23878, 147.87f, 706.51f, 45.11f, 3.04f}, - {23880, 88.95f, 705.49f, 45.11f, 6.11f}, - {23877, 137.23f, 725.98f, 45.11f, 3.71f}, - {23879, 104.29f, 726.43f, 45.11f, 5.43f} -}; - -struct TransformStruct -{ - uint8 text; - uint32 spell, unaura; -}; - -static TransformStruct Transform[4] = -{ - {YELL_TRANSFORM_TO_BEAR, SPELL_SHAPE_OF_THE_BEAR, SPELL_WHIRLWIND}, - {YELL_TRANSFORM_TO_EAGLE, SPELL_SHAPE_OF_THE_EAGLE, SPELL_SHAPE_OF_THE_BEAR}, - {YELL_TRANSFORM_TO_LYNX, SPELL_SHAPE_OF_THE_LYNX, SPELL_SHAPE_OF_THE_EAGLE}, - {YELL_TRANSFORM_TO_DRAGONHAWK, SPELL_SHAPE_OF_THE_DRAGONHAWK, SPELL_SHAPE_OF_THE_LYNX} -}; - -class boss_zuljin : public CreatureScript -{ - public: - - boss_zuljin() - : CreatureScript("boss_zuljin") - { - } - - struct boss_zuljinAI : public ScriptedAI - { - boss_zuljinAI(Creature* creature) : ScriptedAI(creature), Summons(me) - { - instance = creature->GetInstanceScript(); - } - InstanceScript* instance; - - uint64 SpiritGUID[4]; - uint64 ClawTargetGUID; - uint64 TankGUID; - - uint32 Phase; - uint32 health_20; - - uint32 Intro_Timer; - uint32 Berserk_Timer; - - uint32 Whirlwind_Timer; - uint32 Grievous_Throw_Timer; - - uint32 Creeping_Paralysis_Timer; - uint32 Overpower_Timer; - - uint32 Claw_Rage_Timer; - uint32 Lynx_Rush_Timer; - uint32 Claw_Counter; - uint32 Claw_Loop_Timer; - - uint32 Flame_Whirl_Timer; - uint32 Flame_Breath_Timer; - uint32 Pillar_Of_Fire_Timer; - - SummonList Summons; - - void Reset() - { - if (instance) - instance->SetData(DATA_ZULJINEVENT, NOT_STARTED); - - Phase = 0; - - health_20 = me->CountPctFromMaxHealth(20); - - Intro_Timer = 37000; - Berserk_Timer = 600000; - - Whirlwind_Timer = 7000; - Grievous_Throw_Timer = 8000; - - Creeping_Paralysis_Timer = 7000; - Overpower_Timer = 0; - - Claw_Rage_Timer = 5000; - Lynx_Rush_Timer = 14000; - Claw_Loop_Timer = 0; - Claw_Counter = 0; - - Flame_Whirl_Timer = 5000; - Flame_Breath_Timer = 6000; - Pillar_Of_Fire_Timer = 7000; - - ClawTargetGUID = 0; - TankGUID = 0; - - Summons.DespawnAll(); - - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 33975); - //me->SetUInt32Value(UNIT_VIRTUAL_ITEM_INFO, 218172674); - //me->SetByteValue(UNIT_FIELD_BYTES_2, 0, SHEATH_STATE_MELEE); - } - - void EnterCombat(Unit* /*who*/) - { - if (instance) - instance->SetData(DATA_ZULJINEVENT, IN_PROGRESS); - - DoZoneInCombat(); - - Talk(YELL_INTRO); - SpawnAdds(); - EnterPhase(0); - } - - void KilledUnit(Unit* /*victim*/) - { - if (Intro_Timer) - return; - - Talk(YELL_KILL); - } - - void JustDied(Unit* /*killer*/) - { - if (instance) - instance->SetData(DATA_ZULJINEVENT, DONE); - - Talk(YELL_DEATH); - Summons.DespawnEntry(CREATURE_COLUMN_OF_FIRE); - - if (Unit* Temp = Unit::GetUnit(*me, SpiritGUID[3])) - Temp->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD); - } - - void AttackStart(Unit* who) - { - if (Phase == 2) - AttackStartNoMove(who); - else - ScriptedAI::AttackStart(who); - } - - void DoMeleeAttackIfReady() - { - if (!me->IsNonMeleeSpellCasted(false)) - { - if (me->isAttackReady() && me->IsWithinMeleeRange(me->GetVictim())) - { - if (Phase == 1 && !Overpower_Timer) - { - uint32 health = me->GetVictim()->GetHealth(); - me->AttackerStateUpdate(me->GetVictim()); - if (me->GetVictim() && health == me->GetVictim()->GetHealth()) - { - DoCast(me->GetVictim(), SPELL_OVERPOWER, false); - Overpower_Timer = 5000; - } - } else me->AttackerStateUpdate(me->GetVictim()); - me->resetAttackTimer(); - } - } - } - - void SpawnAdds() - { - Creature* creature = NULL; - for (uint8 i = 0; i < 4; ++i) - { - creature = me->SummonCreature(SpiritInfo[i].entry, SpiritInfo[i].x, SpiritInfo[i].y, SpiritInfo[i].z, SpiritInfo[i].orient, TEMPSUMMON_DEAD_DESPAWN, 0); - if (creature) - { - creature->CastSpell(creature, SPELL_SPIRIT_AURA, true); - creature->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - SpiritGUID[i] = creature->GetGUID(); - } - } - } - - void DespawnAdds() - { - for (uint8 i = 0; i < 4; ++i) - { - if (SpiritGUID[i]) - { - if (Unit* temp = Unit::GetUnit(*me, SpiritGUID[i])) - { - temp->SetVisible(false); - temp->setDeathState(DEAD); - } - } - SpiritGUID[i] = 0; - } - } - - void JustSummoned(Creature* summon) - { - Summons.Summon(summon); - } - - void SummonedCreatureDespawn(Creature* summon) - { - Summons.Despawn(summon); - } - - void EnterPhase(uint32 NextPhase) - { - switch (NextPhase) - { - case 0: - break; - case 1: - case 2: - case 3: - case 4: - DoTeleportTo(CENTER_X, CENTER_Y, CENTER_Z, 100); - DoResetThreat(); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, 0); - me->RemoveAurasDueToSpell(Transform[Phase].unaura); - DoCast(me, Transform[Phase].spell); - Talk(Transform[Phase].text); - if (Phase > 0) - { - if (Unit* Temp = Unit::GetUnit(*me, SpiritGUID[Phase - 1])) - Temp->SetUInt32Value(UNIT_FIELD_BYTES_1, UNIT_STAND_STATE_DEAD); - } - if (Unit* Temp = Unit::GetUnit(*me, SpiritGUID[NextPhase - 1])) - Temp->CastSpell(me, SPELL_SIPHON_SOUL, false); // should m cast on temp - if (NextPhase == 2) - { - me->GetMotionMaster()->Clear(); - DoCast(me, SPELL_ENERGY_STORM, true); // enemy aura - for (uint8 i = 0; i < 4; ++i) - { - Creature* Vortex = DoSpawnCreature(CREATURE_FEATHER_VORTEX, 0, 0, 0, 0, TEMPSUMMON_CORPSE_DESPAWN, 0); - if (Vortex) - { - Vortex->CastSpell(Vortex, SPELL_CYCLONE_PASSIVE, true); - Vortex->CastSpell(Vortex, SPELL_CYCLONE_VISUAL, true); - Vortex->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - Vortex->SetSpeed(MOVE_RUN, 1.0f); - Vortex->AI()->AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0)); - DoZoneInCombat(Vortex); - } - } - } - else - me->AI()->AttackStart(me->GetVictim()); - if (NextPhase == 3) - { - me->RemoveAurasDueToSpell(SPELL_ENERGY_STORM); - Summons.DespawnEntry(CREATURE_FEATHER_VORTEX); - me->GetMotionMaster()->MoveChase(me->GetVictim()); - } - break; - default: - break; - } - Phase = NextPhase; - } - - void UpdateAI(uint32 diff) - { - if (!TankGUID) - { - if (!UpdateVictim()) - return; - - if (me->GetHealth() < health_20 * (4 - Phase)) - EnterPhase(Phase + 1); - } - - if (Berserk_Timer <= diff) - { - DoCast(me, SPELL_BERSERK, true); - Talk(YELL_BERSERK); - Berserk_Timer = 60000; - } else Berserk_Timer -= diff; - - switch (Phase) - { - case 0: - if (Intro_Timer) - { - if (Intro_Timer <= diff) - { - Talk(YELL_AGGRO); - Intro_Timer = 0; - } else Intro_Timer -= diff; - } - - if (Whirlwind_Timer <= diff) - { - DoCast(me, SPELL_WHIRLWIND); - Whirlwind_Timer = urand(15000, 20000); - } else Whirlwind_Timer -= diff; - - if (Grievous_Throw_Timer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true)) - DoCast(target, SPELL_GRIEVOUS_THROW, false); - Grievous_Throw_Timer = 10000; - } else Grievous_Throw_Timer -= diff; - break; - - case 1: - if (Creeping_Paralysis_Timer <= diff) - { - DoCast(me, SPELL_CREEPING_PARALYSIS); - Creeping_Paralysis_Timer = 20000; - } else Creeping_Paralysis_Timer -= diff; - - if (Overpower_Timer <= diff) - { - // implemented in DoMeleeAttackIfReady() - Overpower_Timer = 0; - } else Overpower_Timer -= diff; - break; - - case 2: - return; - - case 3: - if (Claw_Rage_Timer <= diff) - { - if (!TankGUID) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - TankGUID = me->GetVictim()->GetGUID(); - me->SetSpeed(MOVE_RUN, 5.0f); - AttackStart(target); // change victim - Claw_Rage_Timer = 0; - Claw_Loop_Timer = 500; - Claw_Counter = 0; - } - } - else if (!Claw_Rage_Timer) // do not do this when Lynx_Rush - { - if (Claw_Loop_Timer <= diff) - { - Unit* target = me->GetVictim(); - if (!target || !target->isTargetableForAttack()) target = Unit::GetUnit(*me, TankGUID); - if (!target || !target->isTargetableForAttack()) target = SelectTarget(SELECT_TARGET_RANDOM, 0); - if (target) - { - AttackStart(target); - if (me->IsWithinMeleeRange(target)) - { - DoCast(target, SPELL_CLAW_RAGE_DAMAGE, true); - ++Claw_Counter; - if (Claw_Counter == 12) - { - Claw_Rage_Timer = urand(15000, 20000); - me->SetSpeed(MOVE_RUN, 1.2f); - AttackStart(Unit::GetUnit(*me, TankGUID)); - TankGUID = 0; - return; - } - else - Claw_Loop_Timer = 500; - } - } - else - { - EnterEvadeMode(); // if (target) - return; - } - } else Claw_Loop_Timer -= diff; - } //if (TankGUID) - } else Claw_Rage_Timer -= diff; - - if (Lynx_Rush_Timer <= diff) - { - if (!TankGUID) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - { - TankGUID = me->GetVictim()->GetGUID(); - me->SetSpeed(MOVE_RUN, 5.0f); - AttackStart(target); // change victim - Lynx_Rush_Timer = 0; - Claw_Counter = 0; - } - } - else if (!Lynx_Rush_Timer) - { - Unit* target = me->GetVictim(); - if (!target || !target->isTargetableForAttack()) - { - target = SelectTarget(SELECT_TARGET_RANDOM, 0); - AttackStart(target); - } - if (target) - { - if (me->IsWithinMeleeRange(target)) - { - DoCast(target, SPELL_LYNX_RUSH_DAMAGE, true); - ++Claw_Counter; - if (Claw_Counter == 9) - { - Lynx_Rush_Timer = urand(15000, 20000); - me->SetSpeed(MOVE_RUN, 1.2f); - AttackStart(Unit::GetUnit(*me, TankGUID)); - TankGUID = 0; - } - else - AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0)); - } - } - else - { - EnterEvadeMode(); // if (target) - return; - } - } //if (TankGUID) - } else Lynx_Rush_Timer -= diff; - - break; - case 4: - if (Flame_Whirl_Timer <= diff) - { - DoCast(me, SPELL_FLAME_WHIRL); - Flame_Whirl_Timer = 12000; - }Flame_Whirl_Timer -= diff; - - if (Pillar_Of_Fire_Timer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - DoCast(target, SPELL_SUMMON_PILLAR); - Pillar_Of_Fire_Timer = 10000; - } else Pillar_Of_Fire_Timer -= diff; - - if (Flame_Breath_Timer <= diff) - { - if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) - me->SetInFront(target); - DoCast(me, SPELL_FLAME_BREATH); - Flame_Breath_Timer = 10000; - } else Flame_Breath_Timer -= diff; - break; - - default: - break; - } - - if (!TankGUID) - DoMeleeAttackIfReady(); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new boss_zuljinAI(creature); - } -}; - -class mob_zuljin_vortex : public CreatureScript -{ - public: - - mob_zuljin_vortex() - : CreatureScript("mob_zuljin_vortex") - { - } - - struct mob_zuljin_vortexAI : public ScriptedAI - { - mob_zuljin_vortexAI(Creature* creature) : ScriptedAI(creature) {} - - void Reset() {} - - void EnterCombat(Unit* /*target*/) {} - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (spell->Id == SPELL_ZAP_INFORM) - DoCast(caster, SPELL_ZAP_DAMAGE, true); - } - - void UpdateAI(uint32 /*diff*/) - { - //if the vortex reach the target, it change his target to another player - if (me->IsWithinMeleeRange(me->GetVictim())) - AttackStart(SelectTarget(SELECT_TARGET_RANDOM, 0)); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new mob_zuljin_vortexAI(creature); - } -}; - -void AddSC_boss_zuljin() -{ - new boss_zuljin(); - new mob_zuljin_vortex(); -} - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp index c8409805a36..85265ddad5d 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp @@ -1,6 +1,5 @@ - /* +/* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * 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 @@ -16,136 +15,68 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: instance_zulaman -SD%Complete: 80 -SDComment: -SDCategory: Zul'Aman -EndScriptData */ - #include "ScriptMgr.h" #include "InstanceScript.h" #include "zulaman.h" -#include "Player.h" -#include "TemporarySummon.h" - -enum Misc -{ - MAX_ENCOUNTER = 7, - RAND_VENDOR = 2, - WORLDSTATE_SHOW_TIMER = 3104, - WORLDSTATE_TIME_TO_SACRIFICE = 3106 -}; - -// Chests spawn at bear/eagle/dragonhawk/lynx bosses -// The loots depend on how many bosses have been killed, but not the entries of the chests -// But we cannot add loots to gameobject, so we have to use the fixed loot_template -struct SHostageInfo -{ - uint32 npc, go; // FIXME go Not used - float x, y, z, o; -}; - -static SHostageInfo HostageInfo[] = -{ - {23790, 186648, -57, 1343, 40.77f, 3.2f}, // bear - {23999, 187021, 400, 1414, 74.36f, 3.3f}, // eagle - {24001, 186672, -35, 1134, 18.71f, 1.9f}, // dragonhawk - {24024, 186667, 413, 1117, 6.32f, 3.1f} // lynx -}; - -Position const HarrisonJonesLoc = {120.687f, 1674.0f, 42.0217f, 1.59044f}; class instance_zulaman : public InstanceMapScript { public: - instance_zulaman() - : InstanceMapScript("instance_zulaman", 568) - { - } + instance_zulaman() : InstanceMapScript(ZulAmanScriptName, 568) { } - struct instance_zulaman_InstanceMapScript : public InstanceScript + struct instance_zulaman_InstanceScript : public InstanceScript { - instance_zulaman_InstanceMapScript(Map* map) : InstanceScript(map) {} - - uint64 HarkorsSatchelGUID; - uint64 TanzarsTrunkGUID; - uint64 AshlisBagGUID; - uint64 KrazsPackageGUID; - uint64 StrangeGongGUID; - uint64 HarrisonJonesGUID; - - uint64 HexLordGateGUID; - uint64 ZulJinGateGUID; - uint64 MassiveGateGUID; - uint64 AkilzonDoorGUID; - uint64 ZulJinDoorGUID; - uint64 HalazziDoorGUID; - - uint32 QuestTimer; - uint16 BossKilled; - uint16 QuestMinute; - uint16 ChestLooted; - - uint32 m_auiEncounter[MAX_ENCOUNTER]; - uint32 RandVendor[RAND_VENDOR]; - - void Initialize() + instance_zulaman_InstanceScript(InstanceMap* map) : InstanceScript(map) { - memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); - - HarkorsSatchelGUID = 0; - TanzarsTrunkGUID = 0; - AshlisBagGUID = 0; - KrazsPackageGUID = 0; - StrangeGongGUID = 0; - HexLordGateGUID = 0; - ZulJinGateGUID = 0; - MassiveGateGUID = 0; - AkilzonDoorGUID = 0; - HalazziDoorGUID = 0; - ZulJinDoorGUID = 0; - - HarrisonJonesGUID = 0; - - QuestTimer = 0; - QuestMinute = 0; - BossKilled = 0; - ChestLooted = 0; - - for (uint8 i = 0; i < RAND_VENDOR; ++i) - RandVendor[i] = NOT_STARTED; - - m_auiEncounter[DATA_GONGEVENT] = NOT_STARTED; - } - - bool IsEncounterInProgress() const - { - for (uint8 i = 0; i < MAX_ENCOUNTER; ++i) - if (m_auiEncounter[i] == IN_PROGRESS) - return true; - - return false; + SetBossNumber(EncounterCount); + + AkilzonGUID = 0; + NalorakkGUID = 0; + JanalaiGUID = 0; + HalazziGUID = 0; + HexLordMalacrassGUID = 0; + DaakaraGUID = 0; + VoljinGUID = 0; + HexLordTriggerGUID = 0; + SpeedRunTimer = 16; + ZulAmanState = NOT_STARTED; + ZulAmanBossCount = 0; } - void OnPlayerEnter(Player* /*player*/) + void FillInitialWorldStates(WorldPacket& packet) { - if (!HarrisonJonesGUID) - instance->SummonCreature(NPC_HARRISON_JONES, HarrisonJonesLoc); + packet << uint32(WORLD_STATE_ZULAMAN_TIMER_ENABLED) << uint32(ZulAmanState ? 1 : 0); + packet << uint32(WORLD_STATE_ZULAMAN_TIMER) << uint32(SpeedRunTimer); } void OnCreatureCreate(Creature* creature) { switch (creature->GetEntry()) { - case NPC_HARRISON_JONES: - HarrisonJonesGUID = creature->GetGUID(); + case NPC_AKILZON: + AkilzonGUID = creature->GetGUID(); + break; + case NPC_NALORAKK: + NalorakkGUID = creature->GetGUID(); break; case NPC_JANALAI: - case NPC_ZULJIN: - case NPC_HEXLORD: + JanalaiGUID = creature->GetGUID(); + break; case NPC_HALAZZI: - case NPC_NALORAKK: + HalazziGUID = creature->GetGUID(); + break; + case NPC_HEXLORD: + HexLordMalacrassGUID = creature->GetGUID(); + break; + case NPC_DAAKARA: + DaakaraGUID = creature->GetGUID(); + break; + case NPC_VOLJIN: + VoljinGUID = creature->GetGUID(); + break; + case NPC_HEXLORD_TRIGGER: + HexLordTriggerGUID = creature->GetGUID(); + break; default: break; } @@ -155,219 +86,261 @@ class instance_zulaman : public InstanceMapScript { switch (go->GetEntry()) { - case GO_DOOR_HALAZZI: HalazziDoorGUID = go->GetGUID(); break; - case GO_GATE_ZULJIN: ZulJinGateGUID = go->GetGUID(); break; - case GO_GATE_HEXLORD: HexLordGateGUID = go->GetGUID(); break; - case GO_MASSIVE_GATE: MassiveGateGUID = go->GetGUID(); break; - case GO_DOOR_AKILZON: AkilzonDoorGUID = go->GetGUID(); break; - case GO_DOOR_ZULJIN: ZulJinDoorGUID = go->GetGUID(); break; - - case GO_HARKORS_SATCHEL: HarkorsSatchelGUID = go->GetGUID(); break; - case GO_TANZARS_TRUNK: TanzarsTrunkGUID = go->GetGUID(); break; - case GO_ASHLIS_BAG: AshlisBagGUID = go->GetGUID(); break; - case GO_KRAZS_PACKAGE: KrazsPackageGUID = go->GetGUID(); break; - case GO_STRANGE_GONG: StrangeGongGUID = go->GetGUID(); break; - default: break; + case GO_STRANGE_GONG: + StrangeGongGUID = go->GetGUID(); + break; + case GO_MASSIVE_GATE: + MasiveGateGUID = go->GetGUID(); + AddDoor(go, true); + if (ZulAmanState != NOT_STARTED) + go->SetGoState(GO_STATE_ACTIVE); + break; + default: + break; } - CheckInstanceStatus(); } - void SummonHostage(uint8 num) + void OnGameObjectRemove(GameObject* go) { - if (!QuestMinute) - return; - - Map::PlayerList const &PlayerList = instance->GetPlayers(); - if (PlayerList.isEmpty()) - return; - - Map::PlayerList::const_iterator i = PlayerList.begin(); - if (Player* i_pl = i->GetSource()) + switch (go->GetEntry()) { - if (Unit* Hostage = i_pl->SummonCreature(HostageInfo[num].npc, HostageInfo[num].x, HostageInfo[num].y, HostageInfo[num].z, HostageInfo[num].o, TEMPSUMMON_DEAD_DESPAWN, 0)) - { - Hostage->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE); - Hostage->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - } + case GO_MASSIVE_GATE: + AddDoor(go, false); + break; + default: + break; } } - void CheckInstanceStatus() + uint64 GetData64(uint32 type) const { - if (BossKilled >= DATA_HALAZZIEVENT) - HandleGameObject(HexLordGateGUID, true); + switch (type) + { + case DATA_AKILZON: + return AkilzonGUID; + case DATA_NALORAKK: + return NalorakkGUID; + case DATA_JANALAI: + return JanalaiGUID; + case DATA_HALAZZI: + return HalazziGUID; + case DATA_HEXLORD: + return HexLordMalacrassGUID; + case DATA_DAAKARA: + return DaakaraGUID; + case DATA_HEXLORD_TRIGGER: + return HexLordTriggerGUID; + case DATA_STRANGE_GONG: + return StrangeGongGUID; + case DATA_MASSIVE_GATE: + return MasiveGateGUID; + default: + break; + } - if (BossKilled >= DATA_HEXLORDEVENT) - HandleGameObject(ZulJinGateGUID, true); + return 0; } - std::string GetSaveData() + void SetData(uint32 type, uint32 data) { - OUT_SAVE_INST_DATA; - - std::ostringstream ss; - ss << "S " << BossKilled << ' ' << ChestLooted << ' ' << QuestMinute; - - OUT_SAVE_INST_DATA_COMPLETE; - return ss.str(); + switch (type) + { + case DATA_ZULAMAN_STATE: + { + if (data == IN_PROGRESS) + { + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, 15); + events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 60000); + SpeedRunTimer = 15; + ZulAmanState = data; + SaveToDB(); + } + break; + } + default: + break; + } } - void Load(const char* load) + uint32 GetData(uint32 type) const { - if (!load) - return; - - std::istringstream ss(load); - //TC_LOG_ERROR(LOG_FILTER_TSCR, "Zul'aman loaded, %s.", ss.str().c_str()); - char dataHead; // S - uint16 data1, data2, data3; - ss >> dataHead >> data1 >> data2 >> data3; - //TC_LOG_ERROR(LOG_FILTER_TSCR, "Zul'aman loaded, %d %d %d.", data1, data2, data3); - if (dataHead == 'S') + switch (type) { - BossKilled = data1; - ChestLooted = data2; - QuestMinute = data3; - } else TC_LOG_ERROR(LOG_FILTER_TSCR, "Zul'aman: corrupted save data."); + case DATA_ZULAMAN_STATE: + return ZulAmanState; + default: + break; + } + + return 0; } - void SetData(uint32 type, uint32 data) + bool SetBossState(uint32 type, EncounterState state) { - switch (type) + if (!InstanceScript::SetBossState(type, state)) + return false; + + if (state == DONE) { - case DATA_GONGEVENT: - m_auiEncounter[DATA_GONGEVENT] = data; - if (data == IN_PROGRESS) - SaveToDB(); - else if (data == DONE) - QuestMinute = 21; - break; - case DATA_NALORAKKEVENT: - m_auiEncounter[DATA_NALORAKKEVENT] = data; - if (data == DONE) + if (ZulAmanState == IN_PROGRESS && SpeedRunTimer) { - if (QuestMinute) + ++ZulAmanBossCount; + + if (ZulAmanBossCount < 2) { - QuestMinute += 15; - DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute); + SpeedRunTimer = SpeedRunTimer + 5; + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, SpeedRunTimer); } - SummonHostage(0); - } - break; - case DATA_AKILZONEVENT: - m_auiEncounter[DATA_AKILZONEVENT] = data; - HandleGameObject(AkilzonDoorGUID, data != IN_PROGRESS); - if (data == DONE) - { - if (QuestMinute) + else if (ZulAmanBossCount == 4) { - QuestMinute += 10; - DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute); + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 0); + events.CancelEvent(EVENT_UPDATE_ZULAMAN_TIMER); + ZulAmanState = DONE; } - SummonHostage(1); } - break; - case DATA_JANALAIEVENT: - m_auiEncounter[DATA_JANALAIEVENT] = data; - if (data == DONE) - SummonHostage(2); - break; - case DATA_HALAZZIEVENT: - m_auiEncounter[DATA_HALAZZIEVENT] = data; - HandleGameObject(HalazziDoorGUID, data != IN_PROGRESS); - if (data == DONE) SummonHostage(3); - break; - case DATA_HEXLORDEVENT: - m_auiEncounter[DATA_HEXLORDEVENT] = data; - if (data == IN_PROGRESS) - HandleGameObject(HexLordGateGUID, false); - else if (data == NOT_STARTED) - CheckInstanceStatus(); - break; - case DATA_ZULJINEVENT: - m_auiEncounter[DATA_ZULJINEVENT] = data; - HandleGameObject(ZulJinDoorGUID, data != IN_PROGRESS); - break; - case DATA_CHESTLOOTED: - ++ChestLooted; - SaveToDB(); - break; - case TYPE_RAND_VENDOR_1: - RandVendor[0] = data; - break; - case TYPE_RAND_VENDOR_2: - RandVendor[1] = data; - break; } - if (data == DONE) + switch (type) { - ++BossKilled; - if (QuestMinute && BossKilled >= DATA_HALAZZIEVENT) - { - QuestMinute = 0; - DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); - } - CheckInstanceStatus(); - SaveToDB(); + case DATA_AKILZON: + break; + case DATA_NALORAKK: + break; + case DATA_JANALAI: + break; + case DATA_HALAZZI: + case DATA_HEXLORD: + case DATA_DAAKARA: + break; + default: + break; } + + return true; } - uint32 GetData(uint32 type) const + void ProcessEvent(WorldObject* /*obj*/, uint32 eventId) { - switch (type) + switch (eventId) { - case DATA_GONGEVENT: return m_auiEncounter[DATA_GONGEVENT]; - case DATA_NALORAKKEVENT: return m_auiEncounter[DATA_NALORAKKEVENT]; - case DATA_AKILZONEVENT: return m_auiEncounter[DATA_AKILZONEVENT]; - case DATA_JANALAIEVENT: return m_auiEncounter[DATA_JANALAIEVENT]; - case DATA_HALAZZIEVENT: return m_auiEncounter[DATA_HALAZZIEVENT]; - case DATA_HEXLORDEVENT: return m_auiEncounter[DATA_HEXLORDEVENT]; - case DATA_ZULJINEVENT: return m_auiEncounter[DATA_ZULJINEVENT]; - case DATA_CHESTLOOTED: return ChestLooted; - case TYPE_RAND_VENDOR_1: return RandVendor[0]; - case TYPE_RAND_VENDOR_2: return RandVendor[1]; - default: return 0; + case EVENT_START_ZULAMAN: + if (Creature* voljin = instance->GetCreature(VoljinGUID)) + { + if (voljin->IsAIEnabled) + voljin->AI()->DoAction(ACTION_START_ZULAMAN); + } + break; + default: + break; } } void Update(uint32 diff) { - if (QuestMinute) + if (events.Empty()) + return; + + events.Update(diff); + + while (uint32 eventId = events.ExecuteEvent()) { - if (QuestTimer <= diff) + switch (eventId) { - QuestMinute--; - SaveToDB(); - QuestTimer += 60000; - if (QuestMinute) - { - DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 1); - DoUpdateWorldState(WORLDSTATE_TIME_TO_SACRIFICE, QuestMinute); - } else DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); + case EVENT_UPDATE_ZULAMAN_TIMER: + SaveToDB(); + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, --SpeedRunTimer); + if (SpeedRunTimer) + events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 60000); + else + { + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 0); + events.CancelEvent(EVENT_UPDATE_ZULAMAN_TIMER); + ZulAmanState = FAIL; + } + break; + default: + break; } - QuestTimer -= diff; } } - uint64 GetData64(uint32 type) const + std::string GetSaveData() { - switch (type) + OUT_SAVE_INST_DATA; + + std::ostringstream saveStream; + saveStream << "Z A " << GetBossSaveData() << ZulAmanState + << ' ' << SpeedRunTimer << ' ' << ZulAmanBossCount; + + OUT_SAVE_INST_DATA_COMPLETE; + return saveStream.str(); + } + + void Load(char const* str) + { + if (!str) { - case GO_STRANGE_GONG: - return StrangeGongGUID; - case GO_MASSIVE_GATE: - return MassiveGateGUID; + OUT_LOAD_INST_DATA_FAIL; + return; } - return 0; + OUT_LOAD_INST_DATA(str); + + char dataHead1, dataHead2; + + std::istringstream loadStream(str); + loadStream >> dataHead1 >> dataHead2; + + if (dataHead1 == 'Z' && dataHead2 == 'A') + { + for (uint8 i = 0; i < EncounterCount; ++i) + { + uint32 tmpState; + loadStream >> tmpState; + if (tmpState == IN_PROGRESS || tmpState > SPECIAL) + tmpState = NOT_STARTED; + + SetBossState(i, EncounterState(tmpState)); + } + + loadStream >> ZulAmanState; + loadStream >> SpeedRunTimer; + loadStream >> ZulAmanBossCount; + + if (ZulAmanState == IN_PROGRESS && SpeedRunTimer && SpeedRunTimer <= 15) + { + events.ScheduleEvent(EVENT_UPDATE_ZULAMAN_TIMER, 60000); + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER_ENABLED, 1); + DoUpdateWorldState(WORLD_STATE_ZULAMAN_TIMER, SpeedRunTimer); + } + } + else + OUT_LOAD_INST_DATA_FAIL; + + OUT_LOAD_INST_DATA_COMPLETE; } + protected: + EventMap events; + uint64 AkilzonGUID; + uint64 NalorakkGUID; + uint64 JanalaiGUID; + uint64 HalazziGUID; + uint64 HexLordMalacrassGUID; + uint64 DaakaraGUID; + uint64 VoljinGUID; + uint64 HexLordTriggerGUID; + uint64 StrangeGongGUID; + uint64 MasiveGateGUID; + uint32 SpeedRunTimer; + uint32 ZulAmanState; + uint32 ZulAmanBossCount; }; InstanceScript* GetInstanceScript(InstanceMap* map) const { - return new instance_zulaman_InstanceMapScript(map); + return new instance_zulaman_InstanceScript(map); } }; @@ -375,4 +348,3 @@ void AddSC_instance_zulaman() { new instance_zulaman(); } - diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp index 0c2c9597cfe..32947f3c342 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.cpp @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * 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 @@ -16,445 +15,209 @@ * with this program. If not, see <http://www.gnu.org/licenses/>. */ -/* ScriptData -SDName: Zulaman -SD%Complete: 90 -SDComment: Forest Frog will turn into different NPC's. Workaround to prevent new entry from running this script -SDCategory: Zul'Aman -EndScriptData */ - -/* ContentData -npc_forest_frog -EndContentData */ - #include "ScriptMgr.h" #include "ScriptedCreature.h" #include "ScriptedGossip.h" -#include "zulaman.h" #include "Player.h" -#include "SpellInfo.h" -#include "SpellScript.h" - -/*###### -## npc_forest_frog -######*/ - -#define SPELL_REMOVE_AMANI_CURSE 43732 -#define SPELL_PUSH_MOJO 43923 -#define ENTRY_FOREST_FROG 24396 - -class npc_forest_frog : public CreatureScript -{ - public: - - npc_forest_frog() - : CreatureScript("npc_forest_frog") - { - } - - struct npc_forest_frogAI : public ScriptedAI - { - npc_forest_frogAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - } - - InstanceScript* instance; - - void Reset() {} - - void EnterCombat(Unit* /*who*/) {} - - void DoSpawnRandom() - { - if (instance) - { - uint32 cEntry = 0; - switch (rand()%10) - { - case 0: cEntry = 24397; break; //Mannuth - case 1: cEntry = 24403; break; //Deez - case 2: cEntry = 24404; break; //Galathryn - case 3: cEntry = 24405; break; //Adarrah - case 4: cEntry = 24406; break; //Fudgerick - case 5: cEntry = 24407; break; //Darwen - case 6: cEntry = 24445; break; //Mitzi - case 7: cEntry = 24448; break; //Christian - case 8: cEntry = 24453; break; //Brennan - case 9: cEntry = 24455; break; //Hollee - } - - if (!instance->GetData(TYPE_RAND_VENDOR_1)) - if (rand()%10 == 1) cEntry = 24408; //Gunter - if (!instance->GetData(TYPE_RAND_VENDOR_2)) - if (rand()%10 == 1) cEntry = 24409; //Kyren - - if (cEntry) me->UpdateEntry(cEntry); - - if (cEntry == 24408) instance->SetData(TYPE_RAND_VENDOR_1, DONE); - if (cEntry == 24409) instance->SetData(TYPE_RAND_VENDOR_2, DONE); - } - } - - void SpellHit(Unit* caster, const SpellInfo* spell) - { - if (spell->Id == SPELL_REMOVE_AMANI_CURSE && caster->GetTypeId() == TYPEID_PLAYER && me->GetEntry() == ENTRY_FOREST_FROG) - { - //increase or decrease chance of mojo? - if (rand()%99 == 50) DoCast(caster, SPELL_PUSH_MOJO, true); - else DoSpawnRandom(); - } - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_forest_frogAI(creature); - } -}; - -/*###### -## npc_zulaman_hostage -######*/ - -#define GOSSIP_HOSTAGE1 "I am glad to help you." - -static uint32 HostageEntry[] = {23790, 23999, 24024, 24001}; -static uint32 ChestEntry[] = {186648, 187021, 186672, 186667}; - -class npc_zulaman_hostage : public CreatureScript -{ - public: - npc_zulaman_hostage() : CreatureScript("npc_zulaman_hostage") { } - - struct npc_zulaman_hostageAI : public ScriptedAI - { - npc_zulaman_hostageAI(Creature* creature) : ScriptedAI(creature) - { - IsLoot = false; - } - - bool IsLoot; - uint64 PlayerGUID; - - void Reset() {} - - void EnterCombat(Unit* /*who*/) {} - - void JustDied(Unit* /*killer*/) - { - Player* player = Unit::GetPlayer(*me, PlayerGUID); - if (player) - player->SendLoot(me->GetGUID(), LOOT_CORPSE); - } - - void UpdateAI(uint32 /*diff*/) - { - if (IsLoot) - DoCast(me, 7, false); - } - }; - - CreatureAI* GetAI(Creature* creature) const - { - return new npc_zulaman_hostageAI(creature); - } - - bool OnGossipHello(Player* player, Creature* creature) - { - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, GOSSIP_HOSTAGE1, GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF + 1); - player->SEND_GOSSIP_MENU(player->GetGossipTextId(creature), creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player* player, Creature* creature, uint32 /*sender*/, uint32 action) - { - player->PlayerTalkClass->ClearMenus(); - - if (action == GOSSIP_ACTION_INFO_DEF + 1) - player->CLOSE_GOSSIP_MENU(); - - if (!creature->HasFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP)) - return true; - - creature->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - - InstanceScript* instance = creature->GetInstanceScript(); - if (instance) - { - //uint8 progress = instance->GetData(DATA_CHESTLOOTED); - instance->SetData(DATA_CHESTLOOTED, 0); - float x, y, z; - creature->GetPosition(x, y, z); - uint32 entry = creature->GetEntry(); - for (uint8 i = 0; i < 4; ++i) - { - if (HostageEntry[i] == entry) - { - creature->SummonGameObject(ChestEntry[i], x-2, y, z, 0, 0, 0, 0, 0, 0); - break; - } - } - } - return true; - } -}; - -/*###### -## npc_harrison_jones -######*/ +#include "CreatureTextMgr.h" +#include "zulaman.h" enum Says { - SAY_HARRISON_0 = 0, - SAY_HARRISON_1 = 1, - SAY_HARRISON_2 = 0, - SAY_HARRISON_3 = 1 + // Vol'jin + SAY_INTRO_1 = 0, + SAY_INTRO_2 = 1, + SAY_INTRO_3 = 2, + SAY_INTRO_4 = 3, + SAY_INTRO_FAIL = 4, + + // Hex Lord Malacrass + SAY_HEXLOR_INTRO = 0 }; enum Spells { - SPELL_BANGING_THE_GONG = 45225, - SPELL_STEALTH = 34189, - SPELL_COSMETIC_SPEAR_THROW = 43647 + // Vol'jin + SPELL_BANGING_THE_GONG = 45225 }; enum Events { - GONG_EVENT_1 = 1, - GONG_EVENT_2 = 2, - GONG_EVENT_3 = 3, - GONG_EVENT_4 = 4, - GONG_EVENT_5 = 5, - GONG_EVENT_6 = 6, - GONG_EVENT_7 = 7, - GONG_EVENT_8 = 8, - GONG_EVENT_9 = 9, - GONG_EVENT_10 = 10, - GONG_EVENT_11 = 11 + EVENT_INTRO_MOVEPOINT_1 = 1, + EVENT_INTRO_MOVEPOINT_2 = 2, + EVENT_INTRO_MOVEPOINT_3 = 3, + EVENT_BANGING_THE_GONG = 4, + EVENT_START_DOOR_OPENING_1 = 5, + EVENT_START_DOOR_OPENING_2 = 6, + EVENT_START_DOOR_OPENING_3 = 7, + EVENT_START_DOOR_OPENING_4 = 8, + EVENT_START_DOOR_OPENING_5 = 9, + EVENT_START_DOOR_OPENING_6 = 10, + EVENT_START_DOOR_OPENING_7 = 11 }; -enum Waypoints +enum Points { - HARRISON_MOVE_1 = 860440, - HARRISON_MOVE_2 = 860441, - HARRISON_MOVE_3 = 860442 + POINT_INTRO = 1, + POINT_STRANGE_GONG = 2, + POINT_START_DOOR_OPENING_1 = 3, + POINT_START_DOOR_OPENING_2 = 4 }; -enum DisplayIds +enum Misc { - MODEL_HARRISON_JONES_0 = 22340, - MODEL_HARRISON_JONES_1 = 22354, - MODEL_HARRISON_JONES_2 = 22347 + ITEM_VIRTUAL_ITEM = 5301 }; -enum EntryIds +Position const VoljinIntroWaypoint[4] = { - NPC_HARRISON_JONES_1 = 24375, - NPC_HARRISON_JONES_2 = 24365, - NPC_AMANISHI_GUARDIAN = 23597, + { 117.7349f, 1662.77f, 42.02156f, 0.0f }, + { 132.14f, 1645.143f, 42.02158f, 0.0f }, + { 121.8901f, 1639.118f, 42.23253f, 0.0f }, + { 122.618f, 1639.546f, 42.11659f, 0.0f }, }; -enum Weapons -{ - WEAPON_MACE = 5301, - WEAPON_SPEAR = 13631 -}; - -class npc_harrison_jones : public CreatureScript +class npc_voljin_zulaman : public CreatureScript { public: + npc_voljin_zulaman() : CreatureScript("npc_voljin_zulaman") { } - npc_harrison_jones() - : CreatureScript("npc_harrison_jones") - { - } - - struct npc_harrison_jonesAI : public ScriptedAI + struct npc_voljin_zulamanAI : public ScriptedAI { - npc_harrison_jonesAI(Creature* creature) : ScriptedAI(creature) + npc_voljin_zulamanAI(Creature* creature) : ScriptedAI(creature), _instance(creature->GetInstanceScript()) { - instance = creature->GetInstanceScript(); + me->SetDisplayId(me->GetCreatureTemplate()->Modelid1); + if (_instance->GetData(DATA_ZULAMAN_STATE) == NOT_STARTED) + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); } - InstanceScript* instance; - - uint8 _gongEvent; - uint32 _gongTimer; - uint64 uiTargetGUID; - void Reset() { - _gongEvent = 0; - _gongTimer = 0; - uiTargetGUID = 0; + _gongCount = 0; } - void EnterCombat(Unit* /*who*/) {} - void sGossipSelect(Player* player, uint32 sender, uint32 action) { - if (me->GetCreatureTemplate()->GossipMenuId == sender && !action) - { - player->CLOSE_GOSSIP_MENU(); - me->SetFacingToObject(player); + if (_instance->GetData(DATA_ZULAMAN_STATE) != NOT_STARTED) + return; + + if (me->GetCreatureTemplate()->GossipMenuId == sender && !action) + { + _events.Reset(); + me->SetUInt32Value(UNIT_FIELD_MOUNTDISPLAYID, 0); me->RemoveFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - Talk(SAY_HARRISON_0); - _gongEvent = GONG_EVENT_1; - _gongTimer = 4000; - } + me->SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE); + _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_1, 1000); + Talk(SAY_INTRO_1, player->GetGUID()); + me->SetWalk(true); + } } - void SpellHit(Unit*, const SpellInfo* spell) + void DoAction(int32 action) { - if (spell->Id == SPELL_COSMETIC_SPEAR_THROW) + if (action == ACTION_START_ZULAMAN) { - me->RemoveAllAuras(); - me->SetEntry(NPC_HARRISON_JONES_2); - me->SetDisplayId(MODEL_HARRISON_JONES_2); - me->SetTarget(0); - me->SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_DEAD); - me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_DEAD); - if (instance) - instance->SetData(DATA_GONGEVENT, DONE); + if (++_gongCount == 10) + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_1, 500); } } void UpdateAI(uint32 diff) { - if (_gongEvent) + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) { - if (_gongTimer <= diff) + switch (eventId) { - switch (_gongEvent) - { - case GONG_EVENT_1: - me->GetMotionMaster()->MovePath(HARRISON_MOVE_1, false); - _gongEvent = GONG_EVENT_2; - _gongTimer = 12000; - break; - case GONG_EVENT_2: - me->SetFacingTo(6.235659f); - Talk(SAY_HARRISON_1); - DoCast(me, SPELL_BANGING_THE_GONG); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_MACE)); - me->SetSheath(SHEATH_STATE_MELEE); - _gongEvent = GONG_EVENT_3; - _gongTimer = 4000; - break; - case GONG_EVENT_3: - if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetData64(GO_STRANGE_GONG))) - gong->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - _gongEvent = GONG_EVENT_4; - _gongTimer = 105000; - break; - case GONG_EVENT_4: - me->RemoveAura(SPELL_BANGING_THE_GONG); - if (GameObject* gong = me->GetMap()->GetGameObject(instance->GetData64(GO_STRANGE_GONG))) - gong->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); - - // trigger or gong will need to be scripted to set IN_PROGRESS after enough hits. - // This is temp workaround. - if (instance) - instance->SetData(DATA_GONGEVENT, IN_PROGRESS); // to be removed. + case EVENT_INTRO_MOVEPOINT_1: + me->GetMotionMaster()->MovePoint(POINT_INTRO, VoljinIntroWaypoint[0]); + _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_2, 1000); + break; + case EVENT_INTRO_MOVEPOINT_2: + me->GetMotionMaster()->MovePoint(POINT_STRANGE_GONG, VoljinIntroWaypoint[1]); + _events.ScheduleEvent(EVENT_INTRO_MOVEPOINT_3, 4000); + break; + case EVENT_INTRO_MOVEPOINT_3: + Talk(SAY_INTRO_2); + _events.ScheduleEvent(EVENT_BANGING_THE_GONG, 3000); + case EVENT_BANGING_THE_GONG: + DoCast(me, SPELL_BANGING_THE_GONG); + if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_STRANGE_GONG))) + strangeGong->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, uint32(ITEM_VIRTUAL_ITEM)); + break; + case EVENT_START_DOOR_OPENING_1: + me->RemoveAura(SPELL_BANGING_THE_GONG); + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_2, 500); + break; + case EVENT_START_DOOR_OPENING_2: + me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, uint32(0)); + if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_STRANGE_GONG))) + strangeGong->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_3, 500); + break; + case EVENT_START_DOOR_OPENING_3: + me->GetMotionMaster()->MovePoint(POINT_START_DOOR_OPENING_1, VoljinIntroWaypoint[2]); + break; + case EVENT_START_DOOR_OPENING_4: + _instance->SetData(DATA_ZULAMAN_STATE, IN_PROGRESS); + if (GameObject* masiveGate = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_MASSIVE_GATE))) + masiveGate->SetGoState(GO_STATE_ACTIVE); + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_5, 3000); + break; + case EVENT_START_DOOR_OPENING_5: + Talk(SAY_INTRO_4); + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_6, 6000); + break; + case EVENT_START_DOOR_OPENING_6: + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_7, 6000); + break; + case EVENT_START_DOOR_OPENING_7: + if (Creature* hexLordTrigger = ObjectAccessor::GetCreature(*me, _instance->GetData64(DATA_HEXLORD_TRIGGER))) + sCreatureTextMgr->SendChat(hexLordTrigger, SAY_HEXLOR_INTRO, 0, CHAT_MSG_ADDON, LANG_ADDON, TEXT_RANGE_MAP); + break; + default: + break; + } + } + } - if (instance->GetData(DATA_GONGEVENT) == IN_PROGRESS) - { - // Players are Now Saved to instance at SPECIAL (Player should be notified?) - me->GetMotionMaster()->MovePath(HARRISON_MOVE_2, false); - _gongEvent = GONG_EVENT_5; - _gongTimer = 5000; - } - else - { - _gongTimer = 1000; - _gongEvent = GONG_EVENT_9; - } - break; - case GONG_EVENT_5: - me->SetEntry(NPC_HARRISON_JONES_1); - me->SetDisplayId(MODEL_HARRISON_JONES_1); - Talk(SAY_HARRISON_2); - _gongTimer = 12000; - _gongEvent = GONG_EVENT_6; - break; - case GONG_EVENT_6: - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_USE_STANDING); - Talk(SAY_HARRISON_3); - _gongTimer = 7000; - _gongEvent = GONG_EVENT_7; - break; - case GONG_EVENT_7: - if (!uiTargetGUID) - { - std::list<Creature*> targetList; - GetCreatureListWithEntryInGrid(targetList, me, NPC_AMANISHI_GUARDIAN, 26.0f); - if (!targetList.empty()) - { - for (std::list<Creature*>::const_iterator itr = targetList.begin(); itr != targetList.end(); ++itr) - { - if (Creature* ptarget = *itr) - { - if (ptarget->GetPositionX() > 120) - { - ptarget->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(WEAPON_SPEAR)); - ptarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - ptarget->SetReactState(REACT_PASSIVE); - ptarget->AI()->SetData(0, 1); - } - else - ptarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_IMMUNE_TO_PC); - ptarget->SetReactState(REACT_PASSIVE); - ptarget->AI()->SetData(0, 2); - } - } - } - } + void MovementInform(uint32 movementType, uint32 pointId) + { + if (movementType != POINT_MOTION_TYPE) + return; - if (GameObject* gate = me->GetMap()->GetGameObject(instance->GetData64(GO_MASSIVE_GATE))) - gate->SetGoState(GO_STATE_ACTIVE); - _gongTimer = 2000; - _gongEvent = GONG_EVENT_8; - break; - case GONG_EVENT_8: - DoCast(me, SPELL_STEALTH); - me->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 0, uint32(0)); - me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_ONESHOT_NONE); - me->GetMotionMaster()->MovePath(HARRISON_MOVE_3, false); - _gongTimer = 1000; - _gongEvent = 0; - break; - case GONG_EVENT_9: - me->GetMotionMaster()->MovePoint(0, 120.687f, 1674.0f, 42.0217f); - _gongTimer = 12000; - _gongEvent = GONG_EVENT_10; - break; - case GONG_EVENT_10: - me->SetFacingTo(1.59044f); - _gongEvent = 11; - _gongTimer = 6000; - break; - case GONG_EVENT_11: - me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); - if (instance) - instance->SetData(DATA_GONGEVENT, NOT_STARTED); - _gongEvent = 0; - _gongTimer = 1000; - break; - } - } - else - _gongTimer -= diff; + switch (pointId) + { + case POINT_STRANGE_GONG: + if (GameObject* strangeGong = ObjectAccessor::GetGameObject(*me, _instance->GetData64(DATA_STRANGE_GONG))) + me->SetFacingToObject(strangeGong); // setInFront + break; + case POINT_START_DOOR_OPENING_1: + me->SetFacingTo(4.747295f); + me->GetMotionMaster()->MovePoint(POINT_START_DOOR_OPENING_2, VoljinIntroWaypoint[3]); + Talk(SAY_INTRO_3); + _events.ScheduleEvent(EVENT_START_DOOR_OPENING_4, 4500); + break; + default: + break; } } + + private: + InstanceScript* _instance; + EventMap _events; + uint8 _gongCount; }; CreatureAI* GetAI(Creature* creature) const { - return new npc_harrison_jonesAI(creature); + return GetZulAmanAI<npc_voljin_zulamanAI>(creature); } }; +// 45226 - Banging the Gong class spell_banging_the_gong : public SpellScriptLoader { public: @@ -482,11 +245,8 @@ class spell_banging_the_gong : public SpellScriptLoader } }; - void AddSC_zulaman() { - new npc_forest_frog(); - new npc_zulaman_hostage(); - new npc_harrison_jones(); + new npc_voljin_zulaman(); new spell_banging_the_gong(); } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h index c3386f8c996..8f955876986 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h @@ -1,6 +1,5 @@ /* * Copyright (C) 2008-2013 TrinityCore <http://www.trinitycore.org/> - * 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 @@ -19,43 +18,73 @@ #ifndef DEF_ZULAMAN_H #define DEF_ZULAMAN_H +uint32 const EncounterCount = 6; +#define ZulAmanScriptName "instance_zulaman" + enum DataTypes { - DATA_GONGEVENT = 0, - DATA_NALORAKKEVENT = 1, - DATA_AKILZONEVENT = 2, - DATA_JANALAIEVENT = 3, - DATA_HALAZZIEVENT = 4, - DATA_HEXLORDEVENT = 5, - DATA_ZULJINEVENT = 6, - DATA_CHESTLOOTED = 7, - TYPE_RAND_VENDOR_1 = 8, - TYPE_RAND_VENDOR_2 = 9 + // BossState + DATA_AKILZON = 0, + DATA_NALORAKK = 1, + DATA_JANALAI = 2, + DATA_HALAZZI = 3, + DATA_HEXLORD = 4, + DATA_DAAKARA = 5, + + // Data64 + DATA_HEXLORD_TRIGGER, + + DATA_STRANGE_GONG, + DATA_MASSIVE_GATE, + + // SetData + DATA_ZULAMAN_STATE }; enum CreatureIds { - NPC_HARRISON_JONES = 24358, - NPC_JANALAI = 23578, - NPC_ZULJIN = 23863, - NPC_HEXLORD = 24239, - NPC_HALAZZI = 23577, - NPC_NALORAKK = 23576 + NPC_AKILZON = 23574, + NPC_NALORAKK = 23576, + NPC_JANALAI = 23578, + NPC_HALAZZI = 23577, + NPC_HEXLORD = 24239, + NPC_DAAKARA = 23863, + + NPC_VOLJIN = 52924, + NPC_HEXLORD_TRIGGER = 24363 +}; + +enum GameObjectIds +{ + GO_STRANGE_GONG = 187359, + GO_MASSIVE_GATE = 186728, }; -enum GameobjectIds +enum ZulAmanEvents { - GO_DOOR_HALAZZI = 186303, - GO_GATE_ZULJIN = 186304, - GO_GATE_HEXLORD = 186305, - GO_MASSIVE_GATE = 186728, - GO_DOOR_AKILZON = 186858, - GO_DOOR_ZULJIN = 186859, - GO_HARKORS_SATCHEL = 187021, - GO_TANZARS_TRUNK = 186648, - GO_ASHLIS_BAG = 186672, - GO_KRAZS_PACKAGE = 186667, - GO_STRANGE_GONG = 187359 + EVENT_START_ZULAMAN = 15897, + EVENT_UPDATE_ZULAMAN_TIMER = 1, }; +enum ZulAmanAction +{ + ACTION_START_ZULAMAN = 1 +}; + +enum ZulAmanWorldStates +{ + WORLD_STATE_ZULAMAN_TIMER_ENABLED = 3104, + WORLD_STATE_ZULAMAN_TIMER = 3106, +}; + +template<class AI> +CreatureAI* GetZulAmanAI(Creature* creature) +{ + if (InstanceMap* instance = creature->GetMap()->ToInstanceMap()) + if (instance->GetInstanceScript()) + if (instance->GetScriptId() == sObjectMgr->GetScriptId(ZulAmanScriptName)) + return new AI(creature); + return NULL; +} + #endif |