From df21a382979166dcaa3107eaa2716722669dbf92 Mon Sep 17 00:00:00 2001 From: StorM <49185826+Burkinc@users.noreply.github.com> Date: Wed, 7 Oct 2026 11:08:49 +0200 Subject: [PATCH] Add Master Shang Xi NPC and quest handling Implementation Start quests and logic --- .../Pandaria/zone_the_wandering_isle.cpp | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp b/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp index 076c8bc7c..536489144 100644 --- a/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp +++ b/src/server/scripts/Pandaria/zone_the_wandering_isle.cpp @@ -26,6 +26,7 @@ #include "GridNotifiersImpl.h" #include "MotionMaster.h" #include "ObjectAccessor.h" +#include "ObjectMgr.h" #include "PhasingHandler.h" #include "Player.h" #include "ScriptMgr.h" @@ -67,6 +68,30 @@ namespace Spells namespace Quests { + // Shang Xi training - Pandaren starting experience + static constexpr uint32 MuchToLearnLegacy = 29404; + static constexpr uint32 LessonIronBoughLegacy = 29405; + static constexpr uint32 LessonSandyFist = 29406; + static constexpr uint32 LessonStifledPride = 29524; + static constexpr uint32 LessonBurningScroll = 29408; + + // Class-specific Much to Learn variants + static constexpr uint32 MuchToLearnMonk = 30039; + static constexpr uint32 MuchToLearnCaster = 30040; + static constexpr uint32 MuchToLearnHunter = 30041; + static constexpr uint32 MuchToLearnPriest = 30042; + static constexpr uint32 MuchToLearnRogue = 30043; + static constexpr uint32 MuchToLearnShaman = 30044; + static constexpr uint32 MuchToLearnWarrior = 30045; + + // Class-specific Iron Bough variants + static constexpr uint32 IronBoughMonk = 30027; + static constexpr uint32 IronBoughCaster = 30033; + static constexpr uint32 IronBoughHunter = 30034; + static constexpr uint32 IronBoughPriest = 30035; + static constexpr uint32 IronBoughRogue = 30036; + static constexpr uint32 IronBoughShaman = 30037; + static constexpr uint32 IronBoughWarrior = 30038; static constexpr uint32 OnlyTheWorthyShallPass = 29421; static constexpr uint32 TheSourceOfLivelihood = 29680; static constexpr uint32 TheSpiritAndBodyOfShenzinsu = 29775; @@ -75,6 +100,8 @@ namespace Quests namespace Creatures { + static constexpr uint32 MasterShangXi = 53566; + static constexpr uint32 TrainingTarget = 53714; static constexpr uint32 MasterLiFei = 54135; static constexpr uint32 MasterLiFeiCombat = 54734; @@ -111,6 +138,87 @@ namespace Events static constexpr int8 YakCartRopes = 2; } + +// 53566 - Master Shang Xi +// Completes the missing first part of the Wandering Isle quest flow. +struct npc_master_shang_xi : public ScriptedAI +{ + npc_master_shang_xi(Creature* creature) : ScriptedAI(creature) { } + + static void OfferQuest(Player* player, uint32 questId, Creature* giver) + { + if (!player || !giver || player->GetQuestStatus(questId) != QUEST_STATUS_NONE || player->GetQuestRewardStatus(questId)) + return; + + if (Quest const* quest = sObjectMgr->GetQuestTemplate(questId)) + if (player->CanTakeQuest(quest, false)) + player->AddQuestAndCheckCompletion(quest, giver); + } + + static uint32 GetWeaponQuestForIntro(uint32 questId) + { + switch (questId) + { + case Quests::MuchToLearnMonk: return Quests::IronBoughMonk; + case Quests::MuchToLearnCaster: return Quests::IronBoughCaster; + case Quests::MuchToLearnHunter: return Quests::IronBoughHunter; + case Quests::MuchToLearnPriest: return Quests::IronBoughPriest; + case Quests::MuchToLearnRogue: return Quests::IronBoughRogue; + case Quests::MuchToLearnShaman: return Quests::IronBoughShaman; + case Quests::MuchToLearnWarrior: return Quests::IronBoughWarrior; + case Quests::MuchToLearnLegacy: return Quests::LessonIronBoughLegacy; + default: return 0; + } + } + + static bool IsWeaponQuest(uint32 questId) + { + switch (questId) + { + case Quests::LessonIronBoughLegacy: + case Quests::IronBoughMonk: + case Quests::IronBoughCaster: + case Quests::IronBoughHunter: + case Quests::IronBoughPriest: + case Quests::IronBoughRogue: + case Quests::IronBoughShaman: + case Quests::IronBoughWarrior: + return true; + default: + return false; + } + } + + void OnQuestReward(Player* player, Quest const* quest, LootItemType /*type*/, uint32 /*opt*/) override + { + uint32 questId = quest->GetQuestId(); + + if (uint32 weaponQuest = GetWeaponQuestForIntro(questId)) + { + OfferQuest(player, weaponQuest, me); + return; + } + + if (IsWeaponQuest(questId)) + { + OfferQuest(player, Quests::LessonSandyFist, me); + return; + } + + switch (questId) + { + case Quests::LessonSandyFist: + OfferQuest(player, Quests::LessonStifledPride, me); + break; + case Quests::LessonStifledPride: + OfferQuest(player, Quests::LessonBurningScroll, me); + break; + default: + break; + } + } +}; + enum TraineeMisc { SAY_FINISH_FIGHT = 0, @@ -874,6 +982,11 @@ struct npc_amberleaf_scamp : public ScriptedAI void UpdateAI(uint32 diff) override { _scheduler.Update(diff); + + if (!UpdateVictim()) + return; + + me->AttackerStateUpdate(me->GetVictim()); } private: @@ -1656,6 +1769,7 @@ void AddSC_zone_the_wandering_isle() { using namespace Scripts::Pandaria::TheWanderingIsle; + RegisterCreatureAI(npc_master_shang_xi); RegisterCreatureAI(npc_tushui_huojin_trainee); RegisterCreatureAI(npc_huojin_trainee); RegisterCreatureAI(npc_instructor_zhi);