diff --git a/sql/updates/world/custom/custom_2020_02_09_00_world.sql b/sql/updates/world/custom/custom_2020_02_09_00_world.sql new file mode 100644 index 0000000000..2b2877b0fd --- /dev/null +++ b/sql/updates/world/custom/custom_2020_02_09_00_world.sql @@ -0,0 +1,51 @@ +UPDATE `creature_template` SET `DamageModifier`= 120, `BaseVariance`= 0.5, `mechanic_immune_mask`= 650854271, `mingold`= 17000, `maxgold`= 23000 WHERE `entry`= 23574; +UPDATE `creature_template` SET `ScriptName`= 'npc_akilzon_soaring_eagle', `mechanic_immune_mask`= 650854271 WHERE `entry`= 24858; +UPDATE `creature_template` SET `speed_run`= 1.4285, `vehicleId`= 1612, `ScriptName`= 'npc_akilzon_amani_kidnapper', `mechanic_immune_mask`= 650854271, `flags_extra`= 256 WHERE `entry`= 52638; + +DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (44008, 43648, 44007, 43658); +DELETE FROM `spell_script_names` WHERE `ScriptName` IN +('spell_akilzon_electrical_storm', +'spell_akilzon_teleport_self', +'spell_akilzon_electrical_overloard_graphic_pulse', +'spell_akilzon_electrical_storm_damage', +'spell_akilzon_grab_passenger', +'spell_akilzon_summon_amani_kidnapper'); + +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(43648, 'spell_akilzon_electrical_storm'), +(44006, 'spell_akilzon_teleport_self'), +(43658, 'spell_akilzon_electrical_overloard_graphic_pulse'), +(43657, 'spell_akilzon_electrical_storm_damage'), +(97300, 'spell_akilzon_electrical_storm_damage'), +(98869, 'spell_akilzon_grab_passenger'), +(97316, 'spell_akilzon_summon_amani_kidnapper'); + +DELETE FROM `creature_text` WHERE `CreatureID`= 23574; +INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `comment`) VALUES +(23574, 0, 0, 'I be da predator! You da prey...', 14, 0, 100, 0, 0, 12013, 23235, 'Akil\'zon to Player'), +(23574, 1, 0, 'Feed, me bruddahs!', 14, 0, 100, 0, 0, 12014, 23931, 'Akil\'zon to Akil\'zon'), +(23574, 2, 0, 'An electrical storm appears!', 41, 0, 100, 0, 0, 0, 23603, 'Akil\'zon to Player'), +(23574, 3, 0, 'Stop your cryin\'!', 14, 0, 100, 0, 0, 0, 23233, 'Akil\'zon to Player'), +(23574, 3, 1, 'Ya got nothin\'!', 14, 0, 100, 0, 0, 0, 23234, 'Akil\'zon to Player'), +(23574, 4, 0, 'You can\'t... kill... me spirit!', 14, 0, 100, 0, 0, 12019, 23232, 'Akil\'zon to Player'); + +DELETE FROM `creature_template_movement` WHERE `CreatureId` IN (24858, 52638); +INSERT INTO `creature_template_movement` (`CreatureId`, `Ground`, `Flight`) VALUES +(24858, 2, 1), +(52638, 1, 1); + +DELETE FROM `creature` WHERE `guid` IN (291846, 291854, 291855, 291848, 291836, 291849, 291845, 291840, 291843, 291850, 291837, 291851, 291838, 291842, 291853, 291852); +DELETE FROM `creature_addon` WHERE `guid` IN (291846, 291854, 291855, 291848, 291836, 291849, 291845, 291840, 291843, 291850, 291837, 291851, 291838, 291842, 291853, 291852); + +DELETE FROM `reference_loot_template` WHERE `Entry`= 34150; +DELETE FROM `creature_loot_template` WHERE `Entry`= 23574; +INSERT INTO `creature_loot_template` (`Entry`, `Item`, `Chance`, `QuestRequired`, `LootMode`, `GroupId`, `MinCount`, `MaxCount`) VALUES +(23574, 69551, 0, 0, 1, 1, 1, 1), +(23574, 69552, 0, 0, 1, 1, 1, 1), +(23574, 69549, 0, 0, 1, 1, 1, 1), +(23574, 69550, 0, 0, 1, 1, 1, 1), +(23574, 69553, 0, 0, 1, 1, 1, 1); + +DELETE FROM `creature_onkill_reward` WHERE `creature_id`= 23574; +INSERT INTO `creature_onkill_reward` (`creature_id`, `CurrencyId1`, `CurrencyCount1`, `RewOnKillRepFaction1`, `MaxStanding1`, `IsTeamAward1`, `RewOnKillRepValue1`, `TeamDependent`) VALUES +(23574, 395, 7000, 1162, 7, 0, 250, 0); diff --git a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp index 8f38ed0336..aae3fadddf 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/boss_akilzon.cpp @@ -15,53 +15,322 @@ * with this program. If not, see . */ -#include "ScriptMgr.h" -#include "CellImpl.h" -#include "GridNotifiersImpl.h" -#include "InstanceScript.h" -#include "MotionMaster.h" -#include "ObjectAccessor.h" -#include "ScriptedCreature.h" -#include "TemporarySummon.h" -#include "Weather.h" #include "zulaman.h" +#include "InstanceScript.h" +#include "ObjectAccessor.h" +#include "PassiveAI.h" +#include "ScriptMgr.h" +#include "ScriptedCreature.h" +#include "Spell.h" +#include "SpellAuraEffects.h" +#include "SpellScript.h" +#include "SpellMgr.h" +#include "Weather.h" enum Texts { + // Akil'zon + SAY_AGGRO = 0, + SAY_SUMMON_EAGLES = 1, + SAY_ANNOUNCE_ELECTRICAL_STORM = 2, + SAY_SLAY = 3, + SAY_DEATH = 4 }; enum Spells { + // Akil'zon + SPELL_STATIC_DISRUPTION = 43622, + SPELL_CALL_LIGHTNING = 43661, + SPELL_GUST_OF_WIND = 43621, + SPELL_ELECTRICAL_STORM = 43648, + + // Soaring Eagle + SPELL_EAGLE_SWOOP = 44732, + + // Amani Kidnapper + SPELL_GRAB_PASSENGER = 98869, + SPELL_PLUCKED = 97318, + + // Player + SPELL_TELEPORT_SELF = 44006, + SPELL_ELECTRICAL_STORM_AREA_AURA = 44007, + SPELL_ELECTRICAL_ARC_1 = 43653, + SPELL_ELECTRICAL_ARC_2 = 43654, + SPELL_ELECTRICAL_ARC_3 = 43655, + SPELL_ELECTRICAL_ARC_4 = 43656, + SPELL_ELECTRICAL_ARC_5 = 43659 +}; + +uint32 const electricalArcSpells[5] = +{ + SPELL_ELECTRICAL_ARC_1, + SPELL_ELECTRICAL_ARC_2, + SPELL_ELECTRICAL_ARC_3, + SPELL_ELECTRICAL_ARC_4, + SPELL_ELECTRICAL_ARC_5 }; enum Events { + // Akil'zon + EVENT_STATIC_DISRUPTION = 1, + EVENT_CALL_LIGHTNING, + EVENT_GUST_OF_WIND, + EVENT_ELECTRICAL_STORM, + EVENT_START_RAIN, + EVENT_END_RAIN, + EVENT_SUMMON_SOARING_EAGLES, + + // Soaring Eagle + EVENT_EAGLE_SWOOP, + EVENT_EAGLE_SCREECH, + EVENT_MOVE_RANDOM, + EVENT_MOVE_CYCLIC_PATH +}; + +enum Actions +{ + // Soaring Eagle + ACTION_DO_RANDOM_MOVEMENT = 1 +}; + +enum Data +{ + DATA_EAGLE_NUMBER = 0 +}; + +enum MovePoints +{ + // Amani Kidnapper + POINT_GRAB_PASSENGER = 1 +}; + +enum Misc +{ + ZONE_ID_ZULAMAN = 3805, + SOUND_ID_EAGLE_SCREECH = 12196 +}; + +Position const SoaringEagleSummonPositions[] = +{ + { 355.0323f, 1411.f, 91.6518f, 5.856372f }, + { 356.82877f, 1422.785f, 91.71573f, 1.518436f }, + { 368.7743f, 1377.933f, 91.78314f, 0.4260757f }, + { 361.3212f, 1380.682f, 91.76196f, 3.036873f }, + { 396.1938f, 1398.954f, 91.53065f, 4.3096f }, + { 395.2363f, 1391.221f, 91.78426f, 3.787364f }, + { 386.3385f, 1430.294f, 92.51662f, 3.173957f }, + { 379.344f, 1434.552f, 91.64027f, 0.9599311f } +}; + +std::vector AmaniKidnapperCyclicPath = +{ + { 360.25174f, 1422.9219f, 79.72605f }, + { 373.98438f, 1431.1823f, 79.85269f }, + { 395.0295f, 1425.8403f, 79.52386f }, + { 399.20486f, 1398.4219f, 79.31239f }, + { 390.6059f, 1390.1146f, 79.76962f }, + { 372.62674f, 1383.9062f, 79.27089f }, + { 354.83682f, 1397.5192f, 79.283394f }, + { 353.40973f, 1414.5608f, 79.529434f } +}; + +std::vector SoraringEagleCyclicPath0 = +{ + { 352.03665f, 1411.3475f, 91.7419f }, + { 352.768f, 1412.0295f, 91.7419f }, + { 389.26443f, 1394.4066f, 90.3169f }, + { 405.69748f, 1381.4075f, 90.3169f }, + { 418.16028f, 1383.2f, 90.3169f }, + { 415.5009f, 1387.942f, 90.3169f }, + { 399.76562f, 1414.877f, 90.3169f }, + { 380.8964f, 1424.8958f, 90.3169f }, + { 357.7345f, 1418.2468f, 90.3169f }, + { 342.5394f, 1404.734f, 90.3169f }, + { 343.50098f, 1395.6887f, 90.3169f }, + { 340.88748f, 1384.222f, 90.3169f }, + { 360.84256f, 1382.7749f, 90.3169f }, + { 369.62912f, 1388.5502f, 90.3169f }, + { 376.77408f, 1400.9977f, 90.3169f }, + { 388.67688f, 1423.4247f, 90.3169f }, + { 398.8929f, 1441.9341f, 90.3169f }, + { 382.19348f, 1437.8445f, 90.3169f }, + { 370.78647f, 1423.2487f, 90.3169f }, + { 356.91635f, 1397.7987f, 90.3169f }, + { 354.5165f, 1380.9031f, 90.3169f }, + { 395.601f, 1376.0145f, 90.3169f }, + { 422.74762f, 1384.6039f, 90.3169f }, + { 398.88052f, 1410.5187f, 90.3169f }, + { 382.2971f, 1424.7145f, 90.3169f }, + { 360.14865f, 1431.6875f, 90.3169f }, + { 345.7219f, 1422.5363f, 90.3169f }, + { 345.66623f, 1416.4381f, 90.3169f }, + { 389.26443f, 1394.4066f, 90.3169f }, + { 405.69748f, 1381.4075f, 90.3169f } +}; + +std::vector SoraringEagleCyclicPath2 = +{ + { 367.06046f, 1376.0284f, 91.747284f }, + { 366.48688f, 1376.8475f, 91.747284f }, + { 402.18002f, 1393.9266f, 92.29734f }, + { 405.5344f, 1407.2664f, 92.29734f }, + { 391.50912f, 1426.6482f, 92.29734f }, + { 384.56445f, 1434.1189f, 92.29734f }, + { 357.36685f, 1441.9121f, 92.29734f }, + { 351.07693f, 1440.2948f, 92.29734f }, + { 329.53537f, 1422.8164f, 92.29734f }, + { 331.16852f, 1411.1921f, 92.29734f }, + { 352.1847f, 1384.4667f, 92.29734f }, + { 394.28995f, 1393.1965f, 92.29734f }, + { 410.53754f, 1400.7565f, 92.29734f }, + { 397.51172f, 1432.3961f, 92.29734f }, + { 351.6988f, 1433.4469f, 92.29734f }, + { 335.5918f, 1438.5464f, 92.29734f }, + { 328.19498f, 1434.6647f, 92.29734f }, + { 319.32867f, 1429.3776f, 92.29734f }, + { 329.76138f, 1413.6876f, 92.29734f }, + { 365.2091f, 1407.883f, 92.29734f }, + { 402.18002f, 1393.9266f, 92.29734f }, + { 405.5344f, 1407.2664f, 92.29734f } +}; + +std::vector SoraringEagleCyclicPath4 = +{ + { 396.47882f, 1402.0371f, 91.81095f }, + { 397.27747f, 1401.4353f, 91.81095f }, + { 387.03668f, 1381.7903f, 89.69339f }, + { 370.12805f, 1370.0513f, 89.69339f }, + { 359.64487f, 1373.1759f, 89.69339f }, + { 350.18198f, 1386.6072f, 89.69339f }, + { 345.56348f, 1402.6711f, 89.69339f }, + { 355.46756f, 1424.0919f, 89.69339f }, + { 367.25217f, 1433.9203f, 89.69339f }, + { 373.7067f, 1438.8328f, 89.69339f }, + { 386.6186f, 1435.4559f, 89.69339f }, + { 405.42404f, 1418.889f, 89.69339f }, + { 410.99643f, 1390.823f, 89.69339f }, + { 397.09592f, 1382.1975f, 89.69339f }, + { 376.45215f, 1393.8619f, 89.69339f }, + { 356.00858f, 1404.278f, 89.69339f }, + { 344.35168f, 1416.3293f, 89.69339f }, + { 351.9594f, 1439.8646f, 89.69339f }, + { 353.33682f, 1441.8173f, 89.69339f }, + { 368.85004f, 1445.7336f, 89.69339f }, + { 381.1107f, 1440.9076f, 89.69339f }, + { 392.25012f, 1433.5304f, 89.69339f }, + { 388.21756f, 1408.2224f, 89.69339f }, + { 378.6734f, 1393.3729f, 89.69339f }, + { 368.74435f, 1377.1985f, 89.69339f }, + { 358.59244f, 1357.8248f, 89.69339f }, + { 352.95963f, 1373.3104f, 89.69339f }, + { 354.78592f, 1394.457f, 89.69339f }, + { 362.43695f, 1408.394f, 89.69339f }, + { 379.70877f, 1427.434f, 89.69339f }, + { 392.25433f, 1431.5131f, 89.69339f }, + { 402.16602f, 1427.8239f, 89.69339f }, + { 387.03668f, 1381.7903f, 89.69339f }, + { 370.12805f, 1370.0513f, 89.69339f } +}; + +std::vector SoraringEagleCyclicPath6 = +{ + { 389.7559f, 1429.5692f, 91.704124f }, + { 389.15408f, 1430.3678f, 91.704124f }, + { 364.2945f, 1429.2323f, 99.35547f }, + { 385.5457f, 1429.0762f, 97.52219f }, + { 403.14258f, 1412.2823f, 91.68882f }, + { 400.02182f, 1390.2379f, 91.68882f }, + { 376.41537f, 1384.655f, 94.605484f }, + { 359.02756f, 1371.6508f, 94.605484f }, + { 346.9107f, 1391.9337f, 94.605484f }, + { 341.37088f, 1418.3412f, 94.605484f }, + { 350.69977f, 1429.8486f, 94.605484f }, + { 370.01108f, 1435.0266f, 94.605484f }, + { 392.06976f, 1429.9241f, 94.605484f }, + { 386.54068f, 1408.4303f, 94.605484f }, + { 373.95096f, 1376.0957f, 94.605484f }, + { 357.72754f, 1363.8644f, 94.605484f }, + { 347.01358f, 1378.5763f, 94.605484f }, + { 347.7666f, 1389.9219f, 94.605484f }, + { 365.9999f, 1404.3414f, 94.605484f }, + { 383.0139f, 1413.7719f, 94.605484f }, + { 409.8304f, 1421.2222f, 94.605484f }, + { 401.74924f, 1445.9572f, 94.605484f }, + { 382.86514f, 1454.6213f, 94.605484f }, + { 365.86273f, 1452.1888f, 94.605484f }, + { 351.98242f, 1449.2568f, 94.605484f }, + { 334.17416f, 1440.2583f, 94.605484f }, + { 334.8176f, 1426.2494f, 94.605484f }, + { 345.3902f, 1406.333f, 94.605484f }, + { 362.73828f, 1394.9055f, 94.605484f }, + { 394.5153f, 1384.1464f, 94.605484f }, + { 419.7296f, 1377.4557f, 94.605484f }, + { 409.288f, 1407.1461f, 94.605484f }, + { 386.95444f, 1434.5723f, 94.605484f }, + { 349.70334f, 1440.1602f, 98.16106f }, + { 333.68912f, 1444.1354f, 100.02217f }, + { 312.27518f, 1440.3971f, 100.02216f }, + { 303.0779f, 1411.3394f, 97.49439f }, + { 321.6631f, 1412.2037f, 94.605484f }, + { 364.2945f, 1429.2323f, 99.35547f }, + { 385.5457f, 1429.0762f, 97.52219f } +}; + +std::unordered_map> CyclicPathsByEagleNumber = +{ + { 0, SoraringEagleCyclicPath0 }, + { 2, SoraringEagleCyclicPath2 }, + { 4, SoraringEagleCyclicPath4 }, + { 6, SoraringEagleCyclicPath6 } }; struct boss_akilzon : public BossAI { - boss_akilzon(Creature* creature) : BossAI(creature, DATA_ALKILZON) - { - Initialize(); - } - - void Initialize() - { - } - - void Reset() override - { - _Reset(); - } + boss_akilzon(Creature* creature) : BossAI(creature, DATA_ALKILZON) { } void JustEngagedWith(Unit* /*who*/) override { _JustEngagedWith(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_ENGAGE, me); + Talk(SAY_AGGRO); + + events.ScheduleEvent(EVENT_STATIC_DISRUPTION, 6s); + events.ScheduleEvent(EVENT_CALL_LIGHTNING, 7s); + events.ScheduleEvent(EVENT_GUST_OF_WIND, 9s + 500ms); + events.ScheduleEvent(EVENT_ELECTRICAL_STORM, 49s); + events.ScheduleEvent(EVENT_START_RAIN, 41s); + events.ScheduleEvent(EVENT_SUMMON_SOARING_EAGLES, 11s); } void JustDied(Unit* /*killer*/) override { _JustDied(); + Talk(SAY_DEATH); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + me->GetMap()->SetZoneWeather(ZONE_ID_ZULAMAN, WEATHER_STATE_FOG, 0.f); + } + + void KilledUnit(Unit* who) override + { + if (who->IsPlayer()) + Talk(SAY_SLAY); + } + + void EnterEvadeMode(EvadeReason /*why*/) override + { + _EnterEvadeMode(); + summons.DespawnAll(); + instance->SendEncounterUnit(ENCOUNTER_FRAME_DISENGAGE, me); + me->GetMap()->SetZoneWeather(ZONE_ID_ZULAMAN, WEATHER_STATE_FOG, 0.f); + _DespawnAtEvade(); + } + + void JustSummoned(Creature* summon) override + { + summons.Summon(summon); + summon->SetReactState(REACT_PASSIVE); } void UpdateAI(uint32 diff) override @@ -71,11 +340,354 @@ struct boss_akilzon : public BossAI events.Update(diff); + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_STATIC_DISRUPTION: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + DoCast(target, SPELL_STATIC_DISRUPTION); + events.Repeat(12s); + break; + case EVENT_CALL_LIGHTNING: + DoCastVictim(SPELL_CALL_LIGHTNING); + events.Repeat(7s, 9s); + break; + case EVENT_GUST_OF_WIND: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, [this](Unit const* target)->bool + { + return target && me->GetVictim() != target && !target->HasAura(SPELL_PLUCKED); + })) + DoCast(target, SPELL_GUST_OF_WIND); + events.Repeat(24s); + break; + case EVENT_ELECTRICAL_STORM: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, NonTankTargetSelector(me))) + DoCast(target, SPELL_ELECTRICAL_STORM); + + events.RescheduleEvent(EVENT_STATIC_DISRUPTION, 14s + 500ms); + events.RescheduleEvent(EVENT_GUST_OF_WIND, 17s); + events.RescheduleEvent(EVENT_CALL_LIGHTNING, 18s); + events.ScheduleEvent(EVENT_END_RAIN, 8s); + events.ScheduleEvent(EVENT_START_RAIN, 41s); + events.ScheduleEvent(EVENT_SUMMON_SOARING_EAGLES, 19s); + events.Repeat(49s); + break; + case EVENT_START_RAIN: + me->GetMap()->SetZoneWeather(ZONE_ID_ZULAMAN, WEATHER_STATE_MEDIUM_RAIN, 0.75f); + break; + case EVENT_END_RAIN: + me->GetMap()->SetZoneWeather(ZONE_ID_ZULAMAN, WEATHER_STATE_FOG, 0.f); + break; + case EVENT_SUMMON_SOARING_EAGLES: + Talk(SAY_SUMMON_EAGLES); + for (uint8 i = 0; i < 8; i++) + { + bool cyclic = i == 0 || i == 2 || i == 4 || i == 6; + + if (Creature* eagle = DoSummon(NPC_SOARING_EAGLE, SoaringEagleSummonPositions[i], 4000)) + { + if (cyclic) + { + eagle->GetMotionMaster()->MoveCyclicPath(CyclicPathsByEagleNumber[i].data(), CyclicPathsByEagleNumber[i].size(), false, true); + eagle->AI()->SetData(DATA_EAGLE_NUMBER, i); + } + else + eagle->AI()->DoAction(ACTION_DO_RANDOM_MOVEMENT); + } + } + break; + default: + break; + } + } DoMeleeAttackIfReady(); } }; +struct npc_akilzon_soaring_eagle : public PassiveAI +{ + npc_akilzon_soaring_eagle(Creature* creature) : PassiveAI(creature), _randomMovement(false), _eagleNumber(0) { } + + void JustAppeared() override + { + _events.ScheduleEvent(EVENT_EAGLE_SCREECH, 3s, 6s); + _events.ScheduleEvent(EVENT_EAGLE_SWOOP, 3s, 6s); + DoZoneInCombat(); + } + + void DoAction(int32 action) override + { + switch (action) + { + case ACTION_DO_RANDOM_MOVEMENT: + _events.ScheduleEvent(EVENT_MOVE_RANDOM, 1ms); + _randomMovement = true; + break; + default: + break; + } + } + + void SetData(uint32 type, uint32 data) override + { + switch (type) + { + case DATA_EAGLE_NUMBER: + _eagleNumber = data; + break; + default: + break; + } + } + + void UpdateAI(uint32 diff) override + { + _events.Update(diff); + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_EAGLE_SCREECH: + me->PlayDirectSound(SOUND_ID_EAGLE_SCREECH); + _events.Repeat(3s + 500ms, 10s); + break; + case EVENT_EAGLE_SWOOP: + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 40.f, true, 0)) + DoCast(target, SPELL_EAGLE_SWOOP); + _events.Repeat(5s, 6s); + + if (_randomMovement) + _events.RescheduleEvent(EVENT_MOVE_RANDOM, 2s); + else + _events.ScheduleEvent(EVENT_MOVE_CYCLIC_PATH, 2s); + break; + case EVENT_MOVE_RANDOM: + { + Position pos = me->GetHomePosition(); + pos.RelocateOffset({ frand(-7.f, 7.f), frand(-7.f, 7.f), frand(-1.f, 1.f) }); + if (me->GetPositionZ() <= 90.f) + pos.m_positionZ = std::min(me->GetPositionZ() + 10.f, pos.GetPositionZ()); + + me->GetMotionMaster()->MovePoint(0, pos, false); + _events.Repeat(1s + 200ms); + break; + } + case EVENT_MOVE_CYCLIC_PATH: + me->GetMotionMaster()->MoveCyclicPath(CyclicPathsByEagleNumber[_eagleNumber].data(), CyclicPathsByEagleNumber[_eagleNumber].size(), false, true); + break; + default: + break; + } + } + } + +private: + EventMap _events; + bool _randomMovement; + uint8 _eagleNumber; +}; + +struct npc_akilzon_amani_kidnapper : public PassiveAI +{ + npc_akilzon_amani_kidnapper(Creature* creature) : PassiveAI(creature) { } + + void IsSummonedBy(Unit* /*summoner*/) override + { + if (InstanceScript* instance = me->GetInstanceScript()) + if (Creature* akilzon = instance->GetCreature(DATA_ALKILZON)) + akilzon->AI()->JustSummoned(me); + } + + void JustAppeared() override + { + if (TempSummon* summon = me->ToTempSummon()) + if (Unit* summoner = summon->GetSummoner()) + me->GetMotionMaster()->MovePoint(POINT_GRAB_PASSENGER, summoner->GetPosition(), false); + } + + void JustDied(Unit* /*killer*/) override + { + me->DespawnOrUnsummon(6s); + } + + void MovementInform(uint32 type, uint32 pointId) override + { + if (type != POINT_MOTION_TYPE) + return; + + switch (pointId) + { + case POINT_GRAB_PASSENGER: + if (TempSummon* summon = me->ToTempSummon()) + if (Unit* summoner = summon->GetSummoner()) + DoCast(summoner, SPELL_GRAB_PASSENGER); + break; + default: + break; + } + } + + void PassengerBoarded(Unit* /*passenger*/, int8 /*seatId*/, bool apply) override + { + if (!apply) + return; + + me->GetMotionMaster()->MoveCyclicPath(AmaniKidnapperCyclicPath.data(), AmaniKidnapperCyclicPath.size(), false, true); + } + + void UpdateAI(uint32 /*diff*/) override { } +}; + +class spell_akilzon_electrical_storm : public AuraScript +{ + PrepareAuraScript(spell_akilzon_electrical_storm); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_TELEPORT_SELF, + SPELL_ELECTRICAL_STORM_AREA_AURA + }); + } + + void AfterApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->SetDisableGravity(true); + target->SendSetPlayHoverAnim(true); + target->SetControlled(true, UNIT_STATE_ROOT); + target->CastSpell(target, SPELL_ELECTRICAL_STORM_AREA_AURA, true); + target->CastSpell(target, SPELL_TELEPORT_SELF, true); + } + + void AfterRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/) + { + Unit* target = GetTarget(); + target->SetDisableGravity(false); + target->SetControlled(false, UNIT_STATE_ROOT); + target->RemoveAurasDueToSpell(SPELL_ELECTRICAL_STORM_AREA_AURA); + target->SendSetPlayHoverAnim(false); + target->CastSpell(target, GetSpellInfo()->Effects[EFFECT_2].BasePoints); + } + + void Register() override + { + AfterEffectApply += AuraEffectApplyFn(spell_akilzon_electrical_storm::AfterApply, EFFECT_0, SPELL_AURA_BLOCK_SPELL_FAMILY, AURA_EFFECT_HANDLE_REAL); + AfterEffectRemove += AuraEffectRemoveFn(spell_akilzon_electrical_storm::AfterRemove, EFFECT_0, SPELL_AURA_BLOCK_SPELL_FAMILY, AURA_EFFECT_HANDLE_REAL); + } +}; + +class spell_akilzon_electrical_storm_damage : public SpellScript +{ + PrepareSpellScript(spell_akilzon_electrical_storm_damage); + + void FilterTargets(std::list& targets) + { + if (targets.empty()) + return; + + targets.remove_if([](WorldObject const* target)->bool + { + return (!target->ToUnit() || target->ToUnit()->HasAura(SPELL_ELECTRICAL_STORM_AREA_AURA)); + }); + } + + void Register() override + { + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_akilzon_electrical_storm_damage::FilterTargets, EFFECT_0, TARGET_UNIT_SRC_AREA_ALLY); + OnObjectAreaTargetSelect += SpellObjectAreaTargetSelectFn(spell_akilzon_electrical_storm_damage::FilterTargets, EFFECT_1, TARGET_UNIT_SRC_AREA_ALLY); + } +}; + +class spell_akilzon_electrical_overloard_graphic_pulse : public SpellScript +{ + PrepareSpellScript(spell_akilzon_electrical_overloard_graphic_pulse); + + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo( + { + SPELL_ELECTRICAL_ARC_1, + SPELL_ELECTRICAL_ARC_2, + SPELL_ELECTRICAL_ARC_3, + SPELL_ELECTRICAL_ARC_4, + SPELL_ELECTRICAL_ARC_5 + }); + } + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + for (uint8 i = 0; i < 5; i++) + GetHitUnit()->CastSpell(GetHitUnit(), electricalArcSpells[i], true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_akilzon_electrical_overloard_graphic_pulse::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +class spell_akilzon_teleport_self : public SpellScript +{ + PrepareSpellScript(spell_akilzon_teleport_self); + + void SetDest(SpellDestination& dest) + { + dest.RelocateOffset({ 0.0f, 0.0f, 10.0f, 0.0f }); + } + + void Register() override + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_akilzon_teleport_self::SetDest, EFFECT_0, TARGET_DEST_CASTER); + } +}; + +class spell_akilzon_grab_passenger : public SpellScript +{ + PrepareSpellScript(spell_akilzon_grab_passenger); + + void HandleScriptEffect(SpellEffIndex /*effIndex*/) + { + if (Unit* caster = GetCaster()) + GetHitUnit()->CastSpell(caster, GetEffectValue(), true); + } + + void Register() override + { + OnEffectHitTarget += SpellEffectFn(spell_akilzon_grab_passenger::HandleScriptEffect, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT); + } +}; + +class spell_akilzon_summon_amani_kidnapper : public SpellScript +{ + PrepareSpellScript(spell_akilzon_summon_amani_kidnapper); + + void SetDest(SpellDestination& dest) + { + dest.RelocateOffset({ 0.0f, 0.0f, 30.0f, 0.0f }); + } + + void Register() + { + OnDestinationTargetSelect += SpellDestinationTargetSelectFn(spell_akilzon_summon_amani_kidnapper::SetDest, EFFECT_0, TARGET_DEST_CASTER); + } +}; + void AddSC_boss_akilzon() { RegisterZulAamanCreatureAI(boss_akilzon); + RegisterZulAamanCreatureAI(npc_akilzon_soaring_eagle); + RegisterZulAamanCreatureAI(npc_akilzon_amani_kidnapper); + RegisterAuraScript(spell_akilzon_electrical_storm); + RegisterSpellScript(spell_akilzon_electrical_storm_damage); + RegisterSpellScript(spell_akilzon_electrical_overloard_graphic_pulse); + RegisterSpellScript(spell_akilzon_teleport_self); + RegisterSpellScript(spell_akilzon_grab_passenger); + RegisterSpellScript(spell_akilzon_summon_amani_kidnapper); } diff --git a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp index 2ee88a3413..bb591954ee 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp +++ b/src/server/scripts/EasternKingdoms/ZulAman/instance_zulaman.cpp @@ -42,6 +42,12 @@ ObjectData const gameobjectData[] = { 0, 0 } // END }; +DoorData const doorData[] = +{ + { GO_DOODAD_ZULAMAN_WIND_DOOR, DATA_ALKILZON, DOOR_TYPE_ROOM }, + { 0, 0, DOOR_TYPE_ROOM } // END +}; + Position const AmanishiGuardianDistanceCheckPos = { 120.223f, 1585.766f, 43.43f }; Position const AmanishiSavageDistanceCheckPos = { 122.176f, 1528.203f, 21.233f }; @@ -57,6 +63,7 @@ public: SetHeaders(DataHeader); SetBossNumber(EncounterCount); LoadObjectData(creatureData, gameobjectData); + LoadDoorData(doorData); _remainingSpeedRunTime = 0; _savagesAtGateTriggered = false; _speedRunState = NOT_STARTED; diff --git a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h index d5cf73f9fb..c71c986e0e 100644 --- a/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h +++ b/src/server/scripts/EasternKingdoms/ZulAman/zulaman.h @@ -54,6 +54,10 @@ enum ZACreatureIds BOSS_HEXLORD_MALACRASS = 24239, BOSS_DAAKARA = 23863, + // Encounter related creatures + /*Akil'zon*/ + NPC_SOARING_EAGLE = 24858, + NPC_VOLJIN = 52924, NPC_HEXLORD_MALACRASS_TRIGGER = 24363, NPC_AMANISHI_GUARDIAN = 23597, @@ -62,8 +66,9 @@ enum ZACreatureIds enum ZAGameObjectIds { - GO_STRANGE_GONG = 187359, - GO_MASSIVE_GATE = 186728, + GO_STRANGE_GONG = 187359, + GO_MASSIVE_GATE = 186728, + GO_DOODAD_ZULAMAN_WIND_DOOR = 186858, }; enum ZAEvents