aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/master/2022_10_10_00_world.sql174
-rw-r--r--src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp992
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp17
3 files changed, 1183 insertions, 0 deletions
diff --git a/sql/updates/world/master/2022_10_10_00_world.sql b/sql/updates/world/master/2022_10_10_00_world.sql
new file mode 100644
index 00000000000..a66c5b0c698
--- /dev/null
+++ b/sql/updates/world/master/2022_10_10_00_world.sql
@@ -0,0 +1,174 @@
+ --
+ --
+ -- Silverpine Forest
+
+SET @CGUID := 395673;
+
+--
+-- Ivar Patch
+
+-- Detect: Quest Invis Zone 2
+DELETE FROM `spell_area` WHERE `spell`=83739 AND `area`=239 AND `quest_start`=27045 AND `aura_spell`=0 AND `racemask`=0 AND `gender`=2;
+INSERT INTO `spell_area` (`spell`, `area`, `quest_start`, `quest_end`, `aura_spell`, `racemask`, `gender`, `flags`, `quest_start_status`, `quest_end_status`) VALUES
+(83739, 239, 27045, 0, 0, 0, 2, 3, 66, 0);
+
+-- Abandoned Outhouse
+UPDATE `gameobject_template` SET `ScriptName` = 'go_silverpine_abandoned_outhouse' WHERE `entry` = 205143;
+
+DELETE FROM `gossip_menu` WHERE `MenuID`=11897 AND `TextID`=16689;
+INSERT INTO `gossip_menu` (`MenuID`, `TextID`, `VerifiedBuild`) VALUES
+(11897, 16689, 45338);
+
+DELETE FROM `gossip_menu_option` WHERE `MenuID`=11897 AND `OptionID`=0;
+INSERT INTO `gossip_menu_option` (`MenuID`, `OptionID`, `OptionNpc`, `OptionText`, `OptionBroadcastTextID`, `OptionNpcFlag`, `Language`, `ActionMenuID`, `ActionPoiID`, `BoxCoded`, `BoxMoney`, `BoxText`, `BoxBroadcastTextID`, `VerifiedBuild`) VALUES
+(11897, 0, 0, 'Yorick, you in there? I\'m ready to do this! Let\'s go!', 44940, 0, 0, 0, 0, 0, 0, NULL, 0, 45338);
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=11897 AND `SourceEntry`=0 AND `SourceId`=0 AND `ElseGroup`=1 AND `ConditionTypeOrReference`=1 AND `ConditionTarget`=0 AND `ConditionValue1`=83751 AND `ConditionValue2`=1 AND `ConditionValue3`=0;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(15, 11897, 0, 0, 1, 1, 0, 83751, 1, 0, 1, 0, 0, '', 'Show gossip option if player doesn\'t have aura 83751');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=15 AND `SourceGroup`=11897 AND `SourceEntry`=0 AND `SourceId`=0 AND `ElseGroup`=1 AND `ConditionTypeOrReference`=9 AND `ConditionTarget`=0 AND `ConditionValue1`=27045 AND `ConditionValue2`=0 AND `ConditionValue3`=0;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(15, 11897, 0, 0, 1, 9, 0, 27045, 0, 0, 0, 0, 0, '', 'Show gossip option if player has taken quest 27045');
+
+-- Deathstalker Rane Yorick
+UPDATE `creature_template` SET `ScriptName` = 'npc_silverpine_deathstalker_rane_yorick' WHERE `entry` = 44882;
+
+DELETE FROM `creature_text` WHERE `CreatureID` = 44882;
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(44882, 0, 0, 'We haven\'t got much time. Crowly will be arriving shortly.', 12, 0, 100, 5, 0, 0, 44951, 5, ''),
+(44882, 1, 0, 'THERE! Hide in the armoire! I\'ll hide in the shadow next to you.', 12, 0, 100, 25, 0, 0, 44955, 5, ''),
+(44882, 2, 0, 'I live... and die... for the Banshee Queen.', 12, 0, 100, 0, 0, 0, 44971, 5, '');
+
+DELETE FROM `waypoint_data` WHERE `id` = 448820;
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(448820, 1, 1300.27, 1190.11, 52.600067, NULL, 0, 0, 0, 0, 0),
+(448820, 2, 1288.52, 1196.86, 52.850067, NULL, 0, 0, 0, 0, 0),
+(448820, 3, 1287.52, 1205.11, 53.100067, NULL, 0, 0, 0, 0, 0),
+(448820, 4, 1294.27, 1207.36, 54.100067, NULL, 0, 0, 0, 0, 0),
+(448820, 5, 1299.27, 1207.86, 54.100067, NULL, 0, 0, 0, 0, 0),
+(448820, 6, 1304.27, 1210.36, 54.100067, NULL, 0, 0, 0, 0, 0),
+(448820, 7, 1304.77, 1217.86, 54.100067, NULL, 0, 0, 0, 0, 0),
+(448820, 8, 1298.52, 1221.36, 54.100067, NULL, 0, 0, 0, 0, 0),
+(448820, 9, 1298.27, 1218.86, 55.100067, NULL, 0, 0, 0, 0, 0),
+(448820, 10, 1298.02, 1216.61, 56.350067, NULL, 0, 0, 0, 0, 0),
+(448820, 11, 1297.27, 1212.86, 58.600067, NULL, 0, 0, 0, 0, 0),
+(448820, 12, 1298.27, 1206.86, 58.600067, NULL, 0, 0, 0, 0, 0),
+(448820, 13, 1307.27, 1206.11, 58.600067, NULL, 0, 0, 0, 0, 0),
+(448820, 14, 1311.27, 1205.86, 58.600067, NULL, 0, 0, 0, 0, 0),
+(448820, 15, 1312.67, 1208.86, 58.5123, NULL, 0, 0, 0, 0, 0);
+
+DELETE FROM `waypoint_data` WHERE `id` = 448821;
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(448821, 1, 1313.435, 1210.425, 58.7561, NULL, 0, 0, 0, 0, 0),
+(448821, 2, 1313.7, 1211.99, 58.4999, 4.564474, 0, 0, 0, 0, 0);
+
+-- Armoire
+UPDATE `creature_template` SET `unit_flags` = 33554440, `VehicleId` = 1055, `ScriptName` = 'npc_silverpine_armoire' WHERE `entry` = 44893;
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceGroup`=1 AND `SourceEntry`=83763 AND `SourceId`=0 AND `ElseGroup`=1 AND `ConditionTypeOrReference`=31 AND `ConditionTarget`=0 AND `ConditionValue1`=3 AND `ConditionValue2`=44883 AND `ConditionValue3`=0;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 83763, 0, 1, 31, 0, 3, 44883, 0, 0, 0, 0, '', 'Armoire Camera - Target Lord Darius Crowley');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceGroup`=1 AND `SourceEntry`=83764 AND `SourceId`=0 AND `ElseGroup`=0 AND `ConditionTypeOrReference`=31 AND `ConditionTarget`=0 AND `ConditionValue1`=3 AND `ConditionValue2`=44884 AND `ConditionValue3`=0;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 83764, 0, 0, 31, 0, 3, 44884, 0, 0, 0, 0, '', 'Armoire Camera - Target Packleader Ivar Bloodfang');
+
+-- Armoire
+UPDATE `creature_template` SET `npcflag` = 16777216 WHERE `entry` = 44894;
+
+DELETE FROM `npc_spellclick_spells` WHERE `npc_entry` = 44894 AND `spell_id` = 83756;
+INSERT INTO `npc_spellclick_spells` (`npc_entry`, `spell_id`, `cast_flags`, `user_type`) VALUES
+(44894, 83756, 1, 0);
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=18 AND `SourceGroup`=44894 AND `SourceEntry`=83756 AND `SourceId`=0 AND `ElseGroup`=0 AND `ConditionTypeOrReference`=47 AND `ConditionTarget`=0 AND `ConditionValue1`=27045 AND `ConditionValue2`=8 AND `ConditionValue3`=0;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(18, 44894, 83756, 0, 0, 47, 0, 27045, 8, 0, 0, 0, 0, '', 'Allow spellclick if quest 27045 is active');
+
+-- Lord Darius Crowley
+UPDATE `creature_template` SET `unit_flags` = 2, `unit_flags2` = 16384, `ScriptName` = 'npc_silverpine_lord_darius_crowley_exsanguinate' WHERE `entry` = 44883;
+
+DELETE FROM `creature_text` WHERE `CreatureID` = 44883;
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(44883, 0, 0, 'Have you given any more thought to my proposal, Ivar?', 12, 0, 100, 6, 0, 0, 44957, 5, ''),
+(44883, 1, 0, 'If we\'re to win this war we will need your help. Our packs must unite! The Forsaken will destroy us otherwise.', 12, 0, 100, 396, 0, 0, 44960, 5, ''),
+(44883, 2, 0, 'You are the alpha male, Ivar. The rest of the ferals in Silverpine will do as you command.', 12, 0, 100, 397, 0, 0, 44961, 5, ''),
+(44883, 3, 0, 'So will you help?', 12, 0, 100, 6, 0, 0, 44965, 5, '');
+
+DELETE FROM `waypoint_data` WHERE `id` = 448830;
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(448830, 0, 1299.36, 1206.64, 58.5706, NULL, 0, 0, 0, 0, 0),
+(448830, 1, 1300.36, 1206.64, 58.5706, NULL, 0, 0, 0, 0, 0),
+(448830, 2, 1302.33, 1206.44, 58.499, NULL, 0, 0, 0, 0, 0),
+(448830, 3, 1305.32, 1206.43, 58.5126, NULL, 0, 0, 0, 0, 0),
+(448830, 4, 1313.48, 1206.09, 58.5119, NULL, 0, 0, 0, 0, 0);
+
+DELETE FROM `waypoint_data` WHERE `id` = 448831;
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(448831, 0, 1310.28, 1206.0249, 58.76205, NULL, 0, 0, 0, 0, 0),
+(448831, 1, 1305.58, 1206.46, 58.5122, NULL, 0, 0, 0, 0, 0);
+
+ -- Packleader Ivar Bloodfang
+UPDATE `creature_template` SET `unit_flags` = 2, `unit_flags2` = 16384, `VehicleId` = 1059, `ScriptName` = 'npc_silverpine_packleader_ivar_bloodfang_exsanguinate' WHERE `entry` = 44884;
+
+DELETE FROM `creature_text` WHERE `CreatureID` = 44884;
+INSERT INTO `creature_text` (`CreatureID`, `GroupID`, `ID`, `Text`, `Type`, `Language`, `Probability`, `Emote`, `Duration`, `Sound`, `BroadcastTextId`, `TextRange`, `comment`) VALUES
+(44884, 0, 0, 'Why trust you now, Crowley? You abandoned us. Left us to die.', 12, 0, 100, 6, 0, 0, 44959, 5, ''),
+(44884, 1, 0, 'I don\'t care about your war, Crowley.', 12, 0, 100, 274, 0, 0, 44962, 5, ''),
+(44884, 2, 0, 'But...', 12, 0, 100, 1, 0, 0, 44963, 5, ''),
+(44884, 3, 0, 'I have seen firsthand what the Forsaken are capable of doing. It is true. They hunt us... slaughter the defenseless.', 12, 0, 100, 1, 0, 0, 44964, 5, ''),
+(44884, 4, 0, 'Aye, I will gather my pack... we...', 12, 0, 100, 1, 0, 0, 44966, 5, ''),
+(44884, 5, 0, 'Packleader Ivar Bloodfang sniffs the air.', 16, 0, 100, 479, 0, 0, 44967, 5, ''),
+(44884, 6, 0, 'It would appear that we are being watched, Crowley. You have grown soft... Likely Greymane\'s fault.', 12, 0, 100, 1, 0, 0, 44968, 5, ''),
+(44884, 7, 0, 'Treacherous little pup!', 12, 0, 100, 15, 0, 0, 44969, 5, ''),
+(44884, 8, 0, 'What say you now, spy?', 12, 0, 100, 0, 0, 0, 44970, 5, ''),
+(44884, 9, 0, 'I was hoping you\'d say that...', 12, 0, 100, 0, 0, 0, 44972, 5, ''),
+(44884, 10, 0, 'I will prepare the pack. It will take some time to gather them all, but we will join... for now.', 12, 0, 100, 1, 0, 0, 44973, 5, '');
+
+DELETE FROM `spell_script_names` WHERE `spell_id` = 83781 AND `ScriptName` = 'spell_gen_reverse_cast_target_to_caster_triggered';
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(83781, 'spell_gen_reverse_cast_target_to_caster_triggered');
+
+DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=13 AND `SourceGroup`=1 AND `SourceEntry`=83781 AND `SourceId`=0 AND `ElseGroup`=0 AND `ConditionTypeOrReference`=31 AND `ConditionTarget`=0 AND `ConditionValue1`=3 AND `ConditionValue2`=44882 AND `ConditionValue3`=0;
+INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorType`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
+(13, 1, 83781, 0, 0, 31, 0, 3, 44882, 0, 0, 0, 0, '', 'Reverse Cast Ride Vehicle - Target Deathstalker Rane Yorick');
+
+DELETE FROM `spell_script_names` WHERE `spell_id` = 80743 AND `ScriptName` = 'spell_gen_eject_passenger_1';
+INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES
+(80743, 'spell_gen_eject_passenger_1');
+
+DELETE FROM `vehicle_seat_addon` WHERE `SeatEntry`=8420;
+INSERT INTO `vehicle_seat_addon` (`SeatEntry`, `SeatOrientation`, `ExitParamX`, `ExitParamY`, `ExitParamZ`, `ExitParamO`, `ExitParamValue`) VALUES
+(8420, 1, 1311.91, 1207.39, 58.477764, 1.5707, 2);
+
+DELETE FROM `waypoint_data` WHERE `id`= 448840;
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(448840, 0, 1296.2, 1210.54, 58.5533, NULL, 0, 0, 0, 0, 0),
+(448840, 1, 1297.2, 1210.54, 58.5533, NULL, 0, 0, 0, 0, 0),
+(448840, 2, 1302.31, 1206.61, 58.4984, NULL, 0, 0, 0, 0, 0),
+(448840, 3, 1308.4, 1206.28, 58.5109, NULL, 0, 0, 0, 0, 0);
+
+DELETE FROM `waypoint_data` WHERE `id`= 448841;
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(448841, 0, 1312.585, 1209.135, 58.7603, NULL, 0, 0, 0, 0, 0),
+(448841, 1, 1313.18, 1210.32, 58.5093, NULL, 0, 0, 0, 0, 0);
+
+DELETE FROM `waypoint_data` WHERE `id`= 448842;
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(448842, 0, 1311.25, 1208.875, 58.7602, NULL, 0, 0, 0, 0, 0),
+(448842, 1, 1309.32, 1206.43, 58.5111, NULL, 0, 0, 0, 0, 0);
+
+DELETE FROM `waypoint_data` WHERE `id`= 448843;
+INSERT INTO `waypoint_data` (`id`, `point`, `position_x`, `position_y`, `position_z`, `orientation`, `delay`, `move_type`, `action`, `action_chance`, `wpguid`) VALUES
+(448843, 0, 1304.2949, 1207.105, 58.760803, NULL, 0, 0, 0, 0, 0),
+(448843, 1, 1299.0449, 1209.605, 58.760803, NULL, 0, 0, 0, 0, 0),
+(448843, 2, 1297.27, 1212.28, 58.5105, NULL, 0, 0, 0, 0, 0);
+
+-- Deathstalker Rane Yorick (44848)
+DELETE FROM `creature` WHERE `guid`=@CGUID+0;
+INSERT INTO `creature` (`guid`, `id`, `map`, `zoneId`, `areaId`, `spawnDifficulties`, `phaseUseFlags`, `PhaseId`, `PhaseGroup`, `terrainSwapMap`, `modelid`, `equipment_id`, `position_x`, `position_y`, `position_z`, `orientation`, `spawntimesecs`, `wander_distance`, `currentwaypoint`, `curhealth`, `curmana`, `MovementType`, `npcflag`, `unit_flags`, `unit_flags2`, `unit_flags3`, `dynamicflags`, `ScriptName`, `VerifiedBuild`) VALUES
+(@CGUID+0, 44899, 0, 130, 239, '0', 0, 169, 0, -1, 0, 1, 1295.52, 1206.65, 58.5013, 0.023232, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 45338);
+
+DELETE FROM `creature_template_addon` WHERE `entry`=44899;
+INSERT INTO `creature_template_addon` (`entry`, `path_id`, `mount`, `MountCreatureID`, `bytes1`, `bytes2`, `emote`, `aiAnimKit`, `movementAnimKit`, `meleeAnimKit`, `visibilityDistanceType`, `auras`) VALUES
+(44899, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, '83738 29266');
diff --git a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp
index bb68b4f25e2..2b381c85c73 100644
--- a/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp
+++ b/src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp
@@ -1596,6 +1596,990 @@ private:
ObjectGuid _playerGUID;
};
+enum AbandonedOuthouse
+{
+ QUEST_WAITING_TO_EXSANGUINATE = 27045,
+
+ SPELL_SUMMON_DEATHSTALKER_YORICK = 83751
+};
+
+// 205143 - Abandoned Outhouse
+struct go_silverpine_abandoned_outhouse : public GameObjectAI
+{
+ go_silverpine_abandoned_outhouse(GameObject* go) : GameObjectAI(go) { }
+
+ void OnQuestAccept(Player* player, Quest const* quest) override
+ {
+ if (quest->GetQuestId() == QUEST_WAITING_TO_EXSANGUINATE)
+ player->CastSpell(player, SPELL_SUMMON_DEATHSTALKER_YORICK, true);
+ }
+
+ bool OnGossipSelect(Player* player, uint32 /*menuId*/, uint32 /*gossipListId*/) override
+ {
+ player->CastSpell(player, SPELL_SUMMON_DEATHSTALKER_YORICK, true);
+ CloseGossipMenuFor(player);
+ return false;
+ }
+};
+
+Position const YorickReadyPosition = { 1313.7f, 1211.99f, 58.5f, 4.564474f };
+
+Position const YorickDeathPosition = { 1295.52f, 1206.58f, 58.501f };
+
+enum DeathstalkerRaneYorick
+{
+ PHASE_WAITING_TO_EXSANGUINATE = 265,
+
+ NPC_ARMOIRE_SUMMONED = 44893,
+ NPC_PACKLEADER_IVAR_BLOODFANG = 44884,
+
+ SPELL_STEALTH = 34189,
+ SPELL_PERMANENT_FEIGN_DEATH = 29266,
+ SPELL_HIDDEN_IN_ARMOIRE = 83788,
+ SPELL_SUMMON_YORICK = 83751,
+ SPELL_CANCEL_SUMMON_YORICK = 83755,
+
+ EVENT_START_QUEST_EXSANGUINATE = 1,
+ EVENT_WAIT_FOR_PLAYER_EXSANGUINATE = 3,
+ EVENT_RANE_HIDE = 4,
+ EVENT_SET_GUID_FOR_ARMOIRE = 5,
+ EVENT_RANE_TALK_TO_PLAYER = 6,
+ EVENT_RANE_LAST_MOVE = 7,
+
+ ACTION_RANE_JUMP_DEATH = 1,
+ ACTION_RANE_SKIP_PATH = 2,
+
+ TALK_YORICK_EXSANGUINATE_SUMMON = 0,
+ TALK_YORICK_EXSANGUINATE_HIDE = 1,
+
+ PATH_YORICK_UP = 448820,
+ PATH_YORICK_HIDE = 448821,
+
+ WAYPOINT_CLOSE_TO_ARMOIRE = 15,
+ WAYPOINT_HIDDEN_NEXT_TO_ARMOIRE = 2
+};
+
+// 44882 - Deathstalker Rane Yorick
+struct npc_silverpine_deathstalker_rane_yorick : public ScriptedAI
+{
+ npc_silverpine_deathstalker_rane_yorick(Creature* creature) : ScriptedAI(creature), _playerArrived(false), _playerSkipped(false) { }
+
+ void JustAppeared() override
+ {
+ me->SetPowerType(POWER_ENERGY);
+ me->SetMaxPower(POWER_ENERGY, 100);
+ me->SetPower(POWER_ENERGY, 100, true);
+ }
+
+ void IsSummonedBy(WorldObject* summoner) override
+ {
+ me->SetFacingToObject(summoner);
+
+ _events.ScheduleEvent(EVENT_START_QUEST_EXSANGUINATE, 1s);
+ }
+
+ void WaypointReached(uint32 waypointId, uint32 pathId) override
+ {
+ if (pathId == PATH_YORICK_UP && waypointId == WAYPOINT_CLOSE_TO_ARMOIRE)
+ _events.ScheduleEvent(EVENT_WAIT_FOR_PLAYER_EXSANGUINATE, 1s);
+
+ if (pathId == PATH_YORICK_HIDE && waypointId == WAYPOINT_HIDDEN_NEXT_TO_ARMOIRE)
+ {
+ me->SetFacingTo(4.6425757f);
+
+ DoCastSelf(SPELL_STEALTH);
+
+ me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+
+ _playerSkipped = true;
+ }
+ }
+
+ void DoAction(int32 param) override
+ {
+ switch (param)
+ {
+ case ACTION_RANE_JUMP_DEATH:
+ me->SetDisableGravity(true);
+ _events.ScheduleEvent(EVENT_RANE_LAST_MOVE, 10ms);
+ break;
+
+ case ACTION_RANE_SKIP_PATH:
+ {
+ me->PauseMovement();
+
+ me->GetMotionMaster()->Clear();
+
+ me->NearTeleportTo(YorickReadyPosition, false);
+
+ _events.Reset();
+
+ _events.ScheduleEvent(EVENT_SET_GUID_FOR_ARMOIRE, 1s);
+
+ DoCastSelf(SPELL_STEALTH);
+
+ me->SetUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ TempSummon* tempSummon = me->ToTempSummon();
+ if (!tempSummon)
+ return;
+
+ _events.Update(diff);
+
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (!summoner->HasAura(SPELL_SUMMON_YORICK))
+ me->DespawnOrUnsummon();
+ }
+
+ if (!_playerSkipped)
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (summoner->HasAura(SPELL_HIDDEN_IN_ARMOIRE))
+ {
+ _playerSkipped = true;
+
+ DoAction(ACTION_RANE_SKIP_PATH);
+ }
+ }
+ }
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_START_QUEST_EXSANGUINATE:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ Talk(TALK_YORICK_EXSANGUINATE_SUMMON, summoner);
+
+ _events.ScheduleEvent(EVENT_START_QUEST_EXSANGUINATE + 1, 1s + 500ms);
+ }
+ break;
+ }
+
+ case EVENT_START_QUEST_EXSANGUINATE + 1:
+ me->GetMotionMaster()->MovePath(PATH_YORICK_UP, false);
+ break;
+
+ case EVENT_WAIT_FOR_PLAYER_EXSANGUINATE:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (summoner->GetDistance2d(me) <= 5.0f && !_playerArrived)
+ {
+ _events.ScheduleEvent(EVENT_RANE_TALK_TO_PLAYER, 1s);
+ _playerArrived = true;
+ }
+ else
+ _events.ScheduleEvent(EVENT_WAIT_FOR_PLAYER_EXSANGUINATE, 1s);
+ }
+ break;
+ }
+
+ case EVENT_RANE_TALK_TO_PLAYER:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ Talk(TALK_YORICK_EXSANGUINATE_HIDE, summoner);
+
+ _events.ScheduleEvent(EVENT_RANE_HIDE, 3s);
+ _events.ScheduleEvent(EVENT_SET_GUID_FOR_ARMOIRE, 1s);
+ }
+ break;
+ }
+
+ case EVENT_RANE_HIDE:
+ me->GetMotionMaster()->MovePath(PATH_YORICK_HIDE, false);
+ break;
+
+ case EVENT_SET_GUID_FOR_ARMOIRE:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (!_bloodfangGUID)
+ {
+ if (Creature* bloodfang = me->FindNearestCreature(NPC_PACKLEADER_IVAR_BLOODFANG, 30.0f))
+ {
+ if (bloodfang->GetOwnerGUID() == summoner->GetGUID())
+ _bloodfangGUID = bloodfang->GetGUID();
+ }
+ }
+
+ if (!_armoireGUID)
+ {
+ if (Creature* armoire = me->FindNearestCreature(NPC_ARMOIRE_SUMMONED, 30.0f))
+ {
+ if (armoire->GetOwnerGUID() == summoner->GetGUID())
+ {
+ _armoireGUID = armoire->GetGUID();
+
+ if (armoire->IsAIEnabled())
+ armoire->GetAI()->SetGUID(me->GetGUID(), me->GetEntry());
+ }
+ }
+ }
+ }
+
+ if (!_bloodfangGUID || !_armoireGUID)
+ _events.ScheduleEvent(EVENT_SET_GUID_FOR_ARMOIRE, 1s);
+ break;
+ }
+
+ case EVENT_RANE_LAST_MOVE:
+ me->GetMotionMaster()->MoveJump(YorickDeathPosition, 10.0f, 10.0f);
+ DoCastSelf(SPELL_PERMANENT_FEIGN_DEATH);
+ _events.ScheduleEvent(EVENT_RANE_LAST_MOVE + 1, 2s);
+ break;
+
+ case EVENT_RANE_LAST_MOVE + 1:
+ me->SetDisableGravity(false);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+private:
+ EventMap _events;
+ ObjectGuid _armoireGUID;
+ ObjectGuid _bloodfangGUID;
+ bool _playerArrived;
+ bool _playerSkipped;
+};
+
+enum WaitingToExsanguinate
+{
+ NPC_DEATHSTALKER_RANE_YORICK = 44882,
+ NPC_LORD_DARIUS_CROWLEY = 44883,
+
+ SPELL_SUMMON_CROWLEY_BLOODFANG_MASTER = 83762,
+ SPELL_ARMOIRE_CAMERA_ON_CROWLEY = 83763,
+ SPELL_ARMOIRE_CAMERA_ON_BLOODFANG = 83764,
+ SPELL_RIDE_REVERSE_CAST_EXSANGUINATE = 83781,
+ SPELL_EJECT_PASSENGER_01 = 80743,
+ SPELL_KILL_CREDIT_YORICK = 83786,
+ SPELL_HIDE_IN_ARMOIRE = 83788,
+
+ EVENT_START_SCENE_EXSANGUINATE = 1,
+ EVENT_TALK_SCENE_EXSANGUINATE = 4,
+ EVENT_ACTION_SCENE_EXSANGUINATE = 27,
+ EVENT_SWITCH_SCENE_CAMERA = 33,
+ EVENT_FINISH_SCENE_EXSANGUINATE = 40,
+
+ TALK_YORICK_EXSANGUINATE_DEATH = 2,
+ TALK_CROWLEY_EXSANGUINATE_0 = 0,
+ TALK_CROWLEY_EXSANGUINATE_1 = 1,
+ TALK_CROWLEY_EXSANGUINATE_2 = 2,
+ TALK_CROWLEY_EXSANGUINATE_3 = 3,
+ TALK_CROWLEY_EXSANGUINATE_4 = 4,
+ TALK_CROWLEY_EXSANGUINATE_5 = 5,
+ TALK_CROWLEY_EXSANGUINATE_6 = 6,
+ TALK_BLOODFANG_EXSANGUINATE_0 = 0,
+ TALK_BLOODFANG_EXSANGUINATE_1 = 1,
+ TALK_BLOODFANG_EXSANGUINATE_2 = 2,
+ TALK_BLOODFANG_EXSANGUINATE_3 = 3,
+ TALK_BLOODFANG_EXSANGUINATE_4 = 4,
+ TALK_BLOODFANG_EXSANGUINATE_5 = 5,
+ TALK_BLOODFANG_EXSANGUINATE_6 = 6,
+ TALK_BLOODFANG_EXSANGUINATE_7 = 7,
+ TALK_BLOODFANG_EXSANGUINATE_8 = 8,
+ TALK_BLOODFANG_EXSANGUINATE_9 = 9,
+ TALK_BLOODFANG_EXSANGUINATE_10 = 10,
+
+ PATH_CROWLEY_ENTER = 448830,
+ PATH_BLOODFANG_ENTER = 448840,
+ PATH_BLOODFANG_NEAR_YORICK = 448841,
+ PATH_BLOODFANG_WITH_YORICK = 448842,
+ PATH_BLOODFANG_EXIT = 448843,
+ PATH_CROWLEY_EXIT = 448831
+};
+
+// 44893 - Armoire
+struct npc_silverpine_armoire : public VehicleAI
+{
+ npc_silverpine_armoire(Creature* creature) : VehicleAI(creature) { }
+
+ void PassengerBoarded(Unit* passenger, int8 /*seatId*/, bool apply) override
+ {
+ if (apply)
+ {
+ if (Player* player = passenger->ToPlayer())
+ {
+ if (player->GetQuestStatus(QUEST_WAITING_TO_EXSANGUINATE) == QUEST_STATUS_INCOMPLETE)
+ _events.ScheduleEvent(EVENT_START_SCENE_EXSANGUINATE, 400ms);
+ }
+ }
+ else
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ crowley->DespawnOrUnsummon();
+
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ bloodfang->DespawnOrUnsummon();
+
+ if (Creature* yorick = ObjectAccessor::GetCreature(*me, _yorickGUID))
+ yorick->CastSpell(nullptr, SPELL_CANCEL_SUMMON_YORICK, true);
+
+ me->DespawnOrUnsummon(1s);
+ }
+ }
+
+ void SetGUID(ObjectGuid const& guid, int32 id) override
+ {
+ switch (id)
+ {
+ case NPC_DEATHSTALKER_RANE_YORICK:
+ _yorickGUID = guid;
+ break;
+
+ case NPC_LORD_DARIUS_CROWLEY:
+ _crowleyGUID = guid;
+ break;
+
+ case NPC_PACKLEADER_IVAR_BLOODFANG:
+ _bloodfangGUID = guid;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ void UpdateAI(uint32 diff) override
+ {
+ TempSummon* tempSummon = me->ToTempSummon();
+ if (!tempSummon)
+ return;
+
+ _events.Update(diff);
+
+ while (uint32 eventId = _events.ExecuteEvent())
+ {
+ switch (eventId)
+ {
+ case EVENT_START_SCENE_EXSANGUINATE:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ summoner->CastSpell(summoner, SPELL_SUMMON_CROWLEY_BLOODFANG_MASTER, true);
+
+ _events.ScheduleEvent(EVENT_START_SCENE_EXSANGUINATE + 1, 100ms);
+ }
+ break;
+ }
+
+ case EVENT_START_SCENE_EXSANGUINATE + 1:
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ {
+ crowley->GetMotionMaster()->MovePath(PATH_CROWLEY_ENTER, false);
+
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->GetMotionMaster()->MovePath(PATH_BLOODFANG_ENTER, false);
+
+ _events.ScheduleEvent(EVENT_START_SCENE_EXSANGUINATE + 2, 7s);
+ }
+ }
+ break;
+ }
+
+ case EVENT_START_SCENE_EXSANGUINATE + 2:
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ crowley->SetFacingToObject(bloodfang);
+
+ bloodfang->SetFacingToObject(crowley);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE, 2s);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ {
+ if (crowley->IsAIEnabled())
+ crowley->AI()->Talk(TALK_CROWLEY_EXSANGUINATE_0, summoner);
+
+ _events.ScheduleEvent(EVENT_SWITCH_SCENE_CAMERA, 3s + 900ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_SWITCH_SCENE_CAMERA:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_BLOODFANG, true);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 1, 2s + 500ms);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 1:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_0, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 2, 3s + 100ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 2:
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->HandleEmoteCommand(EMOTE_ONESHOT_POINT);
+
+ _events.ScheduleEvent(EVENT_SWITCH_SCENE_CAMERA + 1, 4s + 800ms);
+ }
+ break;
+ }
+
+ case EVENT_SWITCH_SCENE_CAMERA + 1:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_CROWLEY, true);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 3, 2s + 500ms);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 3:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ {
+ if (crowley->IsAIEnabled())
+ crowley->AI()->Talk(TALK_CROWLEY_EXSANGUINATE_1, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 4, 3s + 500ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 4:
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ {
+ crowley->HandleEmoteCommand(EMOTE_ONESHOT_EXCLAMATION);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 5, 5s + 400ms);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 5:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ {
+ if (crowley->IsAIEnabled())
+ crowley->AI()->Talk(TALK_CROWLEY_EXSANGUINATE_2, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 6, 3s + 100ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 6:
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ {
+ crowley->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
+
+ _events.ScheduleEvent(EVENT_SWITCH_SCENE_CAMERA + 2, 3s + 550ms);
+ }
+ break;
+ }
+
+ case EVENT_SWITCH_SCENE_CAMERA + 2:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_BLOODFANG, true);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 7, 2s + 500ms);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 7:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_1, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 8, 3s + 800ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 8:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_2, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 9, 2s + 400ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 9:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_3, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 10, 3s + 900ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 10:
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
+
+ _events.ScheduleEvent(EVENT_SWITCH_SCENE_CAMERA + 3, 4s + 450ms);
+ }
+ break;
+ }
+
+ case EVENT_SWITCH_SCENE_CAMERA + 3:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_CROWLEY, true);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 11, 3s);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 11:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ {
+ if (crowley->IsAIEnabled())
+ crowley->AI()->Talk(TALK_CROWLEY_EXSANGUINATE_3, summoner);
+
+ _events.ScheduleEvent(EVENT_SWITCH_SCENE_CAMERA + 4, 1s + 900ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_SWITCH_SCENE_CAMERA + 4:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_BLOODFANG, true);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 12, 2s + 500ms);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 12:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_4, summoner);
+
+ _events.ScheduleEvent(EVENT_ACTION_SCENE_EXSANGUINATE, 2s + 300ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_ACTION_SCENE_EXSANGUINATE:
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->SetFacingTo(0.6457718f);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 13, 1s + 300ms);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 13:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_5, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 14, 4s);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 14:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_6, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 15, 3s + 500ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 15:
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->HandleEmoteCommand(EMOTE_ONESHOT_YES);
+
+ _events.ScheduleEvent(EVENT_ACTION_SCENE_EXSANGUINATE + 1, 2s + 800ms);
+ }
+ break;
+ }
+
+ case EVENT_ACTION_SCENE_EXSANGUINATE + 1:
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->GetMotionMaster()->MovePath(PATH_BLOODFANG_NEAR_YORICK, false);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 16, 3s);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 16:
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->HandleEmoteCommand(EMOTE_ONESHOT_ROAR);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 17, 200ms);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 17:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_7, summoner);
+
+ _events.ScheduleEvent(EVENT_ACTION_SCENE_EXSANGUINATE + 2, 2s + 300ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_ACTION_SCENE_EXSANGUINATE + 2:
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (Creature* yorick = ObjectAccessor::GetCreature(*me, _yorickGUID))
+ {
+ yorick->RemoveAura(SPELL_STEALTH);
+
+ yorick->RemoveUnitFlag(UNIT_FLAG_UNINTERACTIBLE);
+
+ bloodfang->CastSpell(yorick, SPELL_RIDE_REVERSE_CAST_EXSANGUINATE, true);
+
+ _events.ScheduleEvent(EVENT_ACTION_SCENE_EXSANGUINATE + 3, 1s + 100ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_ACTION_SCENE_EXSANGUINATE + 3:
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->GetMotionMaster()->MovePath(PATH_BLOODFANG_WITH_YORICK, false);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 18, 3s);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 18:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->SetFacingTo(3.054326f);
+
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_8, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 19, 3s + 600ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 19:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* yorick = ObjectAccessor::GetCreature(*me, _yorickGUID))
+ {
+ if (yorick->IsAIEnabled())
+ yorick->AI()->Talk(TALK_YORICK_EXSANGUINATE_DEATH, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 20, 4s + 850ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 20:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (Creature* yorick = ObjectAccessor::GetCreature(*me, _yorickGUID))
+ {
+ bloodfang->CastSpell(yorick, SPELL_EJECT_PASSENGER_01, false);
+
+ if (yorick->IsAIEnabled())
+ yorick->AI()->DoAction(ACTION_RANE_JUMP_DEATH);
+
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_9, summoner);
+
+ _events.ScheduleEvent(EVENT_ACTION_SCENE_EXSANGUINATE + 4, 3s + 600ms);
+ }
+ }
+ }
+ break;
+ }
+
+ case EVENT_ACTION_SCENE_EXSANGUINATE + 4:
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->SetFacingTo(0.0f);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 21, 1s + 100ms);
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 21:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ if (bloodfang->IsAIEnabled())
+ bloodfang->AI()->Talk(TALK_BLOODFANG_EXSANGUINATE_10, summoner);
+
+ _events.ScheduleEvent(EVENT_TALK_SCENE_EXSANGUINATE + 22, 4s + 100ms);
+ }
+ }
+ break;
+ }
+
+ case EVENT_TALK_SCENE_EXSANGUINATE + 22:
+ {
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->HandleEmoteCommand(EMOTE_ONESHOT_TALK);
+
+ _events.ScheduleEvent(EVENT_SWITCH_SCENE_CAMERA + 5, 3s + 250ms);
+ }
+ break;
+ }
+
+ case EVENT_SWITCH_SCENE_CAMERA + 5:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ summoner->CastSpell(nullptr, SPELL_ARMOIRE_CAMERA_ON_CROWLEY, true);
+
+ if (Creature* bloodfang = ObjectAccessor::GetCreature(*me, _bloodfangGUID))
+ {
+ bloodfang->SetWalk(false);
+ bloodfang->GetMotionMaster()->MovePath(PATH_BLOODFANG_EXIT, false);
+
+ _events.ScheduleEvent(EVENT_ACTION_SCENE_EXSANGUINATE + 5, 3s);
+ }
+ }
+ break;
+ }
+
+ case EVENT_ACTION_SCENE_EXSANGUINATE + 5:
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ {
+ crowley->GetMotionMaster()->MovePath(PATH_CROWLEY_EXIT, false);
+
+ _events.ScheduleEvent(EVENT_FINISH_SCENE_EXSANGUINATE, 4s);
+ }
+ break;
+ }
+
+ case EVENT_FINISH_SCENE_EXSANGUINATE:
+ {
+ if (Unit* summoner = tempSummon->GetSummonerUnit())
+ {
+ if (Creature* crowley = ObjectAccessor::GetCreature(*me, _crowleyGUID))
+ crowley->CastSpell(summoner, SPELL_KILL_CREDIT_YORICK, false);
+
+ if (Creature* yorick = ObjectAccessor::GetCreature(*me, _yorickGUID))
+ yorick->CastSpell(summoner, SPELL_CANCEL_SUMMON_YORICK, true);
+
+ summoner->GetMotionMaster()->Clear();
+
+ summoner->RemoveAura(SPELL_HIDE_IN_ARMOIRE);
+
+ summoner->ExitVehicle();
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+ }
+ }
+
+private:
+ EventMap _events;
+ ObjectGuid _yorickGUID;
+ ObjectGuid _crowleyGUID;
+ ObjectGuid _bloodfangGUID;
+};
+
+enum DariusCrowleyExsanguinate
+{
+ WAYPOINT_ON_CROWLEY_DESPAWN = 2
+};
+
+// 44883 - Lord Darius Crowley
+struct npc_silverpine_lord_darius_crowley_exsanguinate : public ScriptedAI
+{
+ npc_silverpine_lord_darius_crowley_exsanguinate(Creature* creature) : ScriptedAI(creature) { }
+
+ void JustAppeared() override
+ {
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ if (Creature* armoire = me->FindNearestCreature(NPC_ARMOIRE_SUMMONED, 100.0f))
+ {
+ if (armoire->IsAIEnabled())
+ armoire->GetAI()->SetGUID(me->GetGUID(), me->GetEntry());
+ }
+ }
+
+ void WaypointReached(uint32 waypointId, uint32 pathId) override
+ {
+ if (pathId == PATH_CROWLEY_EXIT && waypointId == WAYPOINT_ON_CROWLEY_DESPAWN)
+ me->DespawnOrUnsummon();
+ }
+};
+
+enum IvarBloodfangExsanguinate
+{
+ WAYPOINT_ON_BLOODFANG_DESPAWN = 3
+};
+
+// 44884 - Packleader Ivar Bloodfang
+struct npc_silverpine_packleader_ivar_bloodfang_exsanguinate : public ScriptedAI
+{
+ npc_silverpine_packleader_ivar_bloodfang_exsanguinate(Creature* creature) : ScriptedAI(creature) { }
+
+ void JustAppeared() override
+ {
+ me->SetReactState(REACT_PASSIVE);
+ }
+
+ void IsSummonedBy(WorldObject* /*summoner*/) override
+ {
+ if (Creature* armoire = me->FindNearestCreature(NPC_ARMOIRE_SUMMONED, 30.0f))
+ {
+ if (armoire->IsAIEnabled())
+ armoire->GetAI()->SetGUID(me->GetGUID(), me->GetEntry());
+ }
+ }
+
+ void WaypointReached(uint32 waypointId, uint32 pathId) override
+ {
+ if (pathId == PATH_BLOODFANG_EXIT && waypointId == WAYPOINT_ON_BLOODFANG_DESPAWN)
+ me->DespawnOrUnsummon();
+ }
+};
+
void AddSC_silverpine_forest()
{
/* Vehicles */
@@ -1616,4 +2600,12 @@ void AddSC_silverpine_forest()
RegisterCreatureAI(npc_silverpine_forsaken_trooper);
RegisterCreatureAI(npc_silverpine_bat_handler_maggotbreath);
RegisterCreatureAI(npc_silverpine_forsaken_bat);
+
+ /* Ivar Patch */
+
+ RegisterGameObjectAI(go_silverpine_abandoned_outhouse);
+ RegisterCreatureAI(npc_silverpine_deathstalker_rane_yorick);
+ RegisterCreatureAI(npc_silverpine_armoire);
+ RegisterCreatureAI(npc_silverpine_lord_darius_crowley_exsanguinate);
+ RegisterCreatureAI(npc_silverpine_packleader_ivar_bloodfang_exsanguinate);
}
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 98271b04737..8cb2b7d547c 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -5141,6 +5141,22 @@ class spell_gen_eject_passengers_3_8 : public SpellScript
}
};
+// 83781 - Reverse Cast Ride Vehicle
+class spell_gen_reverse_cast_target_to_caster_triggered: public SpellScript
+{
+ PrepareSpellScript(spell_gen_reverse_cast_target_to_caster_triggered);
+
+ void HandleScript(SpellEffIndex effIndex)
+ {
+ GetHitUnit()->CastSpell(GetCaster(), GetSpellInfo()->GetEffect(effIndex).CalcValue(), true);
+ }
+
+ void Register() override
+ {
+ OnEffectHitTarget += SpellEffectFn(spell_gen_reverse_cast_target_to_caster_triggered::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
+ }
+};
+
void AddSC_generic_spell_scripts()
{
RegisterSpellScript(spell_gen_absorb0_hitlimit1);
@@ -5299,4 +5315,5 @@ void AddSC_generic_spell_scripts()
RegisterSpellScript(spell_gen_mount_check_aura);
RegisterSpellScript(spell_gen_ancestral_call);
RegisterSpellScript(spell_gen_eject_passengers_3_8);
+ RegisterSpellScript(spell_gen_reverse_cast_target_to_caster_triggered);
}