mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-15 23:20:36 +01:00
Scripts/RedridgeMountains: Implement Quest "Saving Foreman Oslow" (#30947)
This commit is contained in:
122
sql/updates/world/master/2025_05_30_01_world.sql
Normal file
122
sql/updates/world/master/2025_05_30_01_world.sql
Normal file
@@ -0,0 +1,122 @@
|
||||
# fix respawn times for bridge workers, foreman oslow, and huge boulder
|
||||
UPDATE `creature` SET `spawntimesecs` = 30 WHERE `guid` IN (334925, 334930, 334929, 334928, 334931, 334927, 334926, 334924);
|
||||
|
||||
# move script from alex to boulder
|
||||
UPDATE `creature_template` SET `ScriptName`='npc_redridge_huge_boulder' WHERE `entry` = 43196; -- Huge Boulder
|
||||
UPDATE `creature_template` SET `ScriptName`='' WHERE `entry` = 653; -- Bridge Worker Alex
|
||||
|
||||
UPDATE `creature_template` SET `unit_flags2`=0x800 WHERE `entry`=43094; -- Canyon Ettin
|
||||
UPDATE `creature_template` SET `faction`=35, `unit_flags`=0x40, `VehicleId`=938, `ScriptName`='npc_redridge_subdued_canyon_ettin' WHERE `entry`=43197; -- Subdued Canyon Ettin
|
||||
UPDATE `creature_template` SET `unit_flags3`=0x1000000 WHERE `entry`=43196; -- Huge Boulder
|
||||
|
||||
DELETE FROM `creature_template_addon` WHERE `entry` IN (43197 /*43197 (Subdued Canyon Ettin) - Detect: Quest Invis Zone 1*/);
|
||||
INSERT INTO `creature_template_addon` (`entry`, `PathId`, `mount`, `StandState`, `AnimTier`, `VisFlags`, `SheathState`, `PvpFlags`, `emote`, `aiAnimKit`, `movementAnimKit`, `meleeAnimKit`, `visibilityDistanceType`, `auras`) VALUES
|
||||
(43197, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 4, '81299'); -- 43197 (Subdued Canyon Ettin) - Detect: Quest Invis Zone 1
|
||||
|
||||
UPDATE `creature_template_difficulty` SET `StaticFlags1`=0x0, `VerifiedBuild`=60822 WHERE (`Entry`=341 AND `DifficultyID`=0); -- 341 (Foreman Oslow) -
|
||||
UPDATE `creature_template_difficulty` SET `StaticFlags1`=0x0, `VerifiedBuild`=60822 WHERE (`Entry`=648 AND `DifficultyID`=0); -- 648 (Bridge Worker Trent) -
|
||||
UPDATE `creature_template_difficulty` SET `StaticFlags1`=0x0, `VerifiedBuild`=60822 WHERE (`Entry`=649 AND `DifficultyID`=0); -- 649 (Bridge Worker Dmitri) -
|
||||
UPDATE `creature_template_difficulty` SET `StaticFlags1`=0x0, `VerifiedBuild`=60822 WHERE (`Entry`=650 AND `DifficultyID`=0); -- 650 (Bridge Worker Jess) -
|
||||
UPDATE `creature_template_difficulty` SET `StaticFlags1`=0x0, `VerifiedBuild`=60822 WHERE (`Entry`=651 AND `DifficultyID`=0); -- 651 (Bridge Worker Daniel) -
|
||||
UPDATE `creature_template_difficulty` SET `StaticFlags1`=0x0, `VerifiedBuild`=60822 WHERE (`Entry`=652 AND `DifficultyID`=0); -- 652 (Bridge Worker Matthew) -
|
||||
UPDATE `creature_template_difficulty` SET `StaticFlags1`=0x0, `VerifiedBuild`=60822 WHERE (`Entry`=653 AND `DifficultyID`=0); -- 653 (Bridge Worker Alex) -
|
||||
UPDATE `creature_template_difficulty` SET `StaticFlags1`=0x0, `VerifiedBuild`=60822 WHERE (`Entry`=43094 AND `DifficultyID`=0); -- 43094 (Canyon Ettin) -
|
||||
UPDATE `creature_template_difficulty` SET `StaticFlags1`=0x0, `VerifiedBuild`=60822 WHERE (`Entry`=43197 AND `DifficultyID`=0); -- 43197 (Subdued Canyon Ettin) -
|
||||
|
||||
DELETE FROM `spell_script_names` WHERE `spell_id` IN (80704, 80702, 80739, 80707);
|
||||
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
|
||||
(80704, 'spell_redridge_control_ettin'),
|
||||
(80702, 'spell_redridge_control_ettin_2'),
|
||||
(80739, 'spell_gen_reverse_cast_target_to_caster_triggered'),
|
||||
(80707, 'spell_gen_despawn_target');
|
||||
|
||||
# exit location for thrown boulder
|
||||
DELETE FROM `vehicle_seat_addon` WHERE `SeatEntry` = 8161;
|
||||
INSERT INTO `vehicle_seat_addon` (`SeatEntry`, `SeatOrientation`, `ExitParamX`, `ExitParamY`, `ExitParamZ`, `ExitParamO`, `ExitParamValue`) VALUES
|
||||
(8161, 0, -9310.855, -2366.367, 67.17842, 0, 2);
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID` = 43197 AND `GroupID` IN (0, 1, 2, 3);
|
||||
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||
(43197, 0, 0, 'ROCK NOT SO HEAVY! PUNY HUMIES!', 12, 0, 100, 0, 0, 0, 43218, 0, 'Subdued Canyon Ettin to Huge Boulder'),
|
||||
(43197, 1, 0, 'Where trow? TROW ON BRIDGE??', 12, 0, 100, 0, 0, 0, 43220, 0, 'Subdued Canyon Ettin to Huge Boulder'),
|
||||
(43197, 2, 0, 'OK! Me trow in water!', 12, 0, 100, 0, 0, 0, 43222, 0, 'Subdued Canyon Ettin to Huge Boulder'),
|
||||
(43197, 3, 0, 'BYE, BYE, DADDY!', 14, 0, 100, 0, 0, 0, 43226, 0, 'Subdued Canyon Ettin to Huge Boulder');
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID` = 648 AND `GroupID` = 1;
|
||||
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||
(648, 1, 0, 'NO, NO, NO! Please!', 12, 0, 100, 0, 0, 0, 43230, 0, 'Bridge Worker Trent - Scared'),
|
||||
(648, 1, 1, 'NOOOOOO!!!', 12, 0, 100, 0, 0, 0, 43231, 0, 'Bridge Worker Trent - Scared'),
|
||||
(648, 1, 2, 'ANYWHERE BUT THE BRIDGE!', 12, 0, 100, 0, 0, 0, 43232, 0, 'Bridge Worker Trent - Scared');
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID` = 649 AND `GroupID` = 1;
|
||||
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||
(649, 1, 0, 'NO, NO, NO! Please!', 12, 0, 100, 0, 0, 0, 43230, 0, 'Bridge Worker Dmitri - Scared'),
|
||||
(649, 1, 1, 'NOOOOOO!!!', 12, 0, 100, 0, 0, 0, 43231, 0, 'Bridge Worker Dmitri - Scared'),
|
||||
(649, 1, 2, 'ANYWHERE BUT THE BRIDGE!', 12, 0, 100, 0, 0, 0, 43232, 0, 'Bridge Worker Dmitri - Scared');
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID` = 650 AND `GroupID` = 1;
|
||||
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||
(650, 1, 0, 'NO, NO, NO! Please!', 12, 0, 100, 0, 0, 0, 43230, 0, 'Bridge Worker Jess - Scared'),
|
||||
(650, 1, 1, 'NOOOOOO!!!', 12, 0, 100, 0, 0, 0, 43231, 0, 'Bridge Worker Jess - Scared'),
|
||||
(650, 1, 2, 'ANYWHERE BUT THE BRIDGE!', 12, 0, 100, 0, 0, 0, 43232, 0, 'Bridge Worker Jess - Scared');
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID` = 651 AND `GroupID` = 1;
|
||||
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||
(651, 1, 0, 'NO, NO, NO! Please!', 12, 0, 100, 0, 0, 0, 43230, 0, 'Bridge Worker Daniel - Scared'),
|
||||
(651, 1, 1, 'NOOOOOO!!!', 12, 0, 100, 0, 0, 0, 43231, 0, 'Bridge Worker Daniel - Scared'),
|
||||
(651, 1, 2, 'ANYWHERE BUT THE BRIDGE!', 12, 0, 100, 0, 0, 0, 43232, 0, 'Bridge Worker Daniel - Scared');
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID` = 652 AND `GroupID` = 2;
|
||||
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||
(652, 2, 0, 'NO, NO, NO! Please!', 12, 0, 100, 0, 0, 0, 43230, 0, 'Bridge Worker Matthew - Scared'),
|
||||
(652, 2, 1, 'NOOOOOO!!!', 12, 0, 100, 0, 0, 0, 43231, 0, 'Bridge Worker Matthew - Scared'),
|
||||
(652, 2, 2, 'ANYWHERE BUT THE BRIDGE!', 12, 0, 100, 0, 0, 0, 43232, 0, 'Bridge Worker Matthew - Scared');
|
||||
|
||||
DELETE FROM `creature_text` WHERE `CreatureID` = 653 AND `GroupID` = 5;
|
||||
INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
|
||||
(653, 5, 0, 'NO, NO, NO! Please!', 12, 0, 100, 0, 0, 0, 43230, 0, 'Bridge Worker Alex - Scared'),
|
||||
(653, 5, 1, 'NOOOOOO!!!', 12, 0, 100, 0, 0, 0, 43231, 0, 'Bridge Worker Alex - Scared'),
|
||||
(653, 5, 2, 'ANYWHERE BUT THE BRIDGE!', 12, 0, 100, 0, 0, 0, 43232, 0, 'Bridge Worker Alex - Scared');
|
||||
|
||||
-- Path 1 for Subdued Canyon Ettin
|
||||
SET @ENTRY := 43197;
|
||||
SET @PATHOFFSET := 0;
|
||||
SET @PATH := @ENTRY * 100 + @PATHOFFSET;
|
||||
DELETE FROM `waypoint_path` WHERE `PathId`= @PATH;
|
||||
INSERT INTO `waypoint_path` (`PathId`, `MoveType`, `Flags`, `Velocity`, `Comment`) VALUES
|
||||
(@PATH, 1, 0x0, NULL, 'Subdued Canyon Ettin - Scripted Path - Path To Water');
|
||||
|
||||
DELETE FROM `waypoint_path_node` WHERE `PathId`= @PATH;
|
||||
INSERT INTO `waypoint_path_node` (`PathId`, `NodeId`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `Delay`) VALUES
|
||||
(@PATH, 0, -9270.707, -2299.5933, 69.642654, NULL, 0),
|
||||
(@PATH, 1, -9271.457, -2309.5933, 69.892654, NULL, 0),
|
||||
(@PATH, 2, -9279.707, -2319.0933, 66.892654, NULL, 0),
|
||||
(@PATH, 3, -9303.957, -2330.5933, 61.642654, NULL, 0),
|
||||
(@PATH, 4, -9324.86, -2338.94, 61.2445, 5.0614, 0);
|
||||
|
||||
-- Path 2 for Subdued Canyon Ettin
|
||||
SET @ENTRY := 43197;
|
||||
SET @PATHOFFSET := 1;
|
||||
SET @PATH := @ENTRY * 100 + @PATHOFFSET;
|
||||
DELETE FROM `waypoint_path` WHERE `PathId`= @PATH;
|
||||
INSERT INTO `waypoint_path` (`PathId`, `MoveType`, `Flags`, `Velocity`, `Comment`) VALUES
|
||||
(@PATH, 1, 0x0, NULL, 'Subdued Canyon Ettin - Scripted Path - Path Up Hill');
|
||||
|
||||
DELETE FROM `waypoint_path_node` WHERE `PathId`= @PATH;
|
||||
INSERT INTO `waypoint_path_node` (`PathId`, `NodeId`, `PositionX`, `PositionY`, `PositionZ`, `Orientation`, `Delay`) VALUES
|
||||
(@PATH, 0, -9308.439, -2330.975, 61.716003, NULL, 0),
|
||||
(@PATH, 1, -9292.939, -2325.475, 62.716003, NULL, 0),
|
||||
(@PATH, 2, -9276.939, -2316.725, 68.966, NULL, 0),
|
||||
(@PATH, 3, -9260.689, -2312.725, 75.216, NULL, 0),
|
||||
(@PATH, 4, -9237.689, -2313.225, 78.716, NULL, 0),
|
||||
(@PATH, 5, -9214.52, -2334.01, 83.6875, NULL, 0);
|
||||
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceEntry` IN (80739));
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ConditionStringValue1`, `NegativeCondition`, `Comment`) VALUES
|
||||
(13, 1, 80739, 0, 0, 51, 0, 5, 43196, 0, '', 0, 'Potential target of the spell is TYPEID_UNIT, entry is 43196');
|
||||
|
||||
DELETE FROM `conditions` WHERE (`SourceTypeOrReferenceId` = 13) AND (`SourceEntry` IN (80704));
|
||||
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ConditionStringValue1`, `NegativeCondition`, `Comment`) VALUES
|
||||
(13, 2, 80704, 0, 0, 51, 0, 5, 43197, 0, '', 0, 'Potential target of the spell is TYPEID_UNIT, entry is 43197'),
|
||||
(13, 2, 80704, 0, 0, 33, 0, 1, 3, 0, '', 0, 'Potential target of the spell is TYPEID_UNIT, entry is 43197, if owned by spell caster'),
|
||||
(13, 2, 80704, 0, 1, 51, 0, 5, 43094, 0, '', 0, 'Otherwise, potential target of the spell is TYPEID_UNIT, entry is 43094');
|
||||
@@ -22,17 +22,82 @@ SDComment:
|
||||
Script Data End */
|
||||
|
||||
#include "ScriptMgr.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "Containers.h"
|
||||
#include "G3DPosition.hpp"
|
||||
#include "MotionMaster.h"
|
||||
#include "MoveSplineInit.h"
|
||||
#include "ObjectAccessor.h"
|
||||
#include "Player.h"
|
||||
#include "ScriptedCreature.h"
|
||||
#include "SpellAuras.h"
|
||||
#include "SpellInfo.h"
|
||||
#include "SpellScript.h"
|
||||
#include "TemporarySummon.h"
|
||||
#include "WaypointDefines.h"
|
||||
#include "World.h"
|
||||
#include <algorithm>
|
||||
|
||||
enum DumpyKeeshan
|
||||
enum RedridgeSpellData
|
||||
{
|
||||
NPC_BIGEARL = 43248,
|
||||
SPELL_APPLY_QUEST_INVIS_ZONE_3 = 80815, // Used by npc's in Lakeshire Inn
|
||||
SPELL_APPLY_QUEST_INVIS_ZONE_4 = 80816, // Used by npc's in Lakeshire Inn
|
||||
|
||||
SPELL_APPLY_QUEST_INVIS_ZONE_3 = 80815, // Used by npc's in Lakeshire Inn
|
||||
SPELL_APPLY_QUEST_INVIS_ZONE_4 = 80816 // Used by npc's in Lakeshire Inn
|
||||
SPELL_APPLY_QUEST_INVIS_ZONE_19 = 82099, // Used by npc's in Lakeshire Townhall
|
||||
|
||||
SPELL_CONTROL_ETTIN = 80704,
|
||||
SPELL_CONTROL_ETTIN_2 = 80702,
|
||||
SPELL_LIFT_HUGE_BOULDER = 80739,
|
||||
SPELL_LIFT_BOULDER_RIDE = 82566,
|
||||
SPELL_CANYON_ETTIN_SPAWN_SPELL = 82558,
|
||||
SPELL_BOULDER_AURA = 82556,
|
||||
SPELL_DESPAWN_KILL_CREDIT = 228623,
|
||||
SPELL_EJECT_PASSENGER_1 = 80743,
|
||||
SPELL_CANYON_ETTIN_DESPAWN = 82561,
|
||||
SPELL_DESPAWN_ETTIN = 80707,
|
||||
};
|
||||
|
||||
enum RedridgeCreatureData
|
||||
{
|
||||
NPC_FOREMAN_OSLOW = 341,
|
||||
NPC_BRIDGE_WORKER_ALEX = 653,
|
||||
NPC_BRIDGE_WORKER_TRENT = 648,
|
||||
NPC_BRIDGE_WORKER_DMITRI = 649,
|
||||
NPC_BRIDGE_WORKER_JESS = 650,
|
||||
NPC_BRIDGE_WORKER_DANIEL = 651,
|
||||
NPC_BRIDGE_WORKER_MATTHEW = 652,
|
||||
NPC_CANYON_ETTIN = 43094,
|
||||
NPC_SUBDUED_CANYON_ETTIN = 43197,
|
||||
NPC_HUGE_BOULDER = 43196,
|
||||
|
||||
NPC_BIGEARL = 43248,
|
||||
};
|
||||
|
||||
enum RedridgeTalks
|
||||
{
|
||||
TALK_OSLOW_IDLE = 0,
|
||||
|
||||
TALK_ALEX_HEAVE = 1,
|
||||
TALK_ALEX_DAMN = 2,
|
||||
TALK_ALEX_PUSH = 4,
|
||||
TALK_ALEX_SCARED = 5,
|
||||
|
||||
TALK_WORKERS_HO = 0,
|
||||
|
||||
TALK_MATTHEW_IM_PUSHING = 1,
|
||||
TALK_MATTHEW_SCARED = 2,
|
||||
|
||||
TALK_TRENT_SCARED = 1,
|
||||
|
||||
TALK_DMITRI_SCARED = 1,
|
||||
|
||||
TALK_JESS_SCARED = 1,
|
||||
|
||||
TALK_DANIEL_SCARED = 1,
|
||||
|
||||
TALK_NOT_SO_HEAVY = 0,
|
||||
TALK_WHERE_THROW = 1,
|
||||
TALK_THROW_IN_WATER = 2,
|
||||
TALK_BYE = 3
|
||||
};
|
||||
|
||||
/*######
|
||||
@@ -112,148 +177,513 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/*######
|
||||
# npc_bridge_worker_alex "Used by entry 653" "Script not fully complete. Needs scripting added for move rock will be updated in future."
|
||||
######*/
|
||||
|
||||
enum BridgeWorkerAlex
|
||||
enum RedridgeHugeBoulder
|
||||
{
|
||||
EVENT_STORE_GUIDS = 1,
|
||||
EVENT_OSLOW_SAY = 2,
|
||||
EVENT_ALEX_SAY = 3,
|
||||
EVENT_WORKERS_SAY = 4,
|
||||
EVENT_ALEX_SAY_PUSH = 5,
|
||||
EVENT_MATTHEW_SAY = 6,
|
||||
EVENT_STORE_GUIDS = 1,
|
||||
EVENT_OSLOW_IDLE_TALK = 2,
|
||||
EVENT_ALEX_IDLE_TALK = 3,
|
||||
EVENT_WORKERS_RESPONSE = 4,
|
||||
EVENT_ALEX_SAY_PUSH = 5,
|
||||
EVENT_MATTHEW_PUSH_RESPONSE = 6,
|
||||
EVENT_REPOSITION = 7,
|
||||
EVENT_BRIDGE_WORKERS_COWER = 8,
|
||||
EVENT_OSLOW_GET_UP = 9,
|
||||
EVENT_OSLOW_STUN = 10,
|
||||
EVENT_ETTIN_LINE_1 = 11,
|
||||
EVENT_ETTIN_LINE_2 = 12,
|
||||
EVENT_MOVE_TO_WATER = 13,
|
||||
EVENT_THROW_BOULDER = 14,
|
||||
EVENT_PATH_AWAY = 15,
|
||||
EVENT_DONE,
|
||||
|
||||
NPC_OSLOW = 341,
|
||||
NPC_TRENT = 648,
|
||||
NPC_DIMITRI = 649,
|
||||
NPC_JESS = 650,
|
||||
NPC_DANIEL = 651,
|
||||
NPC_MATTHEW = 652,
|
||||
ACTION_OSLOW_GET_UP = 0,
|
||||
ACTION_COWER = 1,
|
||||
ACTION_DONE,
|
||||
|
||||
SAY_OSLOW = 0,
|
||||
SAY_ALEX_PUT = 0,
|
||||
SAY_ALEX_HEAVE = 1,
|
||||
SAY_ALEX_DAMN = 2,
|
||||
SAY_ALEX_HANGON = 3,
|
||||
SAY_ALEX_PUSH = 4,
|
||||
SAY_WORKERS_HO = 0,
|
||||
SAY_MATTHEW_IM_PUSHING = 1
|
||||
PATH_ETTIN_TO_WATER = 4319700,
|
||||
PATH_ETTIN_UP_HILL = 4319701,
|
||||
|
||||
POINT_NEAR_BOULDER = 1,
|
||||
POINT_NEAR_WATER = 2,
|
||||
POINT_UP_PATH = 3,
|
||||
};
|
||||
|
||||
class npc_bridge_worker_alex : public CreatureScript
|
||||
constexpr Position TrentRepositionPos = { -9281.44f, -2285.27f, 67.5123f, 6.0213f };
|
||||
constexpr Position DmitriRepositionPos = { -9282.8f, -2293.28f, 67.5089f, 6.2657f };
|
||||
constexpr Position JessRepositionPos = { -9282.27f, -2290.95f, 67.5319f, 6.0737f };
|
||||
constexpr Position DanielRepositionPos = { -9281.77f, -2287.55f, 67.5869f, 6.0911f };
|
||||
constexpr Position MatthewRepositionPos = { -9280.71f, -2283.21f, 67.5747f, 6.0737f };
|
||||
constexpr Position AlexRepositionPos = { -9279.86f, -2281.42f, 67.5854f, 5.7421f };
|
||||
|
||||
// 43196 - Huge Boulder
|
||||
struct npc_redridge_huge_boulder : public CreatureAI
|
||||
{
|
||||
public:
|
||||
npc_bridge_worker_alex() : CreatureScript("npc_bridge_worker_alex") { }
|
||||
npc_redridge_huge_boulder(Creature* creature) : CreatureAI(creature) { }
|
||||
|
||||
struct npc_bridge_worker_alexAI : public ScriptedAI
|
||||
void Reset() override
|
||||
{
|
||||
npc_bridge_worker_alexAI(Creature* creature) : ScriptedAI(creature) { }
|
||||
_events.Reset();
|
||||
_oslowGUID.Clear();
|
||||
_alexGUID.Clear();
|
||||
_trentGUID.Clear();
|
||||
_dmitriGUID.Clear();
|
||||
_jessGUID.Clear();
|
||||
_danielGUID.Clear();
|
||||
_matthewGUID.Clear();
|
||||
_events.ScheduleEvent(EVENT_STORE_GUIDS, 5s);
|
||||
}
|
||||
|
||||
void Reset() override
|
||||
void SpellHit(WorldObject* /*caster*/, SpellInfo const* spell) override
|
||||
{
|
||||
if (spell->Id != SPELL_LIFT_BOULDER_RIDE)
|
||||
return;
|
||||
|
||||
_events.Reset();
|
||||
_events.ScheduleEvent(EVENT_REPOSITION, 0ms);
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
_events.Reset();
|
||||
_oslowGUID.Clear();
|
||||
_trentGUID.Clear();
|
||||
_dimitriGUID.Clear();
|
||||
_jessGUID.Clear();
|
||||
_danielGUID.Clear();
|
||||
_matthewGUID.Clear();
|
||||
_events.ScheduleEvent(EVENT_STORE_GUIDS, Seconds(5));
|
||||
_events.ScheduleEvent(EVENT_OSLOW_SAY, Seconds(40), Seconds(50));
|
||||
_events.ScheduleEvent(EVENT_ALEX_SAY, Seconds(22), Seconds(30));
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
switch (eventId)
|
||||
{
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
case EVENT_STORE_GUIDS:
|
||||
{
|
||||
switch (eventId)
|
||||
if (Creature const* oslow = me->FindNearestCreature(NPC_FOREMAN_OSLOW, 10.0f, true))
|
||||
_oslowGUID = oslow->GetGUID();
|
||||
if (Creature const* alex = me->FindNearestCreature(NPC_BRIDGE_WORKER_ALEX, 10.0f, true))
|
||||
_alexGUID = alex->GetGUID();
|
||||
if (Creature const* trent = me->FindNearestCreature(NPC_BRIDGE_WORKER_TRENT, 10.0f, true))
|
||||
_trentGUID = trent->GetGUID();
|
||||
if (Creature const* dimitri = me->FindNearestCreature(NPC_BRIDGE_WORKER_DMITRI, 10.0f, true))
|
||||
_dmitriGUID = dimitri->GetGUID();
|
||||
if (Creature const* jess = me->FindNearestCreature(NPC_BRIDGE_WORKER_JESS, 10.0f, true))
|
||||
_jessGUID = jess->GetGUID();
|
||||
if (Creature const* daniel = me->FindNearestCreature(NPC_BRIDGE_WORKER_DANIEL, 10.0f, true))
|
||||
_danielGUID = daniel->GetGUID();
|
||||
if (Creature const* matthew = me->FindNearestCreature(NPC_BRIDGE_WORKER_MATTHEW, 10.0f, true))
|
||||
_matthewGUID = matthew->GetGUID();
|
||||
|
||||
if (!_oslowGUID || !_alexGUID || !_trentGUID || !_dmitriGUID || !_jessGUID || !_danielGUID || !_matthewGUID)
|
||||
_events.Repeat(1s);
|
||||
else
|
||||
{
|
||||
case EVENT_STORE_GUIDS:
|
||||
if (Creature* oslow = me->FindNearestCreature(NPC_OSLOW, 5.0f, true))
|
||||
_oslowGUID = oslow->GetGUID();
|
||||
if (Creature* trent = me->FindNearestCreature(NPC_TRENT, 5.0f, true))
|
||||
_trentGUID = trent->GetGUID();
|
||||
if (Creature* dimitri = me->FindNearestCreature(NPC_DIMITRI, 5.0f, true))
|
||||
_dimitriGUID = dimitri->GetGUID();
|
||||
if (Creature* jess = me->FindNearestCreature(NPC_JESS, 5.0f, true))
|
||||
_jessGUID = jess->GetGUID();
|
||||
if (Creature* daniel = me->FindNearestCreature(NPC_DANIEL, 5.0f, true))
|
||||
_danielGUID = daniel->GetGUID();
|
||||
if (Creature* matthew = me->FindNearestCreature(NPC_MATTHEW, 5.0f, true))
|
||||
_matthewGUID = matthew->GetGUID();
|
||||
break;
|
||||
case EVENT_OSLOW_SAY:
|
||||
if (Creature* oslow = ObjectAccessor::GetCreature(*me, _oslowGUID))
|
||||
oslow->AI()->Talk(SAY_OSLOW);
|
||||
_events.Repeat(Seconds(40), Seconds(50));
|
||||
break;
|
||||
case EVENT_ALEX_SAY:
|
||||
switch (urand(0, 3))
|
||||
{
|
||||
case 0:
|
||||
Talk(SAY_ALEX_PUT);
|
||||
break;
|
||||
case 1:
|
||||
Talk(SAY_ALEX_HEAVE);
|
||||
_events.ScheduleEvent(EVENT_WORKERS_SAY, Seconds(2));
|
||||
break;
|
||||
case 2:
|
||||
Talk(SAY_ALEX_DAMN);
|
||||
_events.ScheduleEvent(EVENT_ALEX_SAY_PUSH, Seconds(4));
|
||||
break;
|
||||
case 3:
|
||||
Talk(SAY_ALEX_HANGON);
|
||||
break;
|
||||
}
|
||||
_events.Repeat(Seconds(22), Seconds(30));
|
||||
break;
|
||||
case EVENT_WORKERS_SAY:
|
||||
if (Creature* trent = ObjectAccessor::GetCreature(*me, _trentGUID))
|
||||
trent->AI()->Talk(SAY_WORKERS_HO);
|
||||
if (Creature* dimitri = ObjectAccessor::GetCreature(*me, _dimitriGUID))
|
||||
dimitri->AI()->Talk(SAY_WORKERS_HO);
|
||||
if (Creature* jess = ObjectAccessor::GetCreature(*me, _jessGUID))
|
||||
jess->AI()->Talk(SAY_WORKERS_HO);
|
||||
if (Creature* daniel = ObjectAccessor::GetCreature(*me, _danielGUID))
|
||||
daniel->AI()->Talk(SAY_WORKERS_HO);
|
||||
if (Creature* matthew = ObjectAccessor::GetCreature(*me, _matthewGUID))
|
||||
matthew->AI()->Talk(SAY_WORKERS_HO);
|
||||
break;
|
||||
case EVENT_ALEX_SAY_PUSH:
|
||||
Talk(SAY_ALEX_PUSH);
|
||||
_events.ScheduleEvent(EVENT_MATTHEW_SAY, Seconds(4));
|
||||
break;
|
||||
case EVENT_MATTHEW_SAY:
|
||||
if (Creature* matthew = ObjectAccessor::GetCreature(*me, _matthewGUID))
|
||||
matthew->AI()->Talk(SAY_MATTHEW_IM_PUSHING);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
_events.ScheduleEvent(EVENT_OSLOW_IDLE_TALK, 45s, 60s);
|
||||
_events.ScheduleEvent(EVENT_ALEX_IDLE_TALK, 20s, 30s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_OSLOW_IDLE_TALK:
|
||||
{
|
||||
if (Creature const* oslow = ObjectAccessor::GetCreature(*me, _oslowGUID))
|
||||
oslow->AI()->Talk(TALK_OSLOW_IDLE);
|
||||
_events.Repeat(45s, 60s);
|
||||
break;
|
||||
}
|
||||
case EVENT_ALEX_IDLE_TALK:
|
||||
{
|
||||
if (Creature const* alex = ObjectAccessor::GetCreature(*me, _alexGUID))
|
||||
{
|
||||
switch (uint32 text = urand(0, 3))
|
||||
{
|
||||
case TALK_ALEX_HEAVE:
|
||||
alex->AI()->Talk(TALK_ALEX_HEAVE);
|
||||
_events.ScheduleEvent(EVENT_WORKERS_RESPONSE, 1s);
|
||||
break;
|
||||
case TALK_ALEX_DAMN:
|
||||
alex->AI()->Talk(TALK_ALEX_DAMN);
|
||||
_events.ScheduleEvent(EVENT_ALEX_SAY_PUSH, 3s);
|
||||
break;
|
||||
default:
|
||||
alex->AI()->Talk(text);
|
||||
_events.Repeat(10s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_WORKERS_RESPONSE:
|
||||
{
|
||||
if (Creature const* alex = ObjectAccessor::GetCreature(*me, _alexGUID))
|
||||
{
|
||||
if (Creature const* trent = ObjectAccessor::GetCreature(*me, _trentGUID))
|
||||
trent->AI()->Talk(TALK_WORKERS_HO, alex);
|
||||
if (Creature const* dmitri = ObjectAccessor::GetCreature(*me, _dmitriGUID))
|
||||
dmitri->AI()->Talk(TALK_WORKERS_HO, alex);
|
||||
if (Creature const* jess = ObjectAccessor::GetCreature(*me, _jessGUID))
|
||||
jess->AI()->Talk(TALK_WORKERS_HO, alex);
|
||||
if (Creature const* daniel = ObjectAccessor::GetCreature(*me, _danielGUID))
|
||||
daniel->AI()->Talk(TALK_WORKERS_HO, alex);
|
||||
if (Creature const* matthew = ObjectAccessor::GetCreature(*me, _matthewGUID))
|
||||
matthew->AI()->Talk(TALK_WORKERS_HO, alex);
|
||||
}
|
||||
_events.ScheduleEvent(EVENT_ALEX_IDLE_TALK, 20s, 30s);
|
||||
break;
|
||||
}
|
||||
case EVENT_ALEX_SAY_PUSH:
|
||||
{
|
||||
if (Creature const* alex = ObjectAccessor::GetCreature(*me, _alexGUID))
|
||||
alex->AI()->Talk(TALK_ALEX_PUSH);
|
||||
_events.ScheduleEvent(EVENT_MATTHEW_PUSH_RESPONSE, 4s);
|
||||
break;
|
||||
}
|
||||
case EVENT_MATTHEW_PUSH_RESPONSE:
|
||||
{
|
||||
if (Creature const* matthew = ObjectAccessor::GetCreature(*me, _matthewGUID))
|
||||
{
|
||||
if (Creature const* alex = ObjectAccessor::GetCreature(*me, _alexGUID))
|
||||
matthew->AI()->Talk(TALK_MATTHEW_IM_PUSHING, alex);
|
||||
}
|
||||
_events.ScheduleEvent(EVENT_ALEX_IDLE_TALK, 20s, 30s);
|
||||
break;
|
||||
}
|
||||
case EVENT_REPOSITION:
|
||||
{
|
||||
if (Creature* trent = ObjectAccessor::GetCreature(*me, _trentGUID))
|
||||
{
|
||||
trent->SetAIAnimKitId(0);
|
||||
trent->GetMotionMaster()->MovePoint(0, TrentRepositionPos, true, TrentRepositionPos.GetOrientation());
|
||||
}
|
||||
|
||||
if (Creature* dmitri = ObjectAccessor::GetCreature(*me, _dmitriGUID))
|
||||
{
|
||||
dmitri->SetAIAnimKitId(0);
|
||||
dmitri->GetMotionMaster()->MovePoint(0, DmitriRepositionPos, true, DmitriRepositionPos.GetOrientation());
|
||||
}
|
||||
|
||||
if (Creature* jess = ObjectAccessor::GetCreature(*me, _jessGUID))
|
||||
{
|
||||
jess->SetAIAnimKitId(0);
|
||||
jess->GetMotionMaster()->MovePoint(0, JessRepositionPos, true, JessRepositionPos.GetOrientation());
|
||||
}
|
||||
|
||||
if (Creature* daniel = ObjectAccessor::GetCreature(*me, _danielGUID))
|
||||
{
|
||||
daniel->SetAIAnimKitId(0);
|
||||
daniel->GetMotionMaster()->MovePoint(0, DanielRepositionPos, true, DanielRepositionPos.GetOrientation());
|
||||
}
|
||||
|
||||
if (Creature* matthew = ObjectAccessor::GetCreature(*me, _matthewGUID))
|
||||
{
|
||||
matthew->SetAIAnimKitId(0);
|
||||
matthew->GetMotionMaster()->MovePoint(0, MatthewRepositionPos, true, MatthewRepositionPos.GetOrientation());
|
||||
}
|
||||
|
||||
if (Creature* alex = ObjectAccessor::GetCreature(*me, _alexGUID))
|
||||
{
|
||||
alex->SetAIAnimKitId(0);
|
||||
alex->GetMotionMaster()->MovePoint(0, AlexRepositionPos, true, AlexRepositionPos.GetOrientation());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_BRIDGE_WORKERS_COWER:
|
||||
{
|
||||
// all workers should cower
|
||||
std::vector<ObjectGuid> allWorkers = { _alexGUID, _matthewGUID, _trentGUID, _dmitriGUID, _jessGUID, _danielGUID };
|
||||
for (ObjectGuid const& workerGUID : allWorkers)
|
||||
if (Creature* worker = ObjectAccessor::GetCreature(*me, workerGUID))
|
||||
worker->SetEmoteState(EMOTE_STATE_COWER);
|
||||
|
||||
// pick two random workers to say random scared things
|
||||
Trinity::Containers::RandomResize(allWorkers, 2);
|
||||
|
||||
for (ObjectGuid const workerGUID : allWorkers)
|
||||
{
|
||||
Creature* worker = ObjectAccessor::GetCreature(*me, workerGUID);
|
||||
if (!worker)
|
||||
continue;
|
||||
|
||||
switch (worker->GetEntry())
|
||||
{
|
||||
case NPC_BRIDGE_WORKER_ALEX:
|
||||
worker->AI()->Talk(TALK_ALEX_SCARED, me);
|
||||
break;
|
||||
case NPC_BRIDGE_WORKER_MATTHEW:
|
||||
worker->AI()->Talk(TALK_MATTHEW_SCARED, me);
|
||||
break;
|
||||
case NPC_BRIDGE_WORKER_TRENT:
|
||||
worker->AI()->Talk(TALK_TRENT_SCARED, me);
|
||||
break;
|
||||
case NPC_BRIDGE_WORKER_DMITRI:
|
||||
worker->AI()->Talk(TALK_DMITRI_SCARED, me);
|
||||
break;
|
||||
case NPC_BRIDGE_WORKER_JESS:
|
||||
worker->AI()->Talk(TALK_JESS_SCARED, me);
|
||||
break;
|
||||
case NPC_BRIDGE_WORKER_DANIEL:
|
||||
worker->AI()->Talk(TALK_DANIEL_SCARED, me);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EVENT_OSLOW_GET_UP:
|
||||
{
|
||||
if (Creature* oslow = ObjectAccessor::GetCreature(*me, _oslowGUID))
|
||||
oslow->SetStandState(UNIT_STAND_STATE_STAND);
|
||||
|
||||
_events.ScheduleEvent(EVENT_OSLOW_STUN, 2s);
|
||||
break;
|
||||
}
|
||||
case EVENT_OSLOW_STUN:
|
||||
{
|
||||
if (Creature* oslow = ObjectAccessor::GetCreature(*me, _oslowGUID))
|
||||
oslow->SetEmoteState(EMOTE_STATE_STUN);
|
||||
break;
|
||||
}
|
||||
case EVENT_DONE:
|
||||
{
|
||||
if (Creature* alex = ObjectAccessor::GetCreature(*me, _alexGUID))
|
||||
alex->DespawnOrUnsummon();
|
||||
if (Creature* matthew = ObjectAccessor::GetCreature(*me, _matthewGUID))
|
||||
matthew->DespawnOrUnsummon();
|
||||
if (Creature* trent = ObjectAccessor::GetCreature(*me, _trentGUID))
|
||||
trent->DespawnOrUnsummon();
|
||||
if (Creature* dmitri = ObjectAccessor::GetCreature(*me, _dmitriGUID))
|
||||
dmitri->DespawnOrUnsummon();
|
||||
if (Creature* jess = ObjectAccessor::GetCreature(*me, _jessGUID))
|
||||
jess->DespawnOrUnsummon();
|
||||
if (Creature* daniel = ObjectAccessor::GetCreature(*me, _danielGUID))
|
||||
daniel->DespawnOrUnsummon();
|
||||
if (Creature* oslow = ObjectAccessor::GetCreature(*me, _oslowGUID))
|
||||
oslow->DespawnOrUnsummon();
|
||||
|
||||
_events.Reset();
|
||||
me->DespawnOrUnsummon();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
ObjectGuid _oslowGUID;
|
||||
ObjectGuid _trentGUID;
|
||||
ObjectGuid _dimitriGUID;
|
||||
ObjectGuid _jessGUID;
|
||||
ObjectGuid _danielGUID;
|
||||
ObjectGuid _matthewGUID;
|
||||
};
|
||||
|
||||
CreatureAI* GetAI(Creature* creature) const override
|
||||
void DoAction(int32 const param) override
|
||||
{
|
||||
return new npc_bridge_worker_alexAI(creature);
|
||||
switch (param)
|
||||
{
|
||||
case ACTION_OSLOW_GET_UP:
|
||||
_events.ScheduleEvent(EVENT_OSLOW_GET_UP, 500ms);
|
||||
|
||||
// in case player who started event disconnects
|
||||
_events.ScheduleEvent(EVENT_DONE, 120s);
|
||||
break;
|
||||
case ACTION_COWER:
|
||||
_events.ScheduleEvent(EVENT_BRIDGE_WORKERS_COWER, 3s);
|
||||
break;
|
||||
case ACTION_DONE:
|
||||
_events.ScheduleEvent(EVENT_DONE, 0s);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
ObjectGuid _oslowGUID;
|
||||
ObjectGuid _alexGUID;
|
||||
ObjectGuid _trentGUID;
|
||||
ObjectGuid _dmitriGUID;
|
||||
ObjectGuid _jessGUID;
|
||||
ObjectGuid _danielGUID;
|
||||
ObjectGuid _matthewGUID;
|
||||
};
|
||||
|
||||
constexpr Position EttinNearBoulderPosition = { -9272.053f, -2291.7463f, 68.54081f };
|
||||
|
||||
// 43197 - Subdued Canyon Ettin
|
||||
struct npc_redridge_subdued_canyon_ettin : public CreatureAI
|
||||
{
|
||||
npc_redridge_subdued_canyon_ettin(Creature* creature) : CreatureAI(creature) { }
|
||||
|
||||
void Reset() override
|
||||
{
|
||||
me->SetReactState(REACT_PASSIVE);
|
||||
_events.Reset();
|
||||
}
|
||||
|
||||
void OnDespawn() override
|
||||
{
|
||||
Unit* owner = me->GetOwner();
|
||||
if (!owner)
|
||||
return;
|
||||
|
||||
owner->RemoveAurasDueToSpell(SPELL_CANYON_ETTIN_SPAWN_SPELL);
|
||||
}
|
||||
|
||||
void SpellHit(WorldObject* caster, SpellInfo const* spell) override
|
||||
{
|
||||
if (!caster || !caster->IsPlayer())
|
||||
return;
|
||||
|
||||
switch (spell->Id)
|
||||
{
|
||||
case SPELL_BOULDER_AURA:
|
||||
me->GetMotionMaster()->MovePoint(POINT_NEAR_BOULDER, EttinNearBoulderPosition, true, {}, {}, MovementWalkRunSpeedSelectionMode::ForceWalk);
|
||||
break;
|
||||
case SPELL_DESPAWN_KILL_CREDIT:
|
||||
if (Player* player = ObjectAccessor::GetPlayer(*me, caster->GetGUID()))
|
||||
player->RewardPlayerAndGroupAtEvent(NPC_FOREMAN_OSLOW, player);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateAI(uint32 diff) override
|
||||
{
|
||||
_events.Update(diff);
|
||||
|
||||
while (uint32 eventId = _events.ExecuteEvent())
|
||||
{
|
||||
switch (eventId)
|
||||
{
|
||||
case EVENT_ETTIN_LINE_1:
|
||||
Talk(TALK_NOT_SO_HEAVY);
|
||||
_events.ScheduleEvent(EVENT_ETTIN_LINE_2, 3s);
|
||||
break;
|
||||
case EVENT_ETTIN_LINE_2:
|
||||
Talk(TALK_WHERE_THROW);
|
||||
|
||||
if (Creature* boulder = ObjectAccessor::GetCreature(*me, _boulderGUID))
|
||||
boulder->AI()->DoAction(ACTION_COWER);
|
||||
|
||||
_events.ScheduleEvent(EVENT_MOVE_TO_WATER, 9s);
|
||||
break;
|
||||
case EVENT_MOVE_TO_WATER:
|
||||
me->GetMotionMaster()->MovePath(PATH_ETTIN_TO_WATER, false);
|
||||
Talk(TALK_THROW_IN_WATER);
|
||||
break;
|
||||
case EVENT_THROW_BOULDER:
|
||||
me->CastSpell(nullptr, SPELL_EJECT_PASSENGER_1);
|
||||
_events.ScheduleEvent(EVENT_PATH_AWAY, 6s);
|
||||
break;
|
||||
case EVENT_PATH_AWAY:
|
||||
Talk(TALK_BYE);
|
||||
|
||||
if (Creature* boulder = ObjectAccessor::GetCreature(*me, _boulderGUID))
|
||||
boulder->AI()->DoAction(ACTION_DONE);
|
||||
|
||||
me->GetMotionMaster()->MovePath(PATH_ETTIN_UP_HILL, false);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MovementInform(uint32 movementType, uint32 pointId) override
|
||||
{
|
||||
if (movementType != POINT_MOTION_TYPE)
|
||||
return;
|
||||
|
||||
if (pointId == POINT_NEAR_BOULDER)
|
||||
{
|
||||
if (Creature const* boulder = me->FindNearestCreature(NPC_HUGE_BOULDER, 5.0f, true))
|
||||
{
|
||||
_boulderGUID = boulder->GetGUID();
|
||||
me->CastSpell(nullptr, SPELL_LIFT_HUGE_BOULDER, false);
|
||||
|
||||
if (Creature const* daniel = me->FindNearestCreature(NPC_BRIDGE_WORKER_DANIEL, 20.0f, true))
|
||||
me->SetFacingToObject(daniel);
|
||||
|
||||
_events.ScheduleEvent(EVENT_ETTIN_LINE_1, 2500ms);
|
||||
boulder->AI()->DoAction(ACTION_OSLOW_GET_UP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WaypointPathEnded(uint32 /*nodeId*/, uint32 pathId) override
|
||||
{
|
||||
if (pathId == PATH_ETTIN_TO_WATER)
|
||||
{
|
||||
_events.ScheduleEvent(EVENT_THROW_BOULDER, 0s);
|
||||
}
|
||||
else if (pathId == PATH_ETTIN_UP_HILL)
|
||||
{
|
||||
me->CastSpell(nullptr, SPELL_CANYON_ETTIN_DESPAWN);
|
||||
me->CastSpell(nullptr, SPELL_DESPAWN_ETTIN);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
EventMap _events;
|
||||
ObjectGuid _boulderGUID;
|
||||
};
|
||||
|
||||
// 80704 - Control Ettin
|
||||
class spell_redridge_control_ettin : public SpellScript
|
||||
{
|
||||
SpellCastResult CheckCast()
|
||||
{
|
||||
// check for a spawn spell with a valid caster (subdued ettin)
|
||||
Aura const* spawnAura = GetCaster()->GetAura(SPELL_CANYON_ETTIN_SPAWN_SPELL, [](Aura const* aura)
|
||||
{
|
||||
return aura->GetCaster() != nullptr;
|
||||
});
|
||||
|
||||
if (spawnAura != nullptr)
|
||||
{
|
||||
// fail if the subdued ettin is no longer alive
|
||||
if (!spawnAura->GetCaster()->IsAlive())
|
||||
return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
|
||||
}
|
||||
else
|
||||
{
|
||||
// no spawn spell, so require nearby canyon ettin
|
||||
if (!GetCaster()->FindNearestCreature(NPC_CANYON_ETTIN, GetSpellInfo()->GetMaxRange(), true))
|
||||
return SPELL_FAILED_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
return SPELL_CAST_OK;
|
||||
}
|
||||
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/) const
|
||||
{
|
||||
if (Unit const* target = GetHitUnit())
|
||||
{
|
||||
// conditions ensure this ettin is owned by player
|
||||
if (target->GetEntry() == NPC_SUBDUED_CANYON_ETTIN)
|
||||
{
|
||||
GetCaster()->CastSpell(nullptr, SPELL_BOULDER_AURA, false);
|
||||
GetCaster()->CastSpell(nullptr, SPELL_DESPAWN_KILL_CREDIT, false);
|
||||
}
|
||||
else
|
||||
GetCaster()->CastSpell(nullptr, SPELL_CONTROL_ETTIN_2, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnCheckCast += SpellCheckCastFn(spell_redridge_control_ettin::CheckCast);
|
||||
OnEffectHitTarget += SpellEffectFn(spell_redridge_control_ettin::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_DUMMY);
|
||||
}
|
||||
};
|
||||
|
||||
// 80702 - Control Ettin
|
||||
class spell_redridge_control_ettin_2 : public SpellScript
|
||||
{
|
||||
void HandleScriptEffect(SpellEffIndex /*effIndex*/) const
|
||||
{
|
||||
if (Creature* target = GetHitCreature())
|
||||
target->DespawnOrUnsummon();
|
||||
|
||||
// subdued ettin minion casts 82558 to player
|
||||
std::list<TempSummon*> minionList;
|
||||
GetCaster()->GetAllMinionsByEntry(minionList, NPC_SUBDUED_CANYON_ETTIN);
|
||||
if (TempSummon* ettin = minionList.front())
|
||||
ettin->CastSpell(GetCaster(), SPELL_CANYON_ETTIN_SPAWN_SPELL, false);
|
||||
}
|
||||
|
||||
void Register() override
|
||||
{
|
||||
OnEffectHitTarget += SpellEffectFn(spell_redridge_control_ettin_2::HandleScriptEffect, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -270,8 +700,6 @@ enum RedridgeCitizen
|
||||
|
||||
SAY_IN_TOWNHALL = 0, // Used by npc's in Lakeshire Townhall
|
||||
SAY_LEAVE_TOWNHALL = 1, // Used by npc's in Lakeshire Townhall
|
||||
|
||||
SPELL_APPLY_QUEST_INVIS_ZONE_19 = 82099 // Used by npc's in Lakeshire Townhall
|
||||
};
|
||||
|
||||
const Emote EmoteID[6] =
|
||||
@@ -370,6 +798,9 @@ void AddSC_redridge_mountains()
|
||||
{
|
||||
new npc_big_earl();
|
||||
new npc_dumpy_and_keeshan();
|
||||
new npc_bridge_worker_alex();
|
||||
RegisterCreatureAI(npc_redridge_huge_boulder);
|
||||
RegisterCreatureAI(npc_redridge_subdued_canyon_ettin);
|
||||
RegisterSpellScript(spell_redridge_control_ettin);
|
||||
RegisterSpellScript(spell_redridge_control_ettin_2);
|
||||
new npc_redridge_citizen();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user