Compare commits
44
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a63829a130 | ||
|
|
a17899e921 | ||
|
|
55da003626 | ||
|
|
9fe909427c | ||
|
|
651845916f | ||
|
|
cebef91f24 | ||
|
|
1de4ff7967 | ||
|
|
ca9d636424 | ||
|
|
944bc6e8b2 | ||
|
|
76d463d664 | ||
|
|
fb1f200652 | ||
|
|
975591fa5b | ||
|
|
1633cd2093 | ||
|
|
014c9cc2d0 | ||
|
|
8ac8a3527b | ||
|
|
36108f76f7 | ||
|
|
b9b49adf03 | ||
|
|
3ce7f17005 | ||
|
|
89aae3dfa9 | ||
|
|
01824cf222 | ||
|
|
8b8aaffd70 | ||
|
|
a0203a632e | ||
|
|
988874e403 | ||
|
|
a4b6ec1100 | ||
|
|
ad87475cd5 | ||
|
|
60546b974f | ||
|
|
cfe74126f5 | ||
|
|
2317f0fe7d | ||
|
|
c354643e47 | ||
|
|
71e005e10f | ||
|
|
f72d0be912 | ||
|
|
0e9b9f7db8 | ||
|
|
7670e0eb91 | ||
|
|
48f5b7e124 | ||
|
|
c797c0c576 | ||
|
|
3cfb6d2c99 | ||
|
|
1b15337809 | ||
|
|
07e78803e2 | ||
|
|
23dc67639f | ||
|
|
371e06dab9 | ||
|
|
c7a4bf966e | ||
|
|
ffaac9ece6 | ||
|
|
b47740c125 | ||
|
|
5072ad8f6f |
@@ -0,0 +1,2 @@
|
|||||||
|
-- Exiles Reach: bind the Giant Boar Trample script (mows the undead down)
|
||||||
|
INSERT INTO `spell_script_names` (`spell_id`, `ScriptName`) VALUES (305557, 'spell_giant_boar_trample_305557');
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- Exiles Reach: post-Torgak quest-giver is Captain Garrick (245394), not 156807
|
||||||
|
-- (which wrongly reused Jaina's model 88316). Point the spawn and the
|
||||||
|
-- Stocking Up / Repair Yourself quest starters+enders at 245394.
|
||||||
|
UPDATE `creature` SET `id`=245394 WHERE `guid`=42560 AND `id`=156807;
|
||||||
|
UPDATE `creature_queststarter` SET `id`=245394 WHERE `id`=156807 AND `quest` IN (55194, 85678);
|
||||||
|
UPDATE `creature_questender` SET `id`=245394 WHERE `id`=156807 AND `quest` IN (55194, 85678);
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- Exiles Reach: Captain Garrick (245394) must be a quest-giver (npcflag bit 0x2)
|
||||||
|
UPDATE `creature_template` SET `npcflag` = `npcflag` | 2 WHERE `entry` = 245394;
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
-- Exiles Reach post-Torgak: revert the quest-giver to Jaina (156807) and give
|
||||||
|
-- Quartermaster Richter the repair flag.
|
||||||
|
-- (Corrects 2026_08_24_01/02 which wrongly swapped in Captain Garrick 245394.)
|
||||||
|
UPDATE `creature` SET `id`=156807 WHERE `guid`=42560 AND `id`=245394;
|
||||||
|
UPDATE `creature_queststarter` SET `id`=156807 WHERE `id`=245394 AND `quest` IN (55194, 85678);
|
||||||
|
UPDATE `creature_questender` SET `id`=156807 WHERE `id`=245394 AND `quest` IN (55194, 85678);
|
||||||
|
UPDATE `creature_template` SET `npcflag`=0 WHERE `entry`=245394;
|
||||||
|
UPDATE `creature_template` SET `npcflag` = `npcflag` | 4096 WHERE `entry` = 156800;
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
-- Exiles Reach: after the ride, Captain Garrick (245394) is the quest-giver for
|
||||||
|
-- Stocking Up on Supplies (55194); Repair Yourself (85678) is no longer offered.
|
||||||
|
UPDATE `creature_template` SET `npcflag` = `npcflag` | 2 WHERE `entry` = 245394;
|
||||||
|
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156807 AND `quest` IN (55194, 85678);
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156807 AND `quest` IN (55194, 85678);
|
||||||
|
|
||||||
|
INSERT INTO `creature_queststarter` (`id`, `quest`, `VerifiedBuild`) VALUES
|
||||||
|
(245394, 55194, 0);
|
||||||
|
INSERT INTO `creature_questender` (`id`, `quest`, `VerifiedBuild`) VALUES
|
||||||
|
(245394, 55194, 0);
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
-- Exiles Reach: post-ride reunion dialogue (Wrathion + Jaina) as a server-driven conversation.
|
||||||
|
-- The scene (2341) references conversation lines 88006-88013; the Wrathion broadcasts
|
||||||
|
-- (302254-302258) already exist, Jaina's (302259-302261) were empty placeholders.
|
||||||
|
-- NOTE: the broadcast_text updates for 302259-302261 live in the hotfixes DB.
|
||||||
|
|
||||||
|
DELETE FROM `conversation_actors` WHERE `ConversationId` = 51000;
|
||||||
|
DELETE FROM `conversation_line_template` WHERE `Id` BETWEEN 88006 AND 88013;
|
||||||
|
DELETE FROM `conversation_template` WHERE `Id` = 51000;
|
||||||
|
|
||||||
|
INSERT INTO `conversation_template` (`Id`, `FirstLineId`, `TextureKitId`, `Flags`, `ScriptName`, `VerifiedBuild`) VALUES
|
||||||
|
(51000, 88006, 0, 0, '', 0);
|
||||||
|
|
||||||
|
INSERT INTO `conversation_line_template` (`Id`, `UiCameraID`, `ActorIdx`, `Flags`, `ChatType`, `VerifiedBuild`, `Unk`) VALUES
|
||||||
|
(88006, 0, 0, 0, 0, 0, 0),
|
||||||
|
(88007, 0, 0, 0, 0, 0, 0),
|
||||||
|
(88008, 0, 0, 0, 0, 0, 0),
|
||||||
|
(88009, 0, 0, 0, 0, 0, 0),
|
||||||
|
(88010, 0, 0, 0, 0, 0, 0),
|
||||||
|
(88011, 0, 1, 0, 0, 0, 0),
|
||||||
|
(88012, 0, 1, 0, 0, 0, 0),
|
||||||
|
(88013, 0, 1, 0, 0, 0, 0);
|
||||||
|
|
||||||
|
INSERT INTO `conversation_actors` (`ConversationId`, `ConversationActorId`, `ConversationActorGuid`, `ConversationActorNearId`, `Idx`, `CreatureId`, `CreatureDisplayInfoId`, `NoActorObject`, `ActivePlayerObject`, `VerifiedBuild`) VALUES
|
||||||
|
(51000, 80000, 0, 0, 0, 156799, 107146, 0, 0, 0),
|
||||||
|
(51000, 80001, 0, 0, 1, 156807, 88316, 0, 0, 0);
|
||||||
|
-- Hrun's Barrow conversations (Alliance 12120 / Horde 14540) were missing actors
|
||||||
|
INSERT INTO `conversation_actors` (`ConversationId`, `ConversationActorId`, `ConversationActorGuid`, `ConversationActorNearId`, `Idx`, `CreatureId`, `CreatureDisplayInfoId`, `NoActorObject`, `ActivePlayerObject`, `VerifiedBuild`) VALUES
|
||||||
|
(12120, 80002, 0, 0, 0, 156900, 92803, 0, 0, 0),
|
||||||
|
(14540, 80003, 0, 0, 0, 156900, 92803, 0, 0, 0);
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
-- Exiles Reach: correct post-Torgak quest flow (idempotent)
|
||||||
|
-- 1. 55196 The Harpy Problem: remove the Wrathion (156799) starter; keep Henry (156833 + 156887)
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156799 AND `quest` = 55196;
|
||||||
|
|
||||||
|
-- 4. 55639 Who Lurks in the Pit: turn in to Captain Garrick (245394), not Jaina (156807)
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156807 AND `quest` = 55639;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 245394 AND `quest` = 55639;
|
||||||
|
INSERT INTO `creature_questender` (`id`, `quest`, `VerifiedBuild`) VALUES
|
||||||
|
(245394, 55639, 0);
|
||||||
|
|
||||||
|
-- 4. 85678 Repair Yourself: start + turn in at Captain Garrick (245394)
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 245394 AND `quest` = 85678;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 245394 AND `quest` = 85678;
|
||||||
|
INSERT INTO `creature_queststarter` (`id`, `quest`, `VerifiedBuild`) VALUES
|
||||||
|
(245394, 85678, 0);
|
||||||
|
INSERT INTO `creature_questender` (`id`, `quest`, `VerifiedBuild`) VALUES
|
||||||
|
(245394, 85678, 0);
|
||||||
|
|
||||||
|
-- 5. 58915 Hjalmar's Final Execution: starts at Hjalmar (162943), ends at Private Cole (156801) — no change needed
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156887 AND `quest` = 55196;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156807 AND `quest` = 55882;
|
||||||
|
INSERT INTO `creature_questender` (`id`, `quest`, `VerifiedBuild`) VALUES (245394, 55882, 0);
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 154300 AND `quest` = 55965;
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156941 AND `quest` = 55981;
|
||||||
|
INSERT INTO `creature_queststarter` (`id`, `quest`, `VerifiedBuild`) VALUES (245397, 55981, 0);
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156941 AND `quest` = 55981;
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156960 AND `quest` = 55989;
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156943 AND `quest` = 55989;
|
||||||
|
INSERT INTO `creature_queststarter` (`id`, `quest`, `VerifiedBuild`) VALUES (245667, 55989, 0);
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156960 AND `quest` = 55989;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156943 AND `quest` = 55989;
|
||||||
|
INSERT INTO `creature_questender` (`id`, `quest`, `VerifiedBuild`) VALUES (245667, 55989, 0);
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156941 AND `quest` = 55990;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156965 AND `quest` = 55990;
|
||||||
|
INSERT INTO `creature_questender` (`id`, `quest`, `VerifiedBuild`) VALUES (156961, 55990, 0);
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156961 AND `quest` = 55991;
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156941 AND `quest` = 55991;
|
||||||
|
INSERT INTO `creature_queststarter` (`id`, `quest`, `VerifiedBuild`) VALUES (245686, 55991, 0);
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 238913 AND `quest` = 55991;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 154169 AND `quest` = 55991;
|
||||||
|
INSERT INTO `creature_questender` (`id`, `quest`, `VerifiedBuild`) VALUES (245686, 55991, 0);
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156941 AND `quest` = 55992;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 161350 AND `quest` = 55992;
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156807 AND `quest` = 56344;
|
||||||
|
INSERT INTO `creature_queststarter` (`id`, `quest`, `VerifiedBuild`) VALUES (245394, 56344, 0);
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156941 AND `quest` = 56344;
|
||||||
|
INSERT INTO `creature_questender` (`id`, `quest`, `VerifiedBuild`) VALUES (245397, 56344, 0);
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 162972 AND `quest` = 58917;
|
||||||
|
INSERT INTO `creature_queststarter` (`id`, `quest`, `VerifiedBuild`) VALUES (156801, 58923, 0);
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 162972 AND `quest` = 58933;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156804 AND `quest` = 59347;
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 156804 AND `quest` = 59349;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 156932 AND `quest` = 59350;
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 167128 AND `quest` = 59943;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 167221 AND `quest` = 59948;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 162998 AND `quest` = 59958;
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 167631 AND `quest` = 59980;
|
||||||
|
INSERT INTO `creature_queststarter` (`id`, `quest`, `VerifiedBuild`) VALUES (167630, 59980, 0);
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 167631 AND `quest` = 59980;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 167633 AND `quest` = 59984;
|
||||||
|
DELETE FROM `creature_queststarter` WHERE `id` = 167633 AND `quest` = 59985;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 244496 AND `quest` = 59985;
|
||||||
|
DELETE FROM `creature_questender` WHERE `id` = 154169 AND `quest` = 59985;
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
-- Exiles Reach: post-Torgak quest givers (custom NPCs) need UNIT_NPC_FLAG_QUESTGIVER (0x2)
|
||||||
|
UPDATE `creature_template` SET `npcflag` = `npcflag` | 2 WHERE `entry` IN (245397, 245667, 245686);
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
-- Exiles Reach: the ritual Meredy/Herbert (153211/167298) need UNIT_NPC_FLAG_GOSSIP (0x1)
|
||||||
|
-- to start the Bloodbeak fight via OnGossipSelect (the event was unreachable with npcflag=0)
|
||||||
|
UPDATE `creature_template` SET `npcflag` = `npcflag` | 1 WHERE `entry` IN (153211, 167298);
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
-- Exiles Reach: correct the post-Torgak reunion scene packages.
|
||||||
|
-- 2341 (Alliance, cast by SPELL_REUNION_SCENE_A) -> 4778 (11.2.7 ExilesReach Alliance IGC)
|
||||||
|
-- 2497 (Horde) already correctly maps to 4779.
|
||||||
|
UPDATE `scene_template` SET `ScriptPackageID` = 4778 WHERE `SceneId` = 2341;
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- Exiles Reach: add a DB spawn for post-Torgak Captain Garrick (245394) at the camp,
|
||||||
|
-- so he's reliably present as quest-giver (55639/55194/85678) like Jaina (156807).
|
||||||
|
-- z = 91.001 matches the camp ground height (Jaina 42560 is also at 91.001).
|
||||||
|
SET @guid := 730202;
|
||||||
|
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`, `curHealthPct`, `MovementType`, `npcflag`, `unit_flags`, `unit_flags2`, `unit_flags3`, `ScriptName`, `StringId`, `VerifiedBuild`) VALUES
|
||||||
|
(@guid, 245394, 2175, 10424, 10424, 0, 0, 15017, 0, -1, 0, 0, 180.8, -2286.0, 91.001, 0.0, 180, 0, 0, NULL, 0, NULL, NULL, NULL, NULL, '', NULL, 0);
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
-- Exiles Reach: bind the Giant Boar ride scene (SceneId 2338, package 2712) to its SceneScript.
|
||||||
|
-- During the boar ride ("Ride of the Scientifically Enhanced Boar" / "The Redeather") the client
|
||||||
|
-- fires "Trampling Time", "Big Kill Credit" and "Knockback" trigger events; core only dispatches
|
||||||
|
-- those to a bound SceneScript via scene_template.ScriptName. The script itself lives in
|
||||||
|
-- src/server/scripts/ExilesReach/exiles_reach.cpp (scene_exiles_reach_boar_ride).
|
||||||
|
UPDATE `scene_template` SET `ScriptName` = 'scene_exiles_reach_boar_ride' WHERE `SceneId` = 2338;
|
||||||
@@ -48,6 +48,13 @@ uint32 SceneMgr::PlaySceneByTemplate(SceneTemplate const* sceneTemplate, Positio
|
|||||||
if (!entry)
|
if (!entry)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
// Scene debug (PlayerbotV2): log which scene plays on Exiles Reach (map 2175)
|
||||||
|
// so the post-ride cinematic can be matched against the expected one.
|
||||||
|
if (GetPlayer()->GetMapId() == 2175)
|
||||||
|
TC_LOG_ERROR("playerbot.v2", "[SceneDebug] {} playing sceneId={} package={} flags={}",
|
||||||
|
GetPlayer()->GetName(), sceneTemplate->SceneId, sceneTemplate->ScenePackageId,
|
||||||
|
sceneTemplate->PlaybackFlags.AsUnderlyingType());
|
||||||
|
|
||||||
// By default, take player position
|
// By default, take player position
|
||||||
if (!position)
|
if (!position)
|
||||||
position = GetPlayer();
|
position = GetPlayer();
|
||||||
|
|||||||
@@ -205,8 +205,21 @@ void ConversationDataStore::LoadConversationTemplates()
|
|||||||
{
|
{
|
||||||
static constexpr uint32 FirstLineId = 60000; // Arbitrary id to cover the affected rows
|
static constexpr uint32 FirstLineId = 60000; // Arbitrary id to cover the affected rows
|
||||||
|
|
||||||
if (conversationLine->ID > FirstLineId && conversationLine->NextConversationLineID < (sConversationLineStore.GetNumRows() - USHRT_MAX - 1))
|
// Line IDs above FirstLineId store NextConversationLineID as a uint16 offset into the high id
|
||||||
return (uint32)(USHRT_MAX + conversationLine->NextConversationLineID + 1);
|
// space (real id = USHRT_MAX + stored + 1) when the real next line id does not fit in a uint16.
|
||||||
|
// The data is sparse, so GetNumRows() is not a reliable upper bound; resolve by checking which
|
||||||
|
// candidate actually exists, preferring the offset when it is the forward chain.
|
||||||
|
if (conversationLine->ID > FirstLineId)
|
||||||
|
{
|
||||||
|
uint32 stored = conversationLine->NextConversationLineID;
|
||||||
|
uint32 candidate = USHRT_MAX + stored + 1;
|
||||||
|
ConversationLineEntry const* rawEntry = sConversationLineStore.LookupEntry(stored);
|
||||||
|
ConversationLineEntry const* offsetEntry = sConversationLineStore.LookupEntry(candidate);
|
||||||
|
if (rawEntry && !offsetEntry)
|
||||||
|
return stored;
|
||||||
|
if (offsetEntry && (!rawEntry || candidate > conversationLine->ID))
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
return (uint32)conversationLine->NextConversationLineID;
|
return (uint32)conversationLine->NextConversationLineID;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2354,6 +2354,7 @@ void ScriptMgr::OnSceneTrigger(Player* player, uint32 sceneInstanceID, SceneTemp
|
|||||||
ASSERT(player);
|
ASSERT(player);
|
||||||
ASSERT(sceneTemplate);
|
ASSERT(sceneTemplate);
|
||||||
|
|
||||||
|
FOREACH_SCRIPT(PlayerScript)->OnSceneTriggerEvent(player, sceneInstanceID, triggerName);
|
||||||
GET_SCRIPT(SceneScript, sceneTemplate->ScriptId, tmpscript);
|
GET_SCRIPT(SceneScript, sceneTemplate->ScriptId, tmpscript);
|
||||||
tmpscript->OnSceneTriggerEvent(player, sceneInstanceID, sceneTemplate, triggerName);
|
tmpscript->OnSceneTriggerEvent(player, sceneInstanceID, sceneTemplate, triggerName);
|
||||||
}
|
}
|
||||||
@@ -2363,6 +2364,7 @@ void ScriptMgr::OnSceneCancel(Player* player, uint32 sceneInstanceID, SceneTempl
|
|||||||
ASSERT(player);
|
ASSERT(player);
|
||||||
ASSERT(sceneTemplate);
|
ASSERT(sceneTemplate);
|
||||||
|
|
||||||
|
FOREACH_SCRIPT(PlayerScript)->OnSceneCancel(player, sceneInstanceID);
|
||||||
GET_SCRIPT(SceneScript, sceneTemplate->ScriptId, tmpscript);
|
GET_SCRIPT(SceneScript, sceneTemplate->ScriptId, tmpscript);
|
||||||
tmpscript->OnSceneCancel(player, sceneInstanceID, sceneTemplate);
|
tmpscript->OnSceneCancel(player, sceneInstanceID, sceneTemplate);
|
||||||
}
|
}
|
||||||
@@ -2372,6 +2374,7 @@ void ScriptMgr::OnSceneComplete(Player* player, uint32 sceneInstanceID, SceneTem
|
|||||||
ASSERT(player);
|
ASSERT(player);
|
||||||
ASSERT(sceneTemplate);
|
ASSERT(sceneTemplate);
|
||||||
|
|
||||||
|
FOREACH_SCRIPT(PlayerScript)->OnSceneComplete(player, sceneInstanceID);
|
||||||
GET_SCRIPT(SceneScript, sceneTemplate->ScriptId, tmpscript);
|
GET_SCRIPT(SceneScript, sceneTemplate->ScriptId, tmpscript);
|
||||||
tmpscript->OnSceneComplete(player, sceneInstanceID, sceneTemplate);
|
tmpscript->OnSceneComplete(player, sceneInstanceID, sceneTemplate);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,12 +24,57 @@
|
|||||||
#include "exiles_reach.h"
|
#include "exiles_reach.h"
|
||||||
#include "MovementPackets.h"
|
#include "MovementPackets.h"
|
||||||
#include "ScriptMgr.h"
|
#include "ScriptMgr.h"
|
||||||
|
#include "CellImpl.h"
|
||||||
|
#include "GridNotifiers.h"
|
||||||
|
#include "GridNotifiersImpl.h"
|
||||||
|
|
||||||
class exiles_reach_general_playerscript : public PlayerScript
|
class exiles_reach_general_playerscript : public PlayerScript
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
exiles_reach_general_playerscript() : PlayerScript("exiles_reach_general_playerscript") {}
|
exiles_reach_general_playerscript() : PlayerScript("exiles_reach_general_playerscript") {}
|
||||||
|
|
||||||
|
// Undead mowed down by the giant boar (spawnIds), so they can be respawned
|
||||||
|
// if the ride quest is abandoned.
|
||||||
|
static std::unordered_set<ObjectGuid::LowType> s_mowedDownUndead;
|
||||||
|
// Players currently on the boar ride, so an abandon can be detected (the
|
||||||
|
// OnQuestStatusChange hook does NOT fire for quest abandon).
|
||||||
|
static std::unordered_set<ObjectGuid> s_rideActivePlayers;
|
||||||
|
|
||||||
|
void CheckRideAbandon(Player* player)
|
||||||
|
{
|
||||||
|
ObjectGuid const guid = player->GetGUID();
|
||||||
|
|
||||||
|
bool active = false;
|
||||||
|
bool rewarded = false;
|
||||||
|
for (uint32 questId : { QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR, QUEST_H_THE_REDEATHER })
|
||||||
|
{
|
||||||
|
QuestStatus const status = player->GetQuestStatus(questId);
|
||||||
|
if (status == QUEST_STATUS_INCOMPLETE || status == QUEST_STATUS_COMPLETE)
|
||||||
|
active = true;
|
||||||
|
else if (status == QUEST_STATUS_REWARDED)
|
||||||
|
rewarded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active)
|
||||||
|
s_rideActivePlayers.insert(guid);
|
||||||
|
else if (s_rideActivePlayers.erase(guid))
|
||||||
|
{
|
||||||
|
// Was riding and no longer is: abandoned (respawn the undead) or
|
||||||
|
// completed (let them stay mowed down).
|
||||||
|
if (!rewarded)
|
||||||
|
{
|
||||||
|
TC_LOG_ERROR("playerbot.v2", "[ExilesReach] ride abandoned; respawning {} tracked undead", s_mowedDownUndead.size());
|
||||||
|
if (Map* map = player->GetMap())
|
||||||
|
for (ObjectGuid::LowType spawnId : s_mowedDownUndead)
|
||||||
|
{
|
||||||
|
TC_LOG_ERROR("playerbot.v2", "[ExilesReach] respawn spawnId={}", spawnId);
|
||||||
|
map->Respawn(SPAWN_TYPE_CREATURE, spawnId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s_mowedDownUndead.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OnLogin(Player* player, bool /*firstLogin*/) override
|
void OnLogin(Player* player, bool /*firstLogin*/) override
|
||||||
{
|
{
|
||||||
if (player->GetMapId() != MAP_NPE)
|
if (player->GetMapId() != MAP_NPE)
|
||||||
@@ -42,6 +87,7 @@ public:
|
|||||||
void OnPlayerWorldObjectUpdate(Player* player, uint32 /*diff*/) override
|
void OnPlayerWorldObjectUpdate(Player* player, uint32 /*diff*/) override
|
||||||
{
|
{
|
||||||
CheckExilesReachSceneSpells(player);
|
CheckExilesReachSceneSpells(player);
|
||||||
|
CheckRideAbandon(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnSceneTriggerEvent(Player* player, uint32 sceneInstanceID, std::string sceneEvent) override
|
void OnSceneTriggerEvent(Player* player, uint32 sceneInstanceID, std::string sceneEvent) override
|
||||||
@@ -49,20 +95,11 @@ public:
|
|||||||
if (player->GetMapId() != MAP_EXILES_REACH)
|
if (player->GetMapId() != MAP_EXILES_REACH)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (sceneEvent == "Big Kill Credit")
|
// NOTE: The Giant Boar ride triggers ("Big Kill Credit", "Knockback",
|
||||||
{
|
// "Trampling Time") are handled in scene_exiles_reach_boar_ride below,
|
||||||
player->CastSpell(player, SPELL_CADAVER_KILL_CREDIT);
|
// bound to scene_template.SceneId = 2338 via SQL. SceneScripts are
|
||||||
|
// dispatched by core on every branch, so the ride works without any
|
||||||
if (player->GetQuestObjectiveProgress(QUEST_H_THE_REDEATHER, 2) == 8)
|
// core changes and fires exactly once per event.
|
||||||
{
|
|
||||||
player->CastSpell(player, SPELL_CADAVER_CREDIT_CHECK_CHOPPY_MALFUNCTION, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (player->GetQuestObjectiveProgress(QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR, 2) == 8)
|
|
||||||
{
|
|
||||||
player->CastSpell(player, SPELL_GIANT_BOAR_PING_VEHICLE, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sceneEvent == "Teleport")
|
if (sceneEvent == "Teleport")
|
||||||
{
|
{
|
||||||
@@ -97,21 +134,6 @@ public:
|
|||||||
player->CastSpell(player, SPELL_ORGRIMMAR_TELEPORT, true);
|
player->CastSpell(player, SPELL_ORGRIMMAR_TELEPORT, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sceneEvent == "Knockback")
|
|
||||||
{
|
|
||||||
player->CastSpell(player, SPELL_GIANT_BOAR_RIDING_KNOCKBACK, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (sceneEvent == "Trampling Time")
|
|
||||||
{
|
|
||||||
if (Creature* giantBoarVehicle = player->GetVehicleCreatureBase())
|
|
||||||
{
|
|
||||||
Position targetLoc = giantBoarVehicle->GetFirstCollisionPosition(20.f, 0.f);
|
|
||||||
giantBoarVehicle->GetMotionMaster()->MoveCharge(targetLoc.GetPositionX(), targetLoc.GetPositionY(), targetLoc.GetPositionZ());
|
|
||||||
player->CastSpell(player, SPELL_GIANT_BOAR_TRAMPLE, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnUpdateArea(Player* player, uint32 newArea, uint32 /*oldArea*/) override
|
void OnUpdateArea(Player* player, uint32 newArea, uint32 /*oldArea*/) override
|
||||||
@@ -154,6 +176,115 @@ public:
|
|||||||
|
|
||||||
if (questId == QUEST_AN_END_TO_BEGINNINGS || questId == QUEST_H_AN_END_TO_BEGINNINGS)
|
if (questId == QUEST_AN_END_TO_BEGINNINGS || questId == QUEST_H_AN_END_TO_BEGINNINGS)
|
||||||
CancelExilesReachSceneAuras(player);
|
CancelExilesReachSceneAuras(player);
|
||||||
|
|
||||||
|
// Ride of the Scientifically Enhanced Boar: clear the mowed-down tracking
|
||||||
|
// when the ride is completed (the mobs stay mowed down). Abandon is
|
||||||
|
// detected in CheckRideAbandon (OnQuestStatusChange doesn't fire for
|
||||||
|
// quest abandon).
|
||||||
|
if (questId == QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR || questId == QUEST_H_THE_REDEATHER)
|
||||||
|
if (player->GetQuestStatus(questId) == QUEST_STATUS_REWARDED)
|
||||||
|
s_mowedDownUndead.clear();
|
||||||
|
|
||||||
|
if (questId == QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR && player->GetQuestStatus(questId) == QUEST_STATUS_REWARDED)
|
||||||
|
{
|
||||||
|
player->CastSpell(player, SPELL_REUNION_SCENE_A, true);
|
||||||
|
Conversation::CreateConversation(CONVERSATION_OGRE_RUINS_REUNION, player, *player, player->GetGUID(), nullptr);
|
||||||
|
}
|
||||||
|
else if (questId == QUEST_H_THE_REDEATHER && player->GetQuestStatus(questId) == QUEST_STATUS_REWARDED)
|
||||||
|
player->CastSpell(player, SPELL_REUNION_SCENE_H, true);
|
||||||
|
|
||||||
|
// After the ride is handed in, the camp at the ogre ruins populates:
|
||||||
|
// Jaina near Austin Huxworth by the rock edging (grants Stocking Up /
|
||||||
|
// Repair Yourself), Captain Garrick by the campfire (DB spawn).
|
||||||
|
if (questId == QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR && player->GetQuestStatus(questId) == QUEST_STATUS_REWARDED)
|
||||||
|
{
|
||||||
|
if (!player->FindNearestCreature(NPC_OGRE_RUINS_POST_TORGOK_JAINA, 50.0f, true))
|
||||||
|
if (Creature* jaina = player->SummonCreature(NPC_OGRE_RUINS_POST_TORGOK_JAINA,
|
||||||
|
Position(186.572f, -2289.42f, 81.6354f, 2.31301f),
|
||||||
|
TEMPSUMMON_MANUAL_DESPAWN, 0s, 0U, 0U, player->GetGUID()))
|
||||||
|
jaina->SetNpcFlag(UNIT_NPC_FLAG_QUESTGIVER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unordered_set<ObjectGuid::LowType> exiles_reach_general_playerscript::s_mowedDownUndead;
|
||||||
|
std::unordered_set<ObjectGuid> exiles_reach_general_playerscript::s_rideActivePlayers;
|
||||||
|
|
||||||
|
/* ## SCENE SCRIPTS > ## */
|
||||||
|
|
||||||
|
// Giant Boar ride (scene_template.SceneId = 2338, package 2712) -
|
||||||
|
// "Ride of the Scientifically Enhanced Boar" / "The Redeather".
|
||||||
|
//
|
||||||
|
// The client fires these trigger events from scene package 2712 during the boar
|
||||||
|
// ride (verified against a retail 12.1 packet capture):
|
||||||
|
// Conversation, then repeating pairs of "Trampling Time" + "Big Kill Credit",
|
||||||
|
// plus "Knockback" and "Hint", until SMSG_CANCEL_SCENE.
|
||||||
|
//
|
||||||
|
// The logic is bound to the scene via scene_template.ScriptName (see SQL
|
||||||
|
// update) instead of living in the PlayerScript hook above: core dispatches
|
||||||
|
// scene trigger events to a bound SceneScript on every branch, while
|
||||||
|
// OnSceneTriggerEvent only reaches PlayerScripts when an extra core change is
|
||||||
|
// present. Keeping it here means each event fires exactly once on both.
|
||||||
|
class scene_exiles_reach_boar_ride : public SceneScript
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
scene_exiles_reach_boar_ride() : SceneScript("scene_exiles_reach_boar_ride") {}
|
||||||
|
|
||||||
|
void OnSceneTriggerEvent(Player* player, uint32 /*sceneInstanceID*/, SceneTemplate const* /*sceneTemplate*/, std::string const& triggerName) override
|
||||||
|
{
|
||||||
|
if (player->GetMapId() != MAP_EXILES_REACH)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (triggerName == "Big Kill Credit")
|
||||||
|
{
|
||||||
|
player->CastSpell(player, SPELL_CADAVER_KILL_CREDIT);
|
||||||
|
|
||||||
|
if (player->GetQuestObjectiveProgress(QUEST_H_THE_REDEATHER, 2) == 8)
|
||||||
|
{
|
||||||
|
player->CastSpell(player, SPELL_CADAVER_CREDIT_CHECK_CHOPPY_MALFUNCTION, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (player->GetQuestObjectiveProgress(QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR, 2) == 8)
|
||||||
|
{
|
||||||
|
player->CastSpell(player, SPELL_GIANT_BOAR_PING_VEHICLE, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The boar mowed the undead down: despawn the hostile mobs around
|
||||||
|
// the rider so the trampled army actually vanishes (and stops
|
||||||
|
// attacking). Tied to the reliable scene credit rather than the
|
||||||
|
// trample's own grid search.
|
||||||
|
std::list<Creature*> mobs;
|
||||||
|
Trinity::AnyUnitInObjectRangeCheck u_check(player, 50.0f);
|
||||||
|
Trinity::CreatureListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(player, mobs, u_check);
|
||||||
|
Cell::VisitGridObjects(player, searcher, 50.0f);
|
||||||
|
for (Creature* mob : mobs)
|
||||||
|
{
|
||||||
|
if (!player->IsHostileTo(mob))
|
||||||
|
continue;
|
||||||
|
if (mob->GetEntry() == NPC_OGRE_RUINS_TORGOK)
|
||||||
|
continue; // leave the boss for the fight
|
||||||
|
// Track so the undead can be respawned if the quest is abandoned.
|
||||||
|
exiles_reach_general_playerscript::s_mowedDownUndead.insert(mob->GetSpawnId());
|
||||||
|
// Long respawn delay so the mowed-down undead stay dead
|
||||||
|
// through the rest of the ride instead of popping back.
|
||||||
|
mob->DespawnOrUnsummon(0s, 1h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triggerName == "Knockback")
|
||||||
|
{
|
||||||
|
player->CastSpell(player, SPELL_GIANT_BOAR_RIDING_KNOCKBACK, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triggerName == "Trampling Time")
|
||||||
|
{
|
||||||
|
if (Creature* giantBoarVehicle = player->GetVehicleCreatureBase())
|
||||||
|
{
|
||||||
|
Position targetLoc = giantBoarVehicle->GetFirstCollisionPosition(20.f, 0.f);
|
||||||
|
giantBoarVehicle->GetMotionMaster()->MoveCharge(targetLoc.GetPositionX(), targetLoc.GetPositionY(), targetLoc.GetPositionZ());
|
||||||
|
player->CastSpell(player, SPELL_GIANT_BOAR_TRAMPLE, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -366,6 +497,8 @@ void AddSC_exiles_reach_general()
|
|||||||
{
|
{
|
||||||
// Player Scripts
|
// Player Scripts
|
||||||
new exiles_reach_general_playerscript();
|
new exiles_reach_general_playerscript();
|
||||||
|
// Scene Scripts
|
||||||
|
new scene_exiles_reach_boar_ride();
|
||||||
// WorldMap Scripts
|
// WorldMap Scripts
|
||||||
new map_exiles_reach();
|
new map_exiles_reach();
|
||||||
// Spell Scripts
|
// Spell Scripts
|
||||||
|
|||||||
@@ -349,6 +349,9 @@ enum ExileReachHelpers
|
|||||||
NPC_OGRE_RUINS_TORGOK_FIGHTER_H = 167145,
|
NPC_OGRE_RUINS_TORGOK_FIGHTER_H = 167145,
|
||||||
NPC_OGRE_RUINS_CADAVER_KILL_CREDIT = 165150,
|
NPC_OGRE_RUINS_CADAVER_KILL_CREDIT = 165150,
|
||||||
NPC_OGRE_RUINS_TORGOK = 162817,
|
NPC_OGRE_RUINS_TORGOK = 162817,
|
||||||
|
NPC_OGRE_RUINS_WRATHION = 156799,
|
||||||
|
NPC_OGRE_RUINS_POST_TORGOK_JAINA = 156807,
|
||||||
|
NPC_OGRE_RUINS_POST_TORGOK_GARRICK = 245394,
|
||||||
NPC_OGRE_RUINS_ALARIA = 156803,
|
NPC_OGRE_RUINS_ALARIA = 156803,
|
||||||
NPC_OGRE_RUINS_BJORN = 154300,
|
NPC_OGRE_RUINS_BJORN = 154300,
|
||||||
NPC_OGRE_RUINS_KEELA_BEFORE_HARPY_ROOST = 156804,
|
NPC_OGRE_RUINS_KEELA_BEFORE_HARPY_ROOST = 156804,
|
||||||
@@ -573,6 +576,7 @@ enum ExileReachHelpers
|
|||||||
PHASE_ALLIANCE_DARKMAUL_CITADEL_15612 = 15612,
|
PHASE_ALLIANCE_DARKMAUL_CITADEL_15612 = 15612,
|
||||||
|
|
||||||
CONVERSATION_BLOOD_BEAK_INCOMING_A = 11739,
|
CONVERSATION_BLOOD_BEAK_INCOMING_A = 11739,
|
||||||
|
CONVERSATION_OGRE_RUINS_REUNION = 51000,
|
||||||
CONVERSATION_BLOOD_BEAK_INCOMING_H = 14572,
|
CONVERSATION_BLOOD_BEAK_INCOMING_H = 14572,
|
||||||
CONVERSATION_GARRICK_OGRE_TRANSFORM_APPLY = 11511,
|
CONVERSATION_GARRICK_OGRE_TRANSFORM_APPLY = 11511,
|
||||||
CONVERSATION_REACHED_DARKMAUL_CITADEL_ENTRANCE = 11511,
|
CONVERSATION_REACHED_DARKMAUL_CITADEL_ENTRANCE = 11511,
|
||||||
|
|||||||
@@ -22,6 +22,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "exiles_reach.h"
|
#include "exiles_reach.h"
|
||||||
|
#include "CellImpl.h"
|
||||||
|
#include "GridNotifiers.h"
|
||||||
|
#include "GridNotifiersImpl.h"
|
||||||
|
|
||||||
class exiles_reach_darkmaul_plains_playerscript : public PlayerScript
|
class exiles_reach_darkmaul_plains_playerscript : public PlayerScript
|
||||||
{
|
{
|
||||||
@@ -59,12 +62,12 @@ public:
|
|||||||
|
|
||||||
if (player->IsInAlliance())
|
if (player->IsInAlliance())
|
||||||
{
|
{
|
||||||
WowCommunity::PhaseShift(player, { PHASE_GENERAL_DARKMAUL_PLAINS_ZOMBIES_AND_CADAVERS }, QuestsRewarded(player, { QUEST_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_DOWN_WITH_THE_QUILBOAR }) && !player->HasAura(SPELL_RIDING_GIANT_BOAR) && !player->GetQuestStatus(QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
WowCommunity::PhaseShift(player, { PHASE_GENERAL_DARKMAUL_PLAINS_ZOMBIES_AND_CADAVERS }, QuestsRewarded(player, { QUEST_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_DOWN_WITH_THE_QUILBOAR }) && !QuestCompletedOrRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_GENERAL_OGRE_RUINS_TORGOK }, !QuestCompletedOrRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
WowCommunity::PhaseShift(player, { PHASE_GENERAL_OGRE_RUINS_TORGOK }, !QuestCompletedOrRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_HARPY_ROOST_MEREDY_RITUAL }, true);
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_HARPY_ROOST_MEREDY_RITUAL }, true);
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_QUILBOAR_BRIARPATCH_15276, PHASE_ALLIANCE_QUILBOAR_BRIARPATCH_16917 }, player->GetQuestStatus(QUEST_DOWN_WITH_THE_QUILBOAR) != QUEST_STATUS_REWARDED);
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_QUILBOAR_BRIARPATCH_15276, PHASE_ALLIANCE_QUILBOAR_BRIARPATCH_16917 }, player->GetQuestStatus(QUEST_DOWN_WITH_THE_QUILBOAR) != QUEST_STATUS_REWARDED);
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_DARKMAUL_PLAINS_SPRINGSTOCK }, QuestCompletedOrRewarded(player, QUEST_DOWN_WITH_THE_QUILBOAR) && !player->GetSummonedCreatureByEntry(NPC_DARKMAUL_PLAINS_SPRINGSTOCK) && !player->GetSummonedCreatureByEntry(NPC_DARKMAUL_PLAINS_SPRINGSTOCK_RESIZING_SUMMON));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_DARKMAUL_PLAINS_SPRINGSTOCK }, QuestCompletedOrRewarded(player, QUEST_DOWN_WITH_THE_QUILBOAR) && !player->GetSummonedCreatureByEntry(NPC_DARKMAUL_PLAINS_SPRINGSTOCK) && !player->GetSummonedCreatureByEntry(NPC_DARKMAUL_PLAINS_SPRINGSTOCK_RESIZING_SUMMON));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_DARKMAUL_PLAINS_GARRICK }, QuestCompletedOrRewarded(player, QUEST_DOWN_WITH_THE_QUILBOAR) && !QuestAccepted(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_DARKMAUL_PLAINS_GARRICK }, QuestCompletedOrRewarded(player, QUEST_DOWN_WITH_THE_QUILBOAR) && !QuestRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_DARKMAUL_PLAINS_AUSTIN }, QuestCompletedOrRewarded(player, QUEST_DOWN_WITH_THE_QUILBOAR));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_DARKMAUL_PLAINS_AUSTIN }, QuestCompletedOrRewarded(player, QUEST_DOWN_WITH_THE_QUILBOAR));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_DARKMAUL_PLAINS_13394 }, QuestCompleted(player, QUEST_DOWN_WITH_THE_QUILBOAR));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_DARKMAUL_PLAINS_13394 }, QuestCompleted(player, QUEST_DOWN_WITH_THE_QUILBOAR));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_DARKMAUL_PLAINS_13780 }, QuestCompleted(player, QUEST_DOWN_WITH_THE_QUILBOAR));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_DARKMAUL_PLAINS_13780 }, QuestCompleted(player, QUEST_DOWN_WITH_THE_QUILBOAR));
|
||||||
@@ -887,6 +890,18 @@ public:
|
|||||||
|
|
||||||
class spell_riding_giant_boar_305068_AuraScript : public AuraScript
|
class spell_riding_giant_boar_305068_AuraScript : public AuraScript
|
||||||
{
|
{
|
||||||
|
void HandleApply(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||||
|
{
|
||||||
|
Unit* owner = GetUnitOwner();
|
||||||
|
if (!owner)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Riding the giant boar: the undead chew on the boar, not the rider.
|
||||||
|
// Block NPC attacks on the player (the trample/charge already pull
|
||||||
|
// threat onto the boar, so remaining direct hits shouldn't reach us).
|
||||||
|
owner->SetUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
|
||||||
|
}
|
||||||
|
|
||||||
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
void HandleRemove(AuraEffect const* /*aurEff*/, AuraEffectHandleModes /*mode*/)
|
||||||
{
|
{
|
||||||
Unit* owner = GetUnitOwner();
|
Unit* owner = GetUnitOwner();
|
||||||
@@ -894,12 +909,15 @@ public:
|
|||||||
if (!owner || !player)
|
if (!owner || !player)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
owner->RemoveUnitFlag(UNIT_FLAG_IMMUNE_TO_NPC);
|
||||||
player->RemoveAura(SPELL_RIDING_GIANT_BOAR2);
|
player->RemoveAura(SPELL_RIDING_GIANT_BOAR2);
|
||||||
player->CastSpell(player, SPELL_KNOCKBACK_FOR_HACKFIX_GIANT_BOAR_LEAVE, true);
|
player->CastSpell(player, SPELL_KNOCKBACK_FOR_HACKFIX_GIANT_BOAR_LEAVE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Register() override
|
void Register() override
|
||||||
{
|
{
|
||||||
|
OnEffectApply += AuraEffectApplyFn(spell_riding_giant_boar_305068_AuraScript::HandleApply, EFFECT_0, SPELL_AURA_CONTROL_VEHICLE, AURA_EFFECT_HANDLE_REAL);
|
||||||
|
OnEffectApply += AuraEffectApplyFn(spell_riding_giant_boar_305068_AuraScript::HandleApply, EFFECT_1, SPELL_AURA_LINKED_SUMMON, AURA_EFFECT_HANDLE_REAL);
|
||||||
OnEffectRemove += AuraEffectRemoveFn(spell_riding_giant_boar_305068_AuraScript::HandleRemove, EFFECT_1, SPELL_AURA_LINKED_SUMMON, AURA_EFFECT_HANDLE_REAL);
|
OnEffectRemove += AuraEffectRemoveFn(spell_riding_giant_boar_305068_AuraScript::HandleRemove, EFFECT_1, SPELL_AURA_LINKED_SUMMON, AURA_EFFECT_HANDLE_REAL);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -982,6 +1000,61 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Giant Boar Trample (305557) — mows down the undead army / Monstrous Cadavers
|
||||||
|
// (157091) around the boar. The spell's Effect 1 is a DUMMY (radius 13) that
|
||||||
|
// targets the caster; the actual damage to nearby enemies is scripted here.
|
||||||
|
class spell_giant_boar_trample_305557 : public SpellScriptLoader
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
spell_giant_boar_trample_305557() : SpellScriptLoader("spell_giant_boar_trample_305557") {}
|
||||||
|
|
||||||
|
class spell_giant_boar_trample_305557_SpellScript : public SpellScript
|
||||||
|
{
|
||||||
|
void HandleDummy(SpellEffIndex /*effIndex*/)
|
||||||
|
{
|
||||||
|
Unit* caster = GetCaster();
|
||||||
|
if (!caster || !caster->IsInWorld())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Damage comes from the boar vehicle so the undead aggro the boar,
|
||||||
|
// not the rider (a player-cast trample would pull threat onto the
|
||||||
|
// player and the mobs would chew through the rider's health).
|
||||||
|
Unit* source = caster;
|
||||||
|
if (Player* player = caster->ToPlayer())
|
||||||
|
if (Unit* boar = player->GetVehicleBase())
|
||||||
|
source = boar;
|
||||||
|
|
||||||
|
float radius = GetEffectInfo().CalcRadius(source).Max;
|
||||||
|
|
||||||
|
std::list<Creature*> targets;
|
||||||
|
Trinity::AnyUnitInObjectRangeCheck u_check(source, radius);
|
||||||
|
Trinity::CreatureListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(source, targets, u_check);
|
||||||
|
Cell::VisitGridObjects(source, searcher, radius);
|
||||||
|
|
||||||
|
for (Creature* target : targets)
|
||||||
|
{
|
||||||
|
if (!source->IsHostileTo(target))
|
||||||
|
continue;
|
||||||
|
// Mow the undead down: despawn them outright so the trampled
|
||||||
|
// army vanishes (the scene's "Big Kill Credit" grants the
|
||||||
|
// quest credit, so the mobs don't need to die through the
|
||||||
|
// normal damage/corpse path).
|
||||||
|
target->DespawnOrUnsummon(0s, 1h);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Register() override
|
||||||
|
{
|
||||||
|
OnEffectHit += SpellEffectFn(spell_giant_boar_trample_305557_SpellScript::HandleDummy, EFFECT_1, SPELL_EFFECT_DUMMY);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SpellScript* GetSpellScript() const override
|
||||||
|
{
|
||||||
|
return new spell_giant_boar_trample_305557_SpellScript();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class LeaveGiantBoarEvent : public BasicEvent
|
class LeaveGiantBoarEvent : public BasicEvent
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -1086,4 +1159,5 @@ void AddSC_exiles_reach_darkmaul_plains()
|
|||||||
new spell_ride_vehicle_173426();
|
new spell_ride_vehicle_173426();
|
||||||
new spell_giant_boar_charge_321627();
|
new spell_giant_boar_charge_321627();
|
||||||
new spell_giant_boar_ping_vehicle_305559();
|
new spell_giant_boar_ping_vehicle_305559();
|
||||||
|
new spell_giant_boar_trample_305557();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -456,6 +456,8 @@ struct npc_exiles_reach_harpy_roost_153964 : public ScriptedAI
|
|||||||
if (player->HasAura(SPELL_RITUAL_SCENE_HARPY_BEAM))
|
if (player->HasAura(SPELL_RITUAL_SCENE_HARPY_BEAM))
|
||||||
player->RemoveAura(SPELL_RITUAL_SCENE_HARPY_BEAM);
|
player->RemoveAura(SPELL_RITUAL_SCENE_HARPY_BEAM);
|
||||||
|
|
||||||
|
player->KilledMonsterCredit(NPC_HARPY_ROOST_BLOODBEAK);
|
||||||
|
|
||||||
std::vector<Creature*> ritualDoneGoHome = std::vector<Creature*>{};
|
std::vector<Creature*> ritualDoneGoHome = std::vector<Creature*>{};
|
||||||
|
|
||||||
if (Creature* meredy = player->GetSummonedCreatureByEntry(NPC_HARPY_ROOST_MEREDY_RITUAL))
|
if (Creature* meredy = player->GetSummonedCreatureByEntry(NPC_HARPY_ROOST_MEREDY_RITUAL))
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public:
|
|||||||
|
|
||||||
if (player->IsInAlliance())
|
if (player->IsInAlliance())
|
||||||
{
|
{
|
||||||
WowCommunity::PhaseShift(player, { PHASE_GENERAL_DARKMAUL_PLAINS_ZOMBIES_AND_CADAVERS }, QuestsRewarded(player, { QUEST_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_DOWN_WITH_THE_QUILBOAR }) && !player->HasAura(SPELL_RIDING_GIANT_BOAR) && !player->GetQuestStatus(QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
WowCommunity::PhaseShift(player, { PHASE_GENERAL_DARKMAUL_PLAINS_ZOMBIES_AND_CADAVERS }, QuestsRewarded(player, { QUEST_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_DOWN_WITH_THE_QUILBOAR }) && !QuestCompletedOrRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_HENRY_RITUAL }, QuestsRewarded(player, { QUEST_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_DOWN_WITH_THE_QUILBOAR }) && !QuestCompletedOrRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_HENRY_RITUAL }, QuestsRewarded(player, { QUEST_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_DOWN_WITH_THE_QUILBOAR }) && !QuestCompletedOrRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_HRUNS_BARROW_RALIA_RITUAL }, QuestCompleted(player, QUEST_THE_SCOUT_O_MATIC_5000));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_HRUNS_BARROW_RALIA_RITUAL }, QuestCompleted(player, QUEST_THE_SCOUT_O_MATIC_5000));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_13395 }, QuestCompleted(player, QUEST_THE_SCOUT_O_MATIC_5000));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_13395 }, QuestCompleted(player, QUEST_THE_SCOUT_O_MATIC_5000));
|
||||||
|
|||||||
@@ -127,8 +127,9 @@ struct npc_exiles_reach_ship_166573_156280 : public ScriptedAI
|
|||||||
Talk(0, player);
|
Talk(0, player);
|
||||||
break;
|
break;
|
||||||
case QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR:
|
case QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR:
|
||||||
if (Creature* clone = player->SummonCreature(NPC_OGRE_RUINS_TORGOK_FIGHTER_A, FindSummonPosition(player, NPC_DARKMAUL_PLAINS_GARRICK), TEMPSUMMON_MANUAL_DESPAWN, 0s, 0U, 0U, player->GetGUID()))
|
// Ride the boar alone — no follower (156807 reuses Jaina's model,
|
||||||
clone->FollowTarget(player);
|
// which read as a duplicate Jaina tagging along). The quest-giver
|
||||||
|
// stays in place.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ public:
|
|||||||
{
|
{
|
||||||
WowCommunity::PhaseShift(player, { PHASE_GENERAL_DARKMAUL_PLAINS_ZOMBIES_AND_CADAVERS }, !player->HasAura(SPELL_RESIZER_SLAUGHTER) && !player->HasAura(SPELL_RIDING_GIANT_BOAR) && !player->GetQuestStatus(QUEST_H_THE_REDEATHER));
|
WowCommunity::PhaseShift(player, { PHASE_GENERAL_DARKMAUL_PLAINS_ZOMBIES_AND_CADAVERS }, !player->HasAura(SPELL_RESIZER_SLAUGHTER) && !player->HasAura(SPELL_RIDING_GIANT_BOAR) && !player->GetQuestStatus(QUEST_H_THE_REDEATHER));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_HORDE_OGRE_RUINS_SHUJA_RITUAL }, QuestsRewarded(player, { QUEST_H_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_H_DOWN_WITH_THE_QUILBOAR }) && !QuestCompletedOrRewarded(player, QUEST_H_THE_REDEATHER));
|
WowCommunity::PhaseShift(player, { PHASE_HORDE_OGRE_RUINS_SHUJA_RITUAL }, QuestsRewarded(player, { QUEST_H_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_H_DOWN_WITH_THE_QUILBOAR }) && !QuestCompletedOrRewarded(player, QUEST_H_THE_REDEATHER));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_HORDE_OGRE_RUINS_SHUJA_QUEST_REWARDER }, QuestCompleted(player, QUEST_H_THE_REDEATHER));
|
WowCommunity::PhaseShift(player, { PHASE_HORDE_OGRE_RUINS_SHUJA_QUEST_REWARDER }, QuestAcceptedOrCompleted(player, QUEST_H_THE_REDEATHER));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_HORDE_OGRE_RUINS_CAMP_OBJECTS }, QuestCompletedOrRewarded(player, QUEST_H_THE_REDEATHER));
|
WowCommunity::PhaseShift(player, { PHASE_HORDE_OGRE_RUINS_CAMP_OBJECTS }, QuestCompletedOrRewarded(player, QUEST_H_THE_REDEATHER));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_HORDE_HRUNS_BARROW_CRENNA_RITUAL }, QuestCompleted(player, QUEST_H_THE_REDEATHER));
|
WowCommunity::PhaseShift(player, { PHASE_HORDE_HRUNS_BARROW_CRENNA_RITUAL }, QuestCompleted(player, QUEST_H_THE_REDEATHER));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_HORDE_OGRE_RUINS_15330 }, QuestCompleted(player, QUEST_H_THE_REDEATHER));
|
WowCommunity::PhaseShift(player, { PHASE_HORDE_OGRE_RUINS_15330 }, QuestCompleted(player, QUEST_H_THE_REDEATHER));
|
||||||
@@ -92,7 +92,7 @@ public:
|
|||||||
|
|
||||||
if (player->IsInAlliance())
|
if (player->IsInAlliance())
|
||||||
{
|
{
|
||||||
WowCommunity::PhaseShift(player, { PHASE_GENERAL_DARKMAUL_PLAINS_ZOMBIES_AND_CADAVERS }, QuestsRewarded(player, { QUEST_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_DOWN_WITH_THE_QUILBOAR }) && !player->HasAura(SPELL_RIDING_GIANT_BOAR) && !player->GetQuestStatus(QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
WowCommunity::PhaseShift(player, { PHASE_GENERAL_DARKMAUL_PLAINS_ZOMBIES_AND_CADAVERS }, QuestsRewarded(player, { QUEST_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_DOWN_WITH_THE_QUILBOAR }) && !QuestCompletedOrRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_HENRY_RITUAL }, QuestsRewarded(player, { QUEST_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_DOWN_WITH_THE_QUILBOAR }) && !QuestCompletedOrRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_HENRY_RITUAL }, QuestsRewarded(player, { QUEST_FORBIDDEN_QUILBOAR_NECROMANCY, QUEST_DOWN_WITH_THE_QUILBOAR }) && !QuestCompletedOrRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_HRUNS_BARROW_RALIA_RITUAL }, QuestCompleted(player, QUEST_THE_SCOUT_O_MATIC_5000));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_HRUNS_BARROW_RALIA_RITUAL }, QuestCompleted(player, QUEST_THE_SCOUT_O_MATIC_5000));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_13395 }, QuestCompleted(player, QUEST_THE_SCOUT_O_MATIC_5000));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_13395 }, QuestCompleted(player, QUEST_THE_SCOUT_O_MATIC_5000));
|
||||||
@@ -111,8 +111,8 @@ public:
|
|||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_HARPY_ROOST_TOTEMS }, true);
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_HARPY_ROOST_TOTEMS }, true);
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_13836 }, true);
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_13836 }, true);
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_13815 }, true);
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_13815 }, true);
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_GARRICK_CAMP }, QuestRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR) && (!QuestRewarded(player, QUEST_MESSAGE_TO_BASE) || !QuestRewarded(player, QUEST_WESTWARD_BOUND)));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_GARRICK_CAMP }, (QuestAccepted(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR) || QuestRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR)) && (!QuestRewarded(player, QUEST_MESSAGE_TO_BASE) || !QuestRewarded(player, QUEST_WESTWARD_BOUND)));
|
||||||
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_GARRICK_BEFORE_DARKMAUL_CITADEL }, QuestRewarded(player, QUEST_MESSAGE_TO_BASE) && QuestRewarded(player, QUEST_WESTWARD_BOUND) && !QuestAcceptedOrCompleted(player, QUEST_TO_DARKMAUL_CITADEL));
|
WowCommunity::PhaseShift(player, { PHASE_ALLIANCE_OGRE_RUINS_GARRICK_BEFORE_DARKMAUL_CITADEL }, QuestRewarded(player, QUEST_RIDE_OF_THE_SCIENTIFICALLY_ENHANCED_BOAR) && !QuestAcceptedOrCompleted(player, QUEST_TO_DARKMAUL_CITADEL));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user