diff options
-rw-r--r-- | sql/updates/world/master/2022_10_10_00_world.sql | 174 | ||||
-rw-r--r-- | src/server/scripts/EasternKingdoms/zone_silverpine_forest.cpp | 992 | ||||
-rw-r--r-- | src/server/scripts/Spells/spell_generic.cpp | 17 |
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); } |