From ce70cf1c13eb03f2476431b8d84f12f6eeb156a2 Mon Sep 17 00:00:00 2001 From: Dan <83884799+elthehablo@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:45:53 +0100 Subject: [PATCH] refactor(Scripts/ZulAman): refactor set data to instance boss states and refactor Hex Lord Malacrass (#20206) * load boss data and initialize hexlord * boundaries and stuff * Update boss_janalai.cpp * Update instance_zulaman.cpp * F * Update boss_hexlord.cpp * remove old creature spells * restore alyson script * remove instance data sets * revert --- .../EasternKingdoms/ZulAman/boss_akilzon.cpp | 10 +- .../EasternKingdoms/ZulAman/boss_halazzi.cpp | 2 +- .../EasternKingdoms/ZulAman/boss_hexlord.cpp | 727 +++++++----------- .../EasternKingdoms/ZulAman/boss_janalai.cpp | 5 +- .../EasternKingdoms/ZulAman/boss_nalorakk.cpp | 3 +- .../EasternKingdoms/ZulAman/boss_zuljin.cpp | 6 +- .../ZulAman/instance_zulaman.cpp | 62 +- .../scripts/EasternKingdoms/ZulAman/zulaman.h | 21 +- 8 files changed, 321 insertions(+), 515 deletions(-) diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp index dbe0f1263..ee9b78f81 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp @@ -85,7 +85,7 @@ public: struct boss_akilzonAI : public BossAI { - boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZONEVENT) + boss_akilzonAI(Creature* creature) : BossAI(creature, DATA_AKILZON) { } @@ -103,9 +103,6 @@ public: StormCount = 0; isRaining = false; - if (instance) - instance->SetData(DATA_AKILZONEVENT, NOT_STARTED); - SetWeather(WEATHER_STATE_FINE, 0.0f); } @@ -120,17 +117,12 @@ public: Talk(SAY_AGGRO); //DoZoneInCombat(); - - if (instance) - instance->SetData(DATA_AKILZONEVENT, IN_PROGRESS); } void JustDied(Unit* /*killer*/) override { Talk(SAY_DEATH); _JustDied(); - if (instance) - instance->SetData(DATA_AKILZONEVENT, DONE); } void KilledUnit(Unit* who) override diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp index 53d2c3d2d..46efc1da6 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_halazzi.cpp @@ -76,7 +76,7 @@ enum Groups struct boss_halazzi : public BossAI { - boss_halazzi(Creature* creature) : BossAI(creature, DATA_HALAZZIEVENT) + boss_halazzi(Creature* creature) : BossAI(creature, DATA_HALAZZI) { scheduler.SetValidator([this] { diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp index ecd3fd21d..ca2ad77b0 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_hexlord.cpp @@ -19,6 +19,7 @@ #include "ScriptedCreature.h" #include "SpellAuraEffects.h" #include "SpellScript.h" +#include "Player.h" #include "SpellScriptLoader.h" #include "zulaman.h" /* ScriptData @@ -40,7 +41,16 @@ enum Says enum Creatures { - NPC_TEMP_TRIGGER = 23920 + NPC_TEMP_TRIGGER = 23920, + NPC_ALYSON_ANTILLE = 24240, + NPC_THURG = 24241, + NPC_GAZAKROTH = 24244, + NPC_LORD_RADAAN = 24243, + NPC_DARKHEART = 24246, + NPC_SLITHER = 24242, + NPC_FENSTALKER = 24245, + NPC_KORAGG = 24247 + }; enum Spells @@ -49,6 +59,11 @@ enum Spells SPELL_DRAIN_POWER = 44131, SPELL_SIPHON_SOUL = 43501, + // Alyson Antille + SPELL_ARCANE_TORRENT = 33390, + SPELL_DISPEL_MAGIC = 43577, + SPELL_FLASH_HEAL = 43575, + // Druid SPELL_DR_THORNS = 43420, SPELL_DR_LIFEBLOOM = 43421, @@ -99,51 +114,33 @@ enum Spells SPELL_WR_WHIRLWIND = 43442, SPELL_WR_SPELL_REFLECT = 43443, - // Thurg - SPELL_BLOODLUST = 43578, - SPELL_CLEAVE = 15496, - - // Gazakroth - SPELL_FIREBOLT = 43584, - - // Alyson Antille - SPELL_FLASH_HEAL = 43575, - SPELL_DISPEL_MAGIC = 43577, - - // Lord Raadan - SPELL_FLAME_BREATH = 43582, - SPELL_THUNDERCLAP = 43583, - - // Darkheart - SPELL_PSYCHIC_WAIL = 43590, - - // Slither - SPELL_VENOM_SPIT = 43579, - - // Fenstalker - SPELL_VOLATILE_INFECTION = 43586, - - // Koragg - SPELL_COLD_STARE = 43593, - SPELL_MIGHTY_BLOW = 43592 + // Death Knight + SPELL_DK_PLAGUE_STRIKE = 57599, + SPELL_DK_DEATH_AND_DECAY = 43265, + SPELL_DK_BLOOD_WORMS = 97630, }; -#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] = +const Position addPosition[4] = { - 24240, //Alyson Antille - 24241, //Thurg - 24242, //Slither - 24243, //Lord Raadan - 24244, //Gazakroth - 24245, //Fenstalker - 24246, //Darkheart - 24247 //Koragg + {112.8827f, 921.2795f, 33.8883f, 1.5696f}, + {107.8827f, 921.2795f, 33.8883f, 1.5696f}, + {122.8827f, 921.2795f, 33.8883f, 1.5696f}, + {127.8827f, 921.2795f, 33.8883f, 1.5696f} +}; + +static uint32 addEntrySets[4][2] = +{ + {NPC_THURG, NPC_ALYSON_ANTILLE }, + {NPC_LORD_RADAAN, NPC_SLITHER }, + {NPC_GAZAKROTH, NPC_FENSTALKER }, + {NPC_DARKHEART, NPC_KORAGG } +}; + +enum Misc +{ + MAX_ADD_COUNT = 4, + ADDITIONAL_CLASS_SPRIEST = 11, + AURA_SHADOW_FORM = 15473 }; enum AbilityTarget @@ -160,455 +157,273 @@ struct PlayerAbilityStruct { uint32 spell; AbilityTarget target; - uint32 cooldown; //FIXME - it's never used + std::chrono::milliseconds cooldown; }; -static PlayerAbilityStruct PlayerAbility[][3] = +static PlayerAbilityStruct PlayerAbility[12][3] = { // 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} + { {SPELL_WR_SPELL_REFLECT, ABILITY_TARGET_SELF, 10000ms}, + {SPELL_WR_WHIRLWIND, ABILITY_TARGET_SELF, 10000ms}, + {SPELL_WR_MORTAL_STRIKE, ABILITY_TARGET_VICTIM, 6000ms} }, // 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} + { {SPELL_PA_CONSECRATION, ABILITY_TARGET_SELF, 10000ms}, + {SPELL_PA_HOLY_LIGHT, ABILITY_TARGET_HEAL, 10000ms}, + {SPELL_PA_AVENGING_WRATH, ABILITY_TARGET_SELF, 10000ms} }, // 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} + { {SPELL_HU_EXPLOSIVE_TRAP, ABILITY_TARGET_SELF, 10000ms}, + {SPELL_HU_FREEZING_TRAP, ABILITY_TARGET_SELF, 10000ms}, + {SPELL_HU_SNAKE_TRAP, ABILITY_TARGET_SELF, 10000ms} }, // 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} + { {SPELL_RO_WOUND_POISON, ABILITY_TARGET_VICTIM, 3000ms}, + {SPELL_RO_SLICE_DICE, ABILITY_TARGET_SELF, 10000ms}, + {SPELL_RO_BLIND, ABILITY_TARGET_ENEMY, 10000ms} }, // 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} + { {SPELL_PR_PAIN_SUPP, ABILITY_TARGET_HEAL, 10000ms}, + {SPELL_PR_HEAL, ABILITY_TARGET_HEAL, 10000ms}, + {SPELL_PR_PSYCHIC_SCREAM, ABILITY_TARGET_SELF, 10000ms} }, - // 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} + // 6 death knight + { + {SPELL_DK_PLAGUE_STRIKE, ABILITY_TARGET_ENEMY, 2000ms}, + {SPELL_DK_DEATH_AND_DECAY, ABILITY_TARGET_SELF, 10000ms}, + {SPELL_DK_BLOOD_WORMS, ABILITY_TARGET_ENEMY, 5000ms} }, // 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} + { {SPELL_SH_FIRE_NOVA, ABILITY_TARGET_SELF, 10000ms}, + {SPELL_SH_HEALING_WAVE, ABILITY_TARGET_HEAL, 10000ms}, + {SPELL_SH_CHAIN_LIGHT, ABILITY_TARGET_ENEMY, 8000ms} }, // 8 mage - { {SPELL_MG_FIREBALL, ABILITY_TARGET_ENEMY, 5000}, - {SPELL_MG_FROSTBOLT, ABILITY_TARGET_ENEMY, 5000}, - {SPELL_MG_ICE_LANCE, ABILITY_TARGET_SPECIAL, 2000} + { {SPELL_MG_FIREBALL, ABILITY_TARGET_ENEMY, 5000ms}, + {SPELL_MG_FROSTBOLT, ABILITY_TARGET_ENEMY, 5000ms}, + {SPELL_MG_ICE_LANCE, ABILITY_TARGET_SPECIAL, 2000ms} }, // 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} + { {SPELL_WL_CURSE_OF_DOOM, ABILITY_TARGET_ENEMY, 10000ms}, + {SPELL_WL_RAIN_OF_FIRE, ABILITY_TARGET_ENEMY, 10000ms}, + {SPELL_WL_UNSTABLE_AFFL, ABILITY_TARGET_ENEMY, 10000ms} + }, + // 10 UNK class (should never be set) + { + {0, ABILITY_TARGET_SELF, 0ms}, + {0, ABILITY_TARGET_SELF, 0ms}, + {0, ABILITY_TARGET_SELF, 0ms} }, // 11 druid - { {SPELL_DR_LIFEBLOOM, ABILITY_TARGET_HEAL, 10000}, - {SPELL_DR_THORNS, ABILITY_TARGET_SELF, 10000}, - {SPELL_DR_MOONFIRE, ABILITY_TARGET_ENEMY, 8000} + { {SPELL_DR_LIFEBLOOM, ABILITY_TARGET_HEAL, 10000ms}, + {SPELL_DR_THORNS, ABILITY_TARGET_SELF, 10000ms}, + {SPELL_DR_MOONFIRE, ABILITY_TARGET_ENEMY, 8000ms} + }, + // MISC shadow priest + { {SPELL_PR_MIND_CONTROL, ABILITY_TARGET_ENEMY, 15000ms}, + {SPELL_PR_MIND_BLAST, ABILITY_TARGET_ENEMY, 5000ms}, + {SPELL_PR_SW_DEATH, ABILITY_TARGET_ENEMY, 10000ms} } }; -struct boss_hexlord_addAI : public ScriptedAI +struct boss_hexlord_malacrass : public BossAI { - InstanceScript* instance; + boss_hexlord_malacrass(Creature* creature) : BossAI(creature, DATA_HEXLORD) { } - boss_hexlord_addAI(Creature* creature) : ScriptedAI(creature) + void Reset() override { - instance = creature->GetInstanceScript(); + BossAI::Reset(); + _currentClass = CLASS_NONE; + _classAbilityTimer = 10000ms; + SpawnAdds(); } - void Reset() override { } - - void JustEngagedWith(Unit* /*who*/) override + void SpawnAdds() { - DoZoneInCombat(); - } - - void UpdateAI(uint32 /*diff*/) override - { - if (instance->GetData(DATA_HEXLORDEVENT) != IN_PROGRESS) + for (uint8 i = 0; i < MAX_ADD_COUNT; ++i) { - EnterEvadeMode(); - return; + uint8 flip = urand(0, 1); + me->SummonCreature(addEntrySets[i][flip], addPosition[i], TEMPSUMMON_DEAD_DESPAWN, 0); } + } + + void JustEngagedWith(Unit* who) override + { + BossAI::JustEngagedWith(who); + Talk(SAY_AGGRO); + summons.DoForAllSummons([&](WorldObject* summon) + { + if (Creature* add = summon->ToCreature()) + add->SetInCombatWithZone(); + }); + + ScheduleTimedEvent(60s, [&]{ + DoCastSelf(SPELL_DRAIN_POWER, true); + Talk(SAY_DRAIN_POWER); + }, 40s, 55s); + ScheduleTimedEvent(30s, [&]{ + DoCastSelf(SPELL_SPIRIT_BOLTS); + scheduler.Schedule(10s, [this](TaskContext) + { + if (Creature* siphonTrigger = me->SummonCreature(NPC_TEMP_TRIGGER, me->GetPosition(), TEMPSUMMON_TIMED_DESPAWN, 30000)) + { + if (Unit* target = SelectTarget(SelectTargetMethod::Random, 0, 70, true)) + { + siphonTrigger->SetDisplayId(11686); + siphonTrigger->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); + siphonTrigger->AI()->DoCast(target, SPELL_SIPHON_SOUL, true); + siphonTrigger->GetMotionMaster()->MoveChase(me); + if (Player* player = target->ToPlayer()) + { + if (player->HasAura(AURA_SHADOW_FORM)) + _currentClass = ADDITIONAL_CLASS_SPRIEST; + else + _currentClass = player->getClass() - 1; + } + } + } + }); + }, 40s); + ScheduleTimedEvent(_classAbilityTimer, [&]{ + if (_currentClass) + { + UseAbility(); + } + }, _classAbilityTimer); + } + + void UseAbility() + { + uint8 random = urand(0, 2); + Unit* target = nullptr; + switch (PlayerAbility[_currentClass][random].target) + { + case ABILITY_TARGET_SELF: + target = me; + break; + case ABILITY_TARGET_VICTIM: + target = me->GetVictim(); + break; + case ABILITY_TARGET_ENEMY: + default: + target = SelectTarget(SelectTargetMethod::Random, 0, 100, true); + break; + case ABILITY_TARGET_HEAL: + target = DoSelectLowestHpFriendly(50, 0); + break; + case ABILITY_TARGET_BUFF: + { + std::list templist = DoFindFriendlyMissingBuff(50, PlayerAbility[_currentClass][random].spell); + if (!templist.empty()) + target = *(templist.begin()); + } + break; + } + if (target) + DoCast(target, PlayerAbility[_currentClass][random].spell, false); + _classAbilityTimer = PlayerAbility[_currentClass][random].cooldown; + } + + void KilledUnit(Unit* victim) override + { + BossAI::KilledUnit(victim); + if (urand(0, 1)) + Talk(SAY_KILL_ONE); + else + Talk(SAY_KILL_TWO); + } +private: + uint8 _currentClass; + std::chrono::milliseconds _classAbilityTimer; +}; + +struct boss_alyson_antille : public ScriptedAI +{ + boss_alyson_antille(Creature* creature) : ScriptedAI(creature) { } + + void Reset() override + { + scheduler.CancelAll(); + _friendlyList.clear(); + ScriptedAI::Reset(); + } + + void JustEngagedWith(Unit* who) override + { + ScriptedAI::JustEngagedWith(who); + //populate list of friendly adds and malacrass + GetNearbyFriendlies(); + ScheduleTimedEvent(10s, [&]{ + bool friendlyCast = false; + RandomReverseFriendlyList(); + for (Creature* friendly : _friendlyList) + { + if (friendly->IsAlive() && friendly->IsWithinDist2d(me, 40.0f)) + { + DoCast(friendly, SPELL_DISPEL_MAGIC); + friendlyCast = true; + break; + } + } + if (!friendlyCast) + { + if (Map* map = me->GetMap()) + { + map->DoForAllPlayers([&](Player* player) + { + if (player->IsWithinDist2d(me, 40.0f)) + { + DoCast(player, SPELL_DISPEL_MAGIC); + return; + } + }); + } + } + }, 10s); + ScheduleTimedEvent(2500ms, [&]{ + RandomReverseFriendlyList(); + for (Creature* friendly : _friendlyList) + { + if (friendly->IsAlive() && friendly->IsWithinDist2d(me, 40.0f) && !friendly->IsFullHealth()) + { + DoCast(friendly, SPELL_FLASH_HEAL); + break; + } + } + }, 2500ms); + ScheduleTimedEvent(30s, [&]{ + DoCastSelf(SPELL_ARCANE_TORRENT); // timer not checked + }, 30s); + } + + void RandomReverseFriendlyList() + { + if (urand(0, 1)) + _friendlyList.reverse(); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + scheduler.Update(diff); DoMeleeAttackIfReady(); } -}; -class boss_hexlord_malacrass : public CreatureScript -{ -public: - boss_hexlord_malacrass() - : CreatureScript("boss_hexlord_malacrass") + void GetNearbyFriendlies() { + me->GetCreaturesWithEntryInRange(_friendlyList, 100.0f, NPC_HEXLORD); + me->GetCreaturesWithEntryInRange(_friendlyList, 100.0f, NPC_GAZAKROTH); + me->GetCreaturesWithEntryInRange(_friendlyList, 100.0f, NPC_LORD_RADAAN); + me->GetCreaturesWithEntryInRange(_friendlyList, 100.0f, NPC_DARKHEART); + me->GetCreaturesWithEntryInRange(_friendlyList, 100.0f, NPC_SLITHER); + me->GetCreaturesWithEntryInRange(_friendlyList, 100.0f, NPC_FENSTALKER); + me->GetCreaturesWithEntryInRange(_friendlyList, 100.0f, NPC_KORAGG); } - - struct boss_hex_lord_malacrassAI : public ScriptedAI - { - boss_hex_lord_malacrassAI(Creature* creature) : ScriptedAI(creature) - { - instance = creature->GetInstanceScript(); - SelectAddEntry(); - } - - InstanceScript* instance; - - ObjectGuid AddGUID[4]; - uint32 AddEntry[4]; - - ObjectGuid PlayerGUID; - - uint32 SpiritBolts_Timer; - uint32 DrainPower_Timer; - uint32 SiphonSoul_Timer; - uint32 PlayerAbility_Timer; - uint32 CheckAddState_Timer; - uint32 ResetTimer; - - uint32 PlayerClass; - - void Reset() override - { - instance->SetData(DATA_HEXLORDEVENT, NOT_STARTED); - - SpiritBolts_Timer = 20000; - DrainPower_Timer = 60000; - SiphonSoul_Timer = 100000; - PlayerAbility_Timer = 99999; - CheckAddState_Timer = 5000; - ResetTimer = 5000; - - SpawnAdds(); - } - - void JustEngagedWith(Unit* /*who*/) override - { - instance->SetData(DATA_HEXLORDEVENT, IN_PROGRESS); - - DoZoneInCombat(); - Talk(SAY_AGGRO); - - for (uint8 i = 0; i < 4; ++i) - { - Creature* creature = ObjectAccessor::GetCreature(*me, AddGUID[i]); - if (creature && creature->IsAlive()) - creature->AI()->AttackStart(me->GetVictim()); - else - { - EnterEvadeMode(); - break; - } - } - } - - void KilledUnit(Unit* /*victim*/) override - { - switch (urand(0, 1)) - { - case 0: - Talk(SAY_KILL_ONE); - break; - case 1: - Talk(SAY_KILL_TWO); - break; - } - } - - void JustDied(Unit* /*killer*/) override - { - instance->SetData(DATA_HEXLORDEVENT, DONE); - - Talk(SAY_DEATH); - - for (uint8 i = 0; i < 4; ++i) - { - Unit* Temp = ObjectAccessor::GetUnit(*me, AddGUID[i]); - if (Temp && Temp->IsAlive()) - Unit::DealDamage(Temp, Temp, Temp->GetHealth(), nullptr, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, nullptr, false); - } - } - - void SelectAddEntry() - { - std::vector 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::const_iterator itr = AddList.begin(); itr != AddList.end(); ++itr, ++i) - AddEntry[i] = *itr; - } - - void SpawnAdds() - { - for (uint8 i = 0; i < 4; ++i) - { - Creature* creature = (ObjectAccessor::GetCreature((*me), AddGUID[i])); - if (!creature || !creature->IsAlive()) - { - if (creature) creature->setDeathState(DeathState::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->StopMovingOnCurrentPos(); - } - } - } - - void UpdateAI(uint32 diff) override - { - 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 = ObjectAccessor::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); - Talk(SAY_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); - Talk(SAY_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(SelectTargetMethod::Random, 0, 70, true); - Unit* trigger = DoSpawnCreature(NPC_TEMP_TRIGGER, 0, 0, 0, 0, TEMPSUMMON_TIMED_DESPAWN, 30000); - if (!target || !trigger) - { - EnterEvadeMode(); - return; - } - else - { - trigger->SetDisplayId(11686); - trigger->SetUnitFlag(UNIT_FLAG_NOT_SELECTABLE); - trigger->CastSpell(target, SPELL_SIPHON_SOUL, true); - trigger->GetMotionMaster()->MoveChase(me); - - //DoCast(target, SPELL_SIPHON_SOUL, true); - //me->SetGuidValue(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 (target->IsClass(CLASS_DRUID)) - PlayerClass = CLASS_DRUID; - else if (target->IsClass(CLASS_PRIEST) && 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 = ObjectAccessor::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 = nullptr; - 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(SelectTargetMethod::Random, 0, 100, true); - break; - case ABILITY_TARGET_HEAL: - target = DoSelectLowestHpFriendly(50, 0); - break; - case ABILITY_TARGET_BUFF: - { - std::list 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 override - { - return GetZulAmanAI(creature); - } -}; - -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() override - { - flashheal_timer = 2500; - dispelmagic_timer = 10000; - - //AcquireGUID(); - - boss_hexlord_addAI::Reset(); - } - - void AttackStart(Unit* who) override - { - 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) override - { - 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 - { - /** - * @bug - * Bugged - * //me->GetMotionMaster()->Clear(); - * //me->GetMotionMaster()->MoveChase(target, 20); - */ - //me->GetMotionMaster()->Clear(); - //me->GetMotionMaster()->MoveChase(target, 20); - } - } - else - { - if (urand(0, 1)) - target = DoSelectLowestHpFriendly(50, 0); - else - target = SelectTarget(SelectTargetMethod::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(SelectTargetMethod::Random, 0), SPELL_DISPEL_MAGIC, false); - - dispelmagic_timer = 12000; - } else dispelmagic_timer -= diff;*/ - - boss_hexlord_addAI::UpdateAI(diff); - } - }; - - CreatureAI* GetAI(Creature* creature) const override - { - return GetZulAmanAI(creature); - } +private: + std::list _friendlyList; }; class spell_hexlord_unstable_affliction : public AuraScript @@ -634,7 +449,7 @@ class spell_hexlord_unstable_affliction : public AuraScript void AddSC_boss_hex_lord_malacrass() { - new boss_hexlord_malacrass(); - new boss_alyson_antille(); + RegisterZulAmanCreatureAI(boss_hexlord_malacrass); + RegisterZulAmanCreatureAI(boss_alyson_antille); RegisterSpellScript(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 f0667f6a9..bb7fae9a4 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_janalai.cpp @@ -125,12 +125,11 @@ enum Misc struct boss_janalai : public BossAI { - boss_janalai(Creature* creature) : BossAI(creature, DATA_JANALAIEVENT) { } + boss_janalai(Creature* creature) : BossAI(creature, DATA_JANALAI) { } void Reset() override { BossAI::Reset(); - instance->SetData(DATA_JANALAIEVENT, NOT_STARTED); HatchAllEggs(HATCH_RESET); _isBombing = false; _isFlameBreathing = false; @@ -153,7 +152,6 @@ struct boss_janalai : public BossAI void JustDied(Unit* killer) override { Talk(SAY_DEATH); - instance->SetData(DATA_JANALAIEVENT, DONE); BossAI::JustDied(killer); } @@ -169,7 +167,6 @@ struct boss_janalai : public BossAI void JustEngagedWith(Unit* who) override { BossAI::JustEngagedWith(who); - instance->SetData(DATA_JANALAIEVENT, IN_PROGRESS); Talk(SAY_AGGRO); //schedule abilities ScheduleTimedEvent(30s, [&]{ diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp index 6438e03f1..7bd34745d 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_nalorakk.cpp @@ -87,7 +87,7 @@ enum NalorakkGroups struct boss_nalorakk : public BossAI { - boss_nalorakk(Creature* creature) : BossAI(creature, DATA_NALORAKKEVENT) + boss_nalorakk(Creature* creature) : BossAI(creature, DATA_NALORAKK) { _phase = PHASE_SEND_GUARDS_1; _ranIntro = false; @@ -351,7 +351,6 @@ struct boss_nalorakk : public BossAI { BossAI::JustDied(killer); Talk(SAY_DEATH); - instance->SetData(DATA_NALORAKKEVENT, DONE); } private: diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp index f03e61f26..a13bc3448 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_zuljin.cpp @@ -167,8 +167,6 @@ public: void Reset() override { - instance->SetData(DATA_ZULJINEVENT, NOT_STARTED); - Phase = 0; health_20 = me->CountPctFromMaxHealth(20); @@ -203,8 +201,6 @@ public: void JustEngagedWith(Unit* /*who*/) override { - instance->SetData(DATA_ZULJINEVENT, IN_PROGRESS); - DoZoneInCombat(); Talk(YELL_INTRO); @@ -222,7 +218,7 @@ public: void JustDied(Unit* /*killer*/) override { - instance->SetData(DATA_ZULJINEVENT, DONE); + instance->SetData(DATA_ZULJIN, DONE); Talk(YELL_DEATH); Summons.DespawnEntry(CREATURE_COLUMN_OF_FIRE); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp index ffb1b771b..f8847e74a 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp @@ -30,7 +30,6 @@ EndScriptData */ enum Misc { - MAX_ENCOUNTER = 7, RAND_VENDOR = 2, WORLDSTATE_SHOW_TIMER = 3104, WORLDSTATE_TIME_TO_SACRIFICE = 3106 @@ -66,6 +65,11 @@ ObjectData const gameObjectData[] = { 0, 0 } }; +BossBoundaryData const boundaries = +{ + { DATA_HEXLORD, new RectangleBoundary(80.50557f, 920.9858f, 155.88986f, 1015.27563f)} +}; + class instance_zulaman : public InstanceMapScript { public: @@ -105,6 +109,8 @@ public: SetHeaders(DataHeader); LoadObjectData(creatureData, gameObjectData); memset(&m_auiEncounter, 0, sizeof(m_auiEncounter)); + SetBossNumber(MAX_ENCOUNTER); + LoadBossBoundaries(boundaries); QuestTimer = 0; QuestMinute = 0; @@ -216,10 +222,10 @@ public: void CheckInstanceStatus() { - if (BossKilled >= DATA_HALAZZIEVENT) + if (BossKilled >= DATA_HALAZZI) HandleGameObject(HexLordGateGUID, true); - if (BossKilled >= DATA_HEXLORDEVENT) + if (BossKilled >= DATA_HEXLORD) HandleGameObject(ZulJinGateGUID, true); } @@ -267,8 +273,8 @@ public: else if (data == DONE) QuestMinute = 21; break; - case DATA_NALORAKKEVENT: - m_auiEncounter[DATA_NALORAKKEVENT] = data; + case DATA_NALORAKK: + m_auiEncounter[DATA_NALORAKK] = data; if (data == DONE) { if (QuestMinute) @@ -280,8 +286,8 @@ public: SaveToDB(); } break; - case DATA_AKILZONEVENT: - m_auiEncounter[DATA_AKILZONEVENT] = data; + case DATA_AKILZON: + m_auiEncounter[DATA_AKILZON] = data; HandleGameObject(AkilzonDoorGUID, data != IN_PROGRESS); if (data == DONE) { @@ -294,28 +300,28 @@ public: SaveToDB(); } break; - case DATA_JANALAIEVENT: - m_auiEncounter[DATA_JANALAIEVENT] = data; + case DATA_JANALAI: + m_auiEncounter[DATA_JANALAI] = data; if (data == DONE) SummonHostage(2); SaveToDB(); break; - case DATA_HALAZZIEVENT: - m_auiEncounter[DATA_HALAZZIEVENT] = data; + case DATA_HALAZZI: + m_auiEncounter[DATA_HALAZZI] = data; HandleGameObject(HalazziDoorGUID, data != IN_PROGRESS); if (data == DONE) SummonHostage(3); SaveToDB(); break; - case DATA_HEXLORDEVENT: - m_auiEncounter[DATA_HEXLORDEVENT] = data; + case DATA_HEXLORD: + m_auiEncounter[DATA_HEXLORD] = data; if (data == IN_PROGRESS) HandleGameObject(HexLordGateGUID, false); else if (data == NOT_STARTED) CheckInstanceStatus(); SaveToDB(); break; - case DATA_ZULJINEVENT: - m_auiEncounter[DATA_ZULJINEVENT] = data; + case DATA_ZULJIN: + m_auiEncounter[DATA_ZULJIN] = data; HandleGameObject(ZulJinDoorGUID, data != IN_PROGRESS); SaveToDB(); break; @@ -334,7 +340,7 @@ public: if (data == DONE) { ++BossKilled; - if (QuestMinute && BossKilled >= DATA_HALAZZIEVENT) + if (QuestMinute && BossKilled >= DATA_HALAZZI) { QuestMinute = 0; DoUpdateWorldState(WORLDSTATE_SHOW_TIMER, 0); @@ -350,18 +356,18 @@ public: { 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_NALORAKK: + return m_auiEncounter[DATA_NALORAKK]; + case DATA_AKILZON: + return m_auiEncounter[DATA_AKILZON]; + case DATA_JANALAI: + return m_auiEncounter[DATA_JANALAI]; + case DATA_HALAZZI: + return m_auiEncounter[DATA_HALAZZI]; + case DATA_HEXLORD: + return m_auiEncounter[DATA_HEXLORD]; + case DATA_ZULJIN: + return m_auiEncounter[DATA_ZULJIN]; case DATA_CHESTLOOTED: return ChestLooted; case TYPE_RAND_VENDOR_1: diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h index caf94bfc2..a6f0d9ee9 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h @@ -26,16 +26,17 @@ enum DataTypes { DATA_GONGEVENT = 0, - DATA_NALORAKKEVENT = 1, - DATA_AKILZONEVENT = 2, - DATA_JANALAIEVENT = 3, - DATA_HALAZZIEVENT = 4, - DATA_HEXLORDEVENT = 5, - DATA_ZULJINEVENT = 6, - DATA_SPIRIT_LYNX = 7, - DATA_CHESTLOOTED = 8, - TYPE_RAND_VENDOR_1 = 9, - TYPE_RAND_VENDOR_2 = 10 + DATA_NALORAKK = 1, + DATA_AKILZON = 2, + DATA_JANALAI = 3, + DATA_HALAZZI = 4, + DATA_HEXLORD = 5, + DATA_ZULJIN = 6, + MAX_ENCOUNTER = 7, + DATA_SPIRIT_LYNX = 8, + DATA_CHESTLOOTED = 9, + TYPE_RAND_VENDOR_1 = 10, + TYPE_RAND_VENDOR_2 = 11 }; enum CreatureIds