From dcd5716ecb3d5f10ec212c8a1362c0770f3e1615 Mon Sep 17 00:00:00 2001 From: Ovahlord Date: Sun, 25 Apr 2021 20:20:34 +0200 Subject: [PATCH] Scripts/BoT: scripted Evolved Drakonaar and updated its pathing --- .../world/4.3.4/2021_04_25_01_world.sql | 30 ++++ .../BastionOfTwilight/bastion_of_twilight.cpp | 140 ++++++++++++++++++ 2 files changed, 170 insertions(+) create mode 100644 sql/updates/world/4.3.4/2021_04_25_01_world.sql diff --git a/sql/updates/world/4.3.4/2021_04_25_01_world.sql b/sql/updates/world/4.3.4/2021_04_25_01_world.sql new file mode 100644 index 00000000000..26462c6f341 --- /dev/null +++ b/sql/updates/world/4.3.4/2021_04_25_01_world.sql @@ -0,0 +1,30 @@ +SET @CGUID := 254061; +SET @PATH := @CGUID * 10; +DELETE FROM `waypoint_data` WHERE `id`= @PATH; +INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`) VALUES +(@PATH, 0, -842.4097, -659.1024, 831.901, 0, 249), +(@PATH, 1, -842.6354, -643.3143, 831.9013, 0, -768), +(@PATH, 2, -845.6443, -630.6788, 831.9009, 0, -933), +(@PATH, 3, -851.9236, -615.9549, 831.9012, 0, -1713), +(@PATH, 4, -858.941, -605.8246, 831.9009, 0, -1803), +(@PATH, 5, -868.1458, -594.6719, 831.9009, 0, -990), +(@PATH, 6, -878.0174, -585.4393, 831.9009, 0, -1492), +(@PATH, 7, -890.8246, -583.9236, 831.9009, 0, 1037), +(@PATH, 8, -878.0174, -585.4393, 831.9009, 0, -1378), +(@PATH, 9, -868.1458, -594.6719, 831.9009, 0, -1706), +(@PATH, 10, -858.941, -605.8246, 831.9009, 0, -929), +(@PATH, 11, -851.9236, -615.9549, 831.9012, 0, -1056), +(@PATH, 12, -845.6736, -630.5555, 831.9009, 0, -1826), +(@PATH, 13, -842.6354, -643.3143, 831.9013, 0, -749); + +UPDATE `creature` SET `position_x`= -842.4097, `position_y`= -659.1024, `position_z`= 831.901, `orientation`= 0, `spawndist`= 0, `MovementType`= 2 WHERE `guid`= @CGUID; +DELETE FROM `creature_addon` WHERE `guid`= @CGUID; +INSERT INTO `creature_addon` (`guid`, `waypointPathId`, `bytes2`) VALUES +(@CGUID, @PATH, 1); + +UPDATE `creature_template` SET `difficulty_entry_1`= 49814, `ScriptName`= 'npc_bot_evolved_drakonaar' WHERE `entry`= 49813; +UPDATE `creature_template` SET `minlevel`= 87, `maxlevel`= 87, `exp`= 3, `faction`= 16, `speed_run`= 1.42857, `BaseAttackTime`= 1500, `mechanic_immune_mask`= 650854271, `unit_flags`= 32832 WHERE `entry` IN (49813, 49814); + +DELETE FROM `spell_script_names` WHERE `ScriptName`= 'spell_bot_twilight_rupture'; +INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES +(93377, 'spell_bot_twilight_rupture'); diff --git a/src/server/scripts/EasternKingdoms/BastionOfTwilight/bastion_of_twilight.cpp b/src/server/scripts/EasternKingdoms/BastionOfTwilight/bastion_of_twilight.cpp index 2273e048a18..632bf33bd8f 100644 --- a/src/server/scripts/EasternKingdoms/BastionOfTwilight/bastion_of_twilight.cpp +++ b/src/server/scripts/EasternKingdoms/BastionOfTwilight/bastion_of_twilight.cpp @@ -24,8 +24,12 @@ #include "GameObject.h" #include "GameObjectAI.h" #include "Object.h" +#include "Map.h" +#include "MotionMaster.h" #include "PassiveAI.h" #include "Player.h" +#include "VMapFactory.h" +#include "VMapManager2.h" #include "bastion_of_twilight.h" #include @@ -135,6 +139,85 @@ struct npc_bot_chogall final : public NullCreatureAI } }; +enum EvolvedDrakonaar +{ + EVENT_CLEAVE = 1, + EVENT_TWILIGHT_RUPTURE, + EVENT_BLADE_TEMPEST, + + SPELL_CLEAVE = 40504, + SPELL_TWILIGHT_RUPTURE = 93377, + SPELL_BLADE_TEMPEST = 93373, +}; + +struct npc_bot_evolved_drakonaar : public ScriptedAI +{ + npc_bot_evolved_drakonaar(Creature * creature) : ScriptedAI(creature) { } + + void JustEngagedWith(Unit* /*who*/) override + { + _events.ScheduleEvent(EVENT_CLEAVE, 9s); + _events.ScheduleEvent(EVENT_TWILIGHT_RUPTURE, 10s); + _events.ScheduleEvent(EVENT_BLADE_TEMPEST, 18s); + + // The Drakonaar in the corner starts moving along the same path as the moving one when engaging the moving one + if (me->GetWaypointPath()) + if (Creature* drakonaar = me->FindNearestCreature(me->GetEntry(), 200.f)) + if (drakonaar->GetMotionMaster()->GetCurrentSlot() == MOTION_SLOT_IDLE && drakonaar->GetMotionMaster()->GetCurrentMovementGeneratorType() != WAYPOINT_MOTION_TYPE) + drakonaar->GetMotionMaster()->MovePath(me->GetWaypointPath(), true); + } + + void EnterEvadeMode(EvadeReason why) override + { + ScriptedAI::EnterEvadeMode(why); + _events.Reset(); + } + + void UpdateAI(uint32 diff) override + { + if (!UpdateVictim()) + return; + + _events.Update(diff); + + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + + while (uint32 eventId = _events.ExecuteEvent()) + { + switch (eventId) + { + case EVENT_CLEAVE: + DoCastVictim(SPELL_CLEAVE); + _events.Repeat(20s, 21s); + break; + case EVENT_TWILIGHT_RUPTURE: + { + if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 45.f, true, false)) + DoCast(target, SPELL_TWILIGHT_RUPTURE); + else + DoCastVictim(SPELL_TWILIGHT_RUPTURE); + _events.Repeat(24s, 25s); + break; + } + case EVENT_BLADE_TEMPEST: + DoCastSelf(SPELL_BLADE_TEMPEST); + // @todo: repeat timer + break; + default: + break; + } + if (me->HasUnitState(UNIT_STATE_CASTING)) + return; + } + + DoMeleeAttackIfReady(); + } + +private: + EventMap _events; +}; + static constexpr uint32 const SPELL_WYVERN_STING_PERIODIC = 24336; class spell_bot_wyvern_sting : public AuraScript @@ -156,6 +239,61 @@ class spell_bot_wyvern_sting : public AuraScript } }; +static constexpr uint32 const SPELL_TWILIGHT_RUPTURE_MISSILE = 93378; + +class spell_bot_twilight_rupture : public SpellScript +{ + bool Validate(SpellInfo const* /*spellInfo*/) override + { + return ValidateSpellInfo({ SPELL_TWILIGHT_RUPTURE_MISSILE }); + } + + void HandleDummyEffect(SpellEffIndex /*effIndex*/) + { + Unit* caster = GetCaster(); + if (!caster) + return; + + float angleVariance = 0.15f; + float currentAngle = caster->GetOrientation(); + bool left = true; + for (uint8 i = 0; i < 60; ++i) + { + float forward = 1.5f * i; + if (i >= 3 && !((i - 3) % 5)) + left = !left; + + currentAngle = left ? (currentAngle + angleVariance) : (currentAngle - angleVariance); + + // Sniffs indicate that they use pathfinding for every single destination but we are not going to do so because of performance. + float destX = caster->GetPositionX() + std::cos(currentAngle) * forward; + float destY = caster->GetPositionY() + std::sin(currentAngle) * forward; + float destZ = caster->GetPositionZ(); + + bool col = VMAP::VMapFactory::createOrGetVMapManager()->getObjectHitPos(caster->GetMapId(), + caster->GetPositionX(), caster->GetPositionY(), caster->GetPositionZ() + 0.5f, + destX, destY, destZ + 0.5f, + destX, destY, destZ, -0.5f); + + destZ -= 0.5f; + + // Collided with static LOS object, move back to collision point + if (col) + { + destX -= 2.f * std::cos(currentAngle); + destY -= 2.f * std::sin(currentAngle); + } + + caster->CastSpell({ destX, destY, destZ }, SPELL_TWILIGHT_RUPTURE_MISSILE); + } + } + + void Register() override + { + OnEffectHitTarget.Register(&spell_bot_twilight_rupture::HandleDummyEffect, EFFECT_0, SPELL_EFFECT_DUMMY); + } +}; + class at_bot_intro_events final : public OnlyOnceAreaTriggerScript { public: @@ -175,7 +313,9 @@ void AddSC_bastion_of_twilight() { RegisterBastionOfTwilightCreatureAI(npc_bot_invisible_stalker_phase_twist); RegisterBastionOfTwilightCreatureAI(npc_bot_chogall); + RegisterBastionOfTwilightCreatureAI(npc_bot_evolved_drakonaar); RegisterSpellScript(spell_bot_wyvern_sting); + RegisterSpellScript(spell_bot_twilight_rupture); new at_bot_intro_events("at_halfus_wyrmbreaker_intro", DATA_AT_HALFUS_WYRMBREAKER_INTRO); new at_bot_intro_events("at_theralion_and_valiona_intro", DATA_AT_THERALION_AND_VALIONA_INTRO); new at_bot_intro_events("at_ascendant_council_intro_1", DATA_AT_ASCENDANT_COUNCIL_INTRO_1);