From f2e60978498929ffc45f13fe4bec78fe14907218 Mon Sep 17 00:00:00 2001 From: Miraco Date: Tue, 21 Jan 2025 11:50:04 +0100 Subject: [PATCH 1/5] Start rework of mulgash escort quest --- sql/scriptdev2/scriptdev2.sql | 30 --- .../scripts/kalimdor/ashenvale.cpp | 200 ++++++++---------- 2 files changed, 89 insertions(+), 141 deletions(-) diff --git a/sql/scriptdev2/scriptdev2.sql b/sql/scriptdev2/scriptdev2.sql index 73adcda1c45..87e8dfc7ee6 100644 --- a/sql/scriptdev2/scriptdev2.sql +++ b/sql/scriptdev2/scriptdev2.sql @@ -6052,36 +6052,6 @@ INSERT INTO script_waypoint (Entry, PathId, Point, PositionX, PositionY, Positio (12580,0,25,-8455.95,351.225,120.88,0,0,0,''), (12580,0,26,-8446.87,339.904,121.33,5.3737,1000,0,'SAY_WINDSOR_KEEP_1'), (12580,0,27,-8446.87,339.904,121.33,0,10000,0,''), -(12717,0,1,3346.25,1007.88,3.59,0,0,0,'SAY_MUG_START2'), -(12717,0,2,3367.39,1011.51,3.72,0,0,0,''), -(12717,0,3,3418.64,1013.96,2.905,0,0,0,''), -(12717,0,4,3426.84,1015.1,3.449,0,0,0,''), -(12717,0,5,3437.03,1020.79,2.742,0,0,0,''), -(12717,0,6,3460.56,1024.26,1.353,0,0,0,''), -(12717,0,7,3479.87,1037.96,1.023,0,0,0,''), -(12717,0,8,3490.53,1043.35,3.338,0,0,0,''), -(12717,0,9,3504.28,1047.77,8.205,0,0,0,''), -(12717,0,10,3510.73,1049.79,12.143,0,0,0,''), -(12717,0,11,3514.41,1051.17,13.235,0,0,0,''), -(12717,0,12,3516.94,1052.91,12.918,0,0,0,''), -(12717,0,13,3523.64,1056.3,7.563,0,0,0,''), -(12717,0,14,3531.94,1059.86,6.175,0,0,0,''), -(12717,0,15,3535.48,1069.96,1.697,0,0,0,''), -(12717,0,16,3546.98,1093.49,0.68,0,0,0,''), -(12717,0,17,3549.73,1101.88,-1.123,0,0,0,''), -(12717,0,18,3555.14,1116.99,-4.326,0,0,0,''), -(12717,0,19,3571.94,1132.18,-0.634,0,0,0,''), -(12717,0,20,3574.28,1137.58,3.684,0,0,0,''), -(12717,0,21,3579.31,1137.25,8.205,0,0,0,''), -(12717,0,22,3590.22,1143.65,8.291,0,0,0,''), -(12717,0,23,3595.97,1145.83,6.773,0,0,0,''), -(12717,0,24,3603.65,1146.92,9.763,0,0,0,''), -(12717,0,25,3607.08,1146.01,10.692,0,5000,0,'SAY_MUG_BRAZIER'), -(12717,0,26,3614.52,1142.63,10.248,0,0,0,''), -(12717,0,27,3616.66,1140.84,10.682,0,3000,0,'SAY_MUG_PATROL'), -(12717,0,28,3621.08,1138.11,10.369,0,0,0,'SAY_MUG_RETURN'), -(12717,0,29,3615.48,1145.53,9.614,0,0,0,''), -(12717,0,30,3607.19,1152.72,8.871,0,0,0,''), (12818,0,1,3347.25,-694.701,159.926,0,0,0,''), (12818,0,2,3341.53,-694.726,161.125,0,1000,0,''), (12818,0,3,3338.35,-686.088,163.444,0,0,0,''), diff --git a/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp b/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp index b8b0a5c88eb..d205d84f1bb 100644 --- a/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp +++ b/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp @@ -37,117 +37,101 @@ EndContentData */ enum { - SAY_MUG_START1 = -1000501, - SAY_MUG_START2 = -1000502, - SAY_MUG_BRAZIER = -1000503, - SAY_MUG_BRAZIER_WAIT = -1000504, - SAY_MUG_ON_GUARD = -1000505, - SAY_MUG_REST = -1000506, - SAY_MUG_DONE = -1000507, - SAY_MUG_GRATITUDE = -1000508, - SAY_MUG_PATROL = -1000509, - SAY_MUG_RETURN = -1000510, + MUGLASH_ESCORT_PATH = 12717, + + SAY_MUGLASH_START = 8555, + SAY_MUGLASH_BRAZIER = 8556, + SAY_MUGLASH_FAIL = 8409, + SAY_MUGLASH_EVENT_01 = 8412, QUEST_VORSHA = 6641, GO_NAGA_BRAZIER = 178247, - NPC_MUGLASH = 12717, + NPC_MUGLASH = 12717, NPC_WRATH_RIDER = 3713, NPC_WRATH_SORCERESS = 3717, NPC_WRATH_RAZORTAIL = 3712, - - NPC_WRATH_PRIESTESS = 3944, - NPC_WRATH_MYRMIDON = 3711, - NPC_WRATH_SEAWITCH = 3715, - - NPC_VORSHA = 12940 }; -static float m_afFirstNagaCoord[3][3] = +enum MuglashActions { - {3603.504150f, 1122.631104f, 1.635f}, // rider - {3589.293945f, 1148.664063f, 5.565f}, // sorceress - {3609.925537f, 1168.759521f, -1.168f} // razortail + NETHEKURSE_ACTION_MAX, + MUGLASH_FAIL, + MUGLASH_EVENT }; -static float m_afSecondNagaCoord[3][3] = +static float m_afFirstNagaCoord[3][4] = { - {3609.925537f, 1168.759521f, -1.168f}, // witch - {3645.652100f, 1139.425415f, 1.322f}, // priest - {3583.602051f, 1128.405762f, 2.347f} // myrmidon + {3629.9194f, 1169.9987f, -3.4472558f, 1.37881f}, // Wrathtail Razortail + {3617.8516f, 1097.7166f, -4.0877485f, 5.67231f}, // Wrathtail Wave Rider + {3583.1497f, 1165.5658f, -5.3660164f, 1.85004f} // Wrathtail Sorceress }; -static float m_fVorshaCoord[] = {3633.056885f, 1172.924072f, -5.388f}; - struct npc_muglashAI : public npc_escortAI { npc_muglashAI(Creature* pCreature) : npc_escortAI(pCreature) { - m_uiWaveId = 0; - m_bIsBrazierExtinguished = false; Reset(); + AddCustomAction(MUGLASH_FAIL, true, [&]() { DoFailEscort(); }, TIMER_COMBAT_OOC); + AddCustomAction(MUGLASH_EVENT, true, [&]() { DoStartEvent(); }, TIMER_COMBAT_OOC); + m_uiWaveId = 0; } - bool m_bIsBrazierExtinguished; - uint32 m_uiWaveId; - uint32 m_uiEventTimer; + uint8 m_uiSummonedAlive; void Reset() override { - m_uiEventTimer = 10000; - if (!HasEscortState(STATE_ESCORT_ESCORTING)) { m_uiWaveId = 0; - m_bIsBrazierExtinguished = false; + m_uiSummonedAlive = 0; } } void Aggro(Unit* /*pWho*/) override { - if (HasEscortState(STATE_ESCORT_PAUSED)) - { - if (urand(0, 1)) - return; - - if (Player* pPlayer = GetPlayerForEscort()) - DoScriptText(SAY_MUG_ON_GUARD, m_creature, pPlayer); - } } void WaypointReached(uint32 uiPointId) override { switch (uiPointId) { - case 1: - if (Player* pPlayer = GetPlayerForEscort()) - DoScriptText(SAY_MUG_START2, m_creature, pPlayer); - break; - case 25: + case 3: if (Player* pPlayer = GetPlayerForEscort()) - DoScriptText(SAY_MUG_BRAZIER, m_creature, pPlayer); - - if (GameObject* pGo = GetClosestGameObjectWithEntry(m_creature, GO_NAGA_BRAZIER, INTERACTION_DISTANCE * 2)) { - // some kind of event flag? Update to player/group only? - pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT); - SetEscortPaused(true); + DoBroadcastText(SAY_MUGLASH_START, m_creature, pPlayer); + m_creature->HandleEmote(EMOTE_ONESHOT_TALK); } break; - case 26: - DoScriptText(SAY_MUG_GRATITUDE, m_creature); - - if (Player* pPlayer = GetPlayerForEscort()) - pPlayer->RewardPlayerAndGroupAtEventExplored(QUEST_VORSHA, m_creature); + case 9: + // Before entering Water ignore mmaps to get better pathing + m_creature->SetIgnoreMMAP(true); break; - case 27: - DoScriptText(SAY_MUG_PATROL, m_creature); + case 15: + // First point after Water + m_creature->SetIgnoreMMAP(false); break; - case 28: - DoScriptText(SAY_MUG_RETURN, m_creature); + case 18: + // Last waypoint Reached + if (Player* pPlayer = GetPlayerForEscort()) + { + DoBroadcastText(SAY_MUGLASH_BRAZIER, m_creature, pPlayer); + m_creature->HandleEmote(EMOTE_ONESHOT_TALK); + } + // Let Escort fail after 5 minutes if players dont use Naga Brazier object + ResetTimer(MUGLASH_FAIL, 300000); break; + case 19: + // Using custom point to get a 2 seconds delay after last text + // Make Naga Brazier object usable + if (GameObject* go = GetClosestGameObjectWithEntry(m_creature, GO_NAGA_BRAZIER, INTERACTION_DISTANCE * 2)) + { + go->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT); + } + // Stop waypoints at this point + SetEscortPaused(true); } } @@ -156,66 +140,58 @@ struct npc_muglashAI : public npc_escortAI switch (m_uiWaveId) { case 1: - m_creature->SummonCreature(NPC_WRATH_RIDER, m_afFirstNagaCoord[0][0], m_afFirstNagaCoord[0][1], m_afFirstNagaCoord[0][2], 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000); - m_creature->SummonCreature(NPC_WRATH_SORCERESS, m_afFirstNagaCoord[1][0], m_afFirstNagaCoord[1][1], m_afFirstNagaCoord[1][2], 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000); - m_creature->SummonCreature(NPC_WRATH_RAZORTAIL, m_afFirstNagaCoord[2][0], m_afFirstNagaCoord[2][1], m_afFirstNagaCoord[2][2], 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000); - break; - case 2: - m_creature->SummonCreature(NPC_WRATH_PRIESTESS, m_afSecondNagaCoord[0][0], m_afSecondNagaCoord[0][1], m_afSecondNagaCoord[0][2], 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000); - m_creature->SummonCreature(NPC_WRATH_MYRMIDON, m_afSecondNagaCoord[1][0], m_afSecondNagaCoord[1][1], m_afSecondNagaCoord[1][2], 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000); - m_creature->SummonCreature(NPC_WRATH_SEAWITCH, m_afSecondNagaCoord[2][0], m_afSecondNagaCoord[2][1], m_afSecondNagaCoord[2][2], 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000); - break; - case 3: - m_creature->SummonCreature(NPC_VORSHA, m_fVorshaCoord[0], m_fVorshaCoord[1], m_fVorshaCoord[2], 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000); - break; - case 4: - SetEscortPaused(false); - DoScriptText(SAY_MUG_DONE, m_creature); + m_creature->SummonCreature(NPC_WRATH_RAZORTAIL, m_afFirstNagaCoord[0][0], m_afFirstNagaCoord[0][1], m_afFirstNagaCoord[0][2], m_afFirstNagaCoord[0][3], TEMPSPAWN_TIMED_OOC_DESPAWN, true, true, 1, 60000); + m_creature->SummonCreature(NPC_WRATH_RIDER, m_afFirstNagaCoord[1][0], m_afFirstNagaCoord[1][1], m_afFirstNagaCoord[1][2], m_afFirstNagaCoord[1][3], TEMPSPAWN_TIMED_OOC_DESPAWN, true, true, 1, 60000); + m_creature->SummonCreature(NPC_WRATH_SORCERESS, m_afFirstNagaCoord[2][0], m_afFirstNagaCoord[2][1], m_afFirstNagaCoord[2][2], m_afFirstNagaCoord[2][3], TEMPSPAWN_TIMED_OOC_DESPAWN, true, true, 1, 60000); + ++m_uiWaveId; break; } } - void JustSummoned(Creature* pSummoned) override + // Failed cause players didnt use Naga Brazier object + void DoFailEscort() { - pSummoned->AI()->AttackStart(m_creature); + if (Player* pPlayer = GetPlayerForEscort()) + { + DoBroadcastText(SAY_MUGLASH_FAIL, m_creature, pPlayer); + m_creature->HandleEmote(EMOTE_ONESHOT_TALK); + } + m_creature->ForcedDespawn(1000); } - void UpdateEscortAI(const uint32 uiDiff) override - { - if (!m_creature->SelectHostileTarget() || !m_creature->GetVictim()) + // When Player activates object start Event + void DoStartEvent() + { + switch(m_uiWaveId) { - if (HasEscortState(STATE_ESCORT_PAUSED) && m_bIsBrazierExtinguished) - { - if (m_uiEventTimer < uiDiff) + case 0: + // Disable Fail timer + DisableTimer(MUGLASH_FAIL); + ++m_uiWaveId; + ResetTimer(MUGLASH_EVENT, 2000); + break; + case 1: + if (Player* pPlayer = GetPlayerForEscort()) { - ++m_uiWaveId; - DoWaveSummon(); - m_uiEventTimer = 10000; + DoBroadcastText(SAY_MUGLASH_EVENT_01, m_creature, pPlayer); } - else - m_uiEventTimer -= uiDiff; - } - - return; + // Summon first wave of adds + DoWaveSummon(); + break; } - - DoMeleeAttackIfReady(); } }; -bool QuestAccept_npc_muglash(Player* pPlayer, Creature* pCreature, const Quest* pQuest) +bool QuestAccept_npc_muglash(Player* player, Creature* creature, const Quest* quest) { - if (pQuest->GetQuestId() == QUEST_VORSHA) + if (quest->GetQuestId() == QUEST_VORSHA) { - if (npc_muglashAI* pEscortAI = dynamic_cast(pCreature->AI())) + if (npc_muglashAI* pEscortAI = dynamic_cast(creature->AI())) { - DoScriptText(SAY_MUG_START1, pCreature); - pCreature->SetFactionTemporary(FACTION_ESCORT_H_PASSIVE, TEMPFACTION_RESTORE_RESPAWN | TEMPFACTION_TOGGLE_IMMUNE_TO_NPC); - - pEscortAI->Start(false, pPlayer, pQuest); + creature->SetFactionTemporary(FACTION_ESCORT_H_NEUTRAL_PASSIVE, TEMPFACTION_RESTORE_RESPAWN); + pEscortAI->Start(false, player, quest, false, false, MUGLASH_ESCORT_PATH); } } - return true; } @@ -224,19 +200,21 @@ UnitAI* GetAI_npc_muglash(Creature* pCreature) return new npc_muglashAI(pCreature); } -bool GOUse_go_naga_brazier(Player* /*pPlayer*/, GameObject* pGo) +bool GOUse_go_naga_brazier(Player* /*pPlayer*/, GameObject* go) { - if (Creature* pCreature = GetClosestCreatureWithEntry(pGo, NPC_MUGLASH, INTERACTION_DISTANCE * 2)) + // When player finishs cast inform npc muglash + if (Creature* creature = GetClosestCreatureWithEntry(go, NPC_MUGLASH, INTERACTION_DISTANCE * 2)) { - if (npc_muglashAI* pEscortAI = dynamic_cast(pCreature->AI())) + if (npc_muglashAI* pEscortAI = dynamic_cast(creature->AI())) { - DoScriptText(SAY_MUG_BRAZIER_WAIT, pCreature); - - pEscortAI->m_bIsBrazierExtinguished = true; + // Start Event with 2 seconds delay + pEscortAI->DoStartEvent(); return false; } } - + // Make Object not interactable again and remove flames visual + go->SetGoState(GO_STATE_READY); + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT); return true; } From ceda4c084a5f23cf0c2896b0e7ec6acec58fb368 Mon Sep 17 00:00:00 2001 From: Miraco Date: Thu, 23 Jan 2025 20:40:57 +0100 Subject: [PATCH 2/5] add wave handling --- .../scripts/kalimdor/ashenvale.cpp | 235 +++++++++++++++--- 1 file changed, 204 insertions(+), 31 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp b/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp index d205d84f1bb..9c6c65cb95b 100644 --- a/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp +++ b/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp @@ -42,16 +42,32 @@ enum SAY_MUGLASH_START = 8555, SAY_MUGLASH_BRAZIER = 8556, SAY_MUGLASH_FAIL = 8409, - SAY_MUGLASH_EVENT_01 = 8412, + SAY_MUGLASH_AGGRO = 8412, + SAY_MUGLASH_EVENT_01 = 8413, + SAY_MUGLASH_EVENT_02 = 8567, + SAY_MUGLASH_EVENT_03 = 8568, + SAY_MUGLASH_SUCCESS = 8569, + SAY_MUGLASH_SUCCESS_02 = 8558, + SAY_MUGLASH_SUCCESS_03 = 8564, + SAY_MUGLASH_SUCCESS_04 = 8565, QUEST_VORSHA = 6641, GO_NAGA_BRAZIER = 178247, NPC_MUGLASH = 12717, + + // First Wave NPC_WRATH_RIDER = 3713, NPC_WRATH_SORCERESS = 3717, NPC_WRATH_RAZORTAIL = 3712, + + // 2nd Wave + NPC_WRATH_PRIESTESS = 3944, + NPC_WRATH_MYRMIDON = 3711, + NPC_WRATH_SEAWITCH = 3715, + + NPC_VORSHA = 12940, }; enum MuglashActions @@ -61,11 +77,30 @@ enum MuglashActions MUGLASH_EVENT }; -static float m_afFirstNagaCoord[3][4] = +struct firstWaveLocations +{ + uint32 uiEntry; + float fX, fY, fZ; +}; +// First Wave Data +static const firstWaveLocations nagaLocations[3] = { - {3629.9194f, 1169.9987f, -3.4472558f, 1.37881f}, // Wrathtail Razortail - {3617.8516f, 1097.7166f, -4.0877485f, 5.67231f}, // Wrathtail Wave Rider - {3583.1497f, 1165.5658f, -5.3660164f, 1.85004f} // Wrathtail Sorceress + { NPC_WRATH_RAZORTAIL, 3629.9194f, 1169.9987f, -3.4472558f}, + { NPC_WRATH_RIDER, 3617.8516f, 1097.7166f, -4.0877485f}, + { NPC_WRATH_SORCERESS, 3583.1497f, 1165.5658f, -5.3660164f} +}; + +// 2nd Wave Data +struct secondWaveLocations +{ + uint32 uiEntry; + float fX, fY, fZ; +}; +static const secondWaveLocations secondnagaLocations[3] = +{ + { NPC_WRATH_MYRMIDON, 3575.009f, 1119.8704f, -4.2547455f}, + { NPC_WRATH_SEAWITCH, 3606.9448f, 1176.3822f, -2.9632108f}, + { NPC_WRATH_PRIESTESS, 3651.5383f, 1155.5522f, -3.9628646f} }; struct npc_muglashAI : public npc_escortAI @@ -75,23 +110,34 @@ struct npc_muglashAI : public npc_escortAI Reset(); AddCustomAction(MUGLASH_FAIL, true, [&]() { DoFailEscort(); }, TIMER_COMBAT_OOC); AddCustomAction(MUGLASH_EVENT, true, [&]() { DoStartEvent(); }, TIMER_COMBAT_OOC); - m_uiWaveId = 0; + m_uiEventId = 0; } - uint32 m_uiWaveId; - uint8 m_uiSummonedAlive; + uint32 m_uiEventId; + uint8 m_uiWaveOneAlive; + uint8 m_uiWaveTwoAlive; + bool m_Wave; void Reset() override { if (!HasEscortState(STATE_ESCORT_ESCORTING)) { - m_uiWaveId = 0; - m_uiSummonedAlive = 0; + m_uiEventId = 0; + m_uiWaveOneAlive = 0; + m_uiWaveTwoAlive = 0; } } void Aggro(Unit* /*pWho*/) override { + if (HasEscortState(STATE_ESCORT_PAUSED)) + { + if (urand(0, 1)) + return; + + if (Player* player = GetPlayerForEscort()) + DoBroadcastText(SAY_MUGLASH_AGGRO, m_creature, player); + } } void WaypointReached(uint32 uiPointId) override @@ -99,9 +145,9 @@ struct npc_muglashAI : public npc_escortAI switch (uiPointId) { case 3: - if (Player* pPlayer = GetPlayerForEscort()) + if (Player* player = GetPlayerForEscort()) { - DoBroadcastText(SAY_MUGLASH_START, m_creature, pPlayer); + DoBroadcastText(SAY_MUGLASH_START, m_creature, player); m_creature->HandleEmote(EMOTE_ONESHOT_TALK); } break; @@ -115,9 +161,9 @@ struct npc_muglashAI : public npc_escortAI break; case 18: // Last waypoint Reached - if (Player* pPlayer = GetPlayerForEscort()) + if (Player* player = GetPlayerForEscort()) { - DoBroadcastText(SAY_MUGLASH_BRAZIER, m_creature, pPlayer); + DoBroadcastText(SAY_MUGLASH_BRAZIER, m_creature, player); m_creature->HandleEmote(EMOTE_ONESHOT_TALK); } // Let Escort fail after 5 minutes if players dont use Naga Brazier object @@ -132,51 +178,178 @@ struct npc_muglashAI : public npc_escortAI } // Stop waypoints at this point SetEscortPaused(true); + break; + case 20: + // Stop waypoints at this point + SetEscortPaused(true); + break; + case 21: + SetEscortPaused(true); + ResetTimer(MUGLASH_EVENT, 2000); + m_uiEventId = 4; + break; + } + } + + void JustSummoned(Creature* summoned) override + { + // Ignore mmap so they can get out of water without strange movement + summoned->SetIgnoreMMAP(true); + summoned->GetMotionMaster()->MovePath(1); + + switch (summoned->GetEntry()) + { + case NPC_WRATH_RAZORTAIL: + case NPC_WRATH_RIDER: + case NPC_WRATH_SORCERESS: + ++m_uiWaveOneAlive; + break; + case NPC_WRATH_MYRMIDON: + case NPC_WRATH_SEAWITCH: + case NPC_WRATH_PRIESTESS: + ++m_uiWaveTwoAlive; + break; } } - void DoWaveSummon() + void SummonedCreatureJustDied(Creature* summoned) override { - switch (m_uiWaveId) + switch (summoned->GetEntry()) { - case 1: - m_creature->SummonCreature(NPC_WRATH_RAZORTAIL, m_afFirstNagaCoord[0][0], m_afFirstNagaCoord[0][1], m_afFirstNagaCoord[0][2], m_afFirstNagaCoord[0][3], TEMPSPAWN_TIMED_OOC_DESPAWN, true, true, 1, 60000); - m_creature->SummonCreature(NPC_WRATH_RIDER, m_afFirstNagaCoord[1][0], m_afFirstNagaCoord[1][1], m_afFirstNagaCoord[1][2], m_afFirstNagaCoord[1][3], TEMPSPAWN_TIMED_OOC_DESPAWN, true, true, 1, 60000); - m_creature->SummonCreature(NPC_WRATH_SORCERESS, m_afFirstNagaCoord[2][0], m_afFirstNagaCoord[2][1], m_afFirstNagaCoord[2][2], m_afFirstNagaCoord[2][3], TEMPSPAWN_TIMED_OOC_DESPAWN, true, true, 1, 60000); - ++m_uiWaveId; + // First Wave + case NPC_WRATH_RAZORTAIL: + case NPC_WRATH_RIDER: + case NPC_WRATH_SORCERESS: + // Not all dead + if (m_uiWaveOneAlive != 0) + { + --m_uiWaveOneAlive; + } + // Continue Event if all are dead and spawn 2nd wave already + else if (m_uiWaveOneAlive == 0) + { + for (auto& i : secondnagaLocations) + m_creature->SummonCreature(i.uiEntry, i.fX, i.fY, i.fZ, 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000, true, true); + m_uiEventId = 2; + ResetTimer(MUGLASH_EVENT, 5000); + } + break; + case NPC_WRATH_MYRMIDON: + case NPC_WRATH_SEAWITCH: + case NPC_WRATH_PRIESTESS: + if (m_uiWaveTwoAlive != 0) + { + --m_uiWaveTwoAlive; + } + // If 2nd Wave is Dead go to next waypoint and spawn Vorsha + else if (m_uiWaveTwoAlive == 0) + { + m_creature->SummonCreature(NPC_VORSHA, 3630.2092f, 1190.3536f, -16.624332f, 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000, true, false); + SetEscortPaused(false); // go to next waypoint + } break; } + + // Vorsha killed + if (summoned->GetEntry() == NPC_VORSHA) + { + ResetTimer(MUGLASH_EVENT, 2000); + m_uiEventId = 6; + } } // Failed cause players didnt use Naga Brazier object void DoFailEscort() { - if (Player* pPlayer = GetPlayerForEscort()) + if (Player* player = GetPlayerForEscort()) { - DoBroadcastText(SAY_MUGLASH_FAIL, m_creature, pPlayer); + DoBroadcastText(SAY_MUGLASH_FAIL, m_creature, player); m_creature->HandleEmote(EMOTE_ONESHOT_TALK); } + // Make Object not interactable when it quest failed + if (GameObject* go = GetClosestGameObjectWithEntry(m_creature, GO_NAGA_BRAZIER, INTERACTION_DISTANCE * 2)) + { + go->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT); + } m_creature->ForcedDespawn(1000); } // When Player activates object start Event void DoStartEvent() { - switch(m_uiWaveId) + switch(m_uiEventId) { case 0: - // Disable Fail timer + // Disable Fail timer, player used object DisableTimer(MUGLASH_FAIL); - ++m_uiWaveId; + ++m_uiEventId; ResetTimer(MUGLASH_EVENT, 2000); break; - case 1: - if (Player* pPlayer = GetPlayerForEscort()) + case 1: + if (Player* player = GetPlayerForEscort()) + DoBroadcastText(SAY_MUGLASH_AGGRO, m_creature, player); + // Summon first wave of adds + for (auto& i : nagaLocations) + m_creature->SummonCreature(i.uiEntry, i.fX, i.fY, i.fZ, 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000, true, true); + SetEscortPaused(false); // go to next waypoint + break; + case 2: + // Rest after first wave is dead + DoBroadcastText(SAY_MUGLASH_EVENT_01, m_creature); + m_creature->SetStandState(UNIT_STAND_STATE_SIT); + ResetTimer(MUGLASH_EVENT, 9000); + ++m_uiEventId; + break; + case 3: + // 2nd wave comes to muglash + m_creature->SetStandState(UNIT_STAND_STATE_SIT); + ++m_uiEventId; + break; + case 4: + // 2nd wave is dead + DoBroadcastText(SAY_MUGLASH_EVENT_02, m_creature); + ++m_uiEventId; + ResetTimer(MUGLASH_EVENT, 3000); + break; + case 5: + m_creature->HandleEmote(EMOTE_ONESHOT_POINT); + DoBroadcastText(SAY_MUGLASH_EVENT_03, m_creature); + break; + case 6: + m_creature->HandleEmote(EMOTE_ONESHOT_CHEER); + if (Player* player = GetPlayerForEscort()) + DoBroadcastText(SAY_MUGLASH_SUCCESS, m_creature, player); + ++m_uiEventId; + ResetTimer(MUGLASH_EVENT, 8000); + break; + case 7: + if (Player* player = GetPlayerForEscort()) { - DoBroadcastText(SAY_MUGLASH_EVENT_01, m_creature, pPlayer); + // Award quest credit + player->RewardPlayerAndGroupAtEventExplored(QUEST_VORSHA, m_creature); } - // Summon first wave of adds - DoWaveSummon(); + m_creature->HandleEmote(EMOTE_ONESHOT_BOW); + if (Player* player = GetPlayerForEscort()) + DoBroadcastText(SAY_MUGLASH_SUCCESS_02, m_creature, player); + ++m_uiEventId; + ResetTimer(MUGLASH_EVENT, 3000); + break; + case 8: + m_creature->HandleEmote(EMOTE_ONESHOT_TALK); + DoBroadcastText(SAY_MUGLASH_SUCCESS_03, m_creature); + ++m_uiEventId; + ResetTimer(MUGLASH_EVENT, 5000); + break; + case 9: + DoBroadcastText(SAY_MUGLASH_SUCCESS_04, m_creature); + ++m_uiEventId; + ResetTimer(MUGLASH_EVENT, 5000); + break; + case 10: + // Escort Finished, move random around point before despawning + m_creature->GetMotionMaster()->MoveRandomAroundPoint(m_creature->GetPositionX(), m_creature->GetPositionY(), m_creature->GetPositionZ(), 5.0f); + End(); + m_creature->ForcedDespawn(14000); // Despawn after 14 break; } } From ff4ecda1e68ddf10803b00f060edb72ae6ee83d9 Mon Sep 17 00:00:00 2001 From: Miraco Date: Fri, 24 Jan 2025 11:26:50 +0100 Subject: [PATCH 3/5] fix wave spawning --- .../scripts/kalimdor/ashenvale.cpp | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp b/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp index 9c6c65cb95b..9fa7eb2c9fb 100644 --- a/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp +++ b/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp @@ -43,14 +43,16 @@ enum SAY_MUGLASH_BRAZIER = 8556, SAY_MUGLASH_FAIL = 8409, SAY_MUGLASH_AGGRO = 8412, - SAY_MUGLASH_EVENT_01 = 8413, - SAY_MUGLASH_EVENT_02 = 8567, - SAY_MUGLASH_EVENT_03 = 8568, + SAY_MUGLASH_EVENT_01 = 8410, + SAY_MUGLASH_EVENT_02 = 8413, + SAY_MUGLASH_EVENT_03 = 8567, + SAY_MUGLASH_EVENT_04 = 8568, SAY_MUGLASH_SUCCESS = 8569, SAY_MUGLASH_SUCCESS_02 = 8558, SAY_MUGLASH_SUCCESS_03 = 8564, SAY_MUGLASH_SUCCESS_04 = 8565, + SPELL_MUGLASH_WAITING = 20861, QUEST_VORSHA = 6641, GO_NAGA_BRAZIER = 178247, @@ -67,6 +69,7 @@ enum NPC_WRATH_MYRMIDON = 3711, NPC_WRATH_SEAWITCH = 3715, + // 3rd Wave NPC_VORSHA = 12940, }; @@ -109,7 +112,7 @@ struct npc_muglashAI : public npc_escortAI { Reset(); AddCustomAction(MUGLASH_FAIL, true, [&]() { DoFailEscort(); }, TIMER_COMBAT_OOC); - AddCustomAction(MUGLASH_EVENT, true, [&]() { DoStartEvent(); }, TIMER_COMBAT_OOC); + AddCustomAction(MUGLASH_EVENT, true, [&]() { DoStartEvent(); }, TIMER_ALWAYS); m_uiEventId = 0; } @@ -180,7 +183,7 @@ struct npc_muglashAI : public npc_escortAI SetEscortPaused(true); break; case 20: - // Stop waypoints at this point + // First Wave spawned disable waypoints for now SetEscortPaused(true); break; case 21: @@ -220,13 +223,9 @@ struct npc_muglashAI : public npc_escortAI case NPC_WRATH_RAZORTAIL: case NPC_WRATH_RIDER: case NPC_WRATH_SORCERESS: - // Not all dead - if (m_uiWaveOneAlive != 0) - { - --m_uiWaveOneAlive; - } + --m_uiWaveOneAlive; // Continue Event if all are dead and spawn 2nd wave already - else if (m_uiWaveOneAlive == 0) + if (m_uiWaveOneAlive == 0) { for (auto& i : secondnagaLocations) m_creature->SummonCreature(i.uiEntry, i.fX, i.fY, i.fZ, 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000, true, true); @@ -237,12 +236,9 @@ struct npc_muglashAI : public npc_escortAI case NPC_WRATH_MYRMIDON: case NPC_WRATH_SEAWITCH: case NPC_WRATH_PRIESTESS: - if (m_uiWaveTwoAlive != 0) - { - --m_uiWaveTwoAlive; - } + --m_uiWaveTwoAlive; // If 2nd Wave is Dead go to next waypoint and spawn Vorsha - else if (m_uiWaveTwoAlive == 0) + if (m_uiWaveTwoAlive == 0) { m_creature->SummonCreature(NPC_VORSHA, 3630.2092f, 1190.3536f, -16.624332f, 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000, true, false); SetEscortPaused(false); // go to next waypoint @@ -287,15 +283,15 @@ struct npc_muglashAI : public npc_escortAI break; case 1: if (Player* player = GetPlayerForEscort()) - DoBroadcastText(SAY_MUGLASH_AGGRO, m_creature, player); + DoBroadcastText(SAY_MUGLASH_EVENT_01, m_creature, player); // Summon first wave of adds for (auto& i : nagaLocations) m_creature->SummonCreature(i.uiEntry, i.fX, i.fY, i.fZ, 0.0f, TEMPSPAWN_TIMED_OOC_DESPAWN, 60000, true, true); SetEscortPaused(false); // go to next waypoint break; case 2: - // Rest after first wave is dead - DoBroadcastText(SAY_MUGLASH_EVENT_01, m_creature); + // First Wave is Dead rest now + DoBroadcastText(SAY_MUGLASH_EVENT_02, m_creature); m_creature->SetStandState(UNIT_STAND_STATE_SIT); ResetTimer(MUGLASH_EVENT, 9000); ++m_uiEventId; @@ -307,13 +303,13 @@ struct npc_muglashAI : public npc_escortAI break; case 4: // 2nd wave is dead - DoBroadcastText(SAY_MUGLASH_EVENT_02, m_creature); + DoBroadcastText(SAY_MUGLASH_EVENT_03, m_creature); ++m_uiEventId; ResetTimer(MUGLASH_EVENT, 3000); break; case 5: m_creature->HandleEmote(EMOTE_ONESHOT_POINT); - DoBroadcastText(SAY_MUGLASH_EVENT_03, m_creature); + DoBroadcastText(SAY_MUGLASH_EVENT_04, m_creature); break; case 6: m_creature->HandleEmote(EMOTE_ONESHOT_CHEER); From a8aee7344260e745d4b03616cf5147a28ab5ec93 Mon Sep 17 00:00:00 2001 From: Miraco Date: Thu, 30 Jan 2025 19:13:43 +0100 Subject: [PATCH 4/5] remoe unneeded texts from database --- sql/scriptdev2/scriptdev2.sql | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/sql/scriptdev2/scriptdev2.sql b/sql/scriptdev2/scriptdev2.sql index 87e8dfc7ee6..427d9447647 100644 --- a/sql/scriptdev2/scriptdev2.sql +++ b/sql/scriptdev2/scriptdev2.sql @@ -1919,17 +1919,6 @@ INSERT INTO script_texts (entry,content_default,sound,type,language,emote,broadc ('-1000499','Puny $r wanna fight Overlord Mok''Morokk? Me beat you! Me boss here!','0','0','1','0','1515','morokk SAY_MOR_CHALLENGE'), ('-1000500','Me scared! Me run now!','0','1','0','0','1523','morokk SAY_MOR_SCARED'), -('-1000501','Are you sure that you are ready? If we do not have a group of your allies to aid us, we will surely fail.','0','0','1','0','8566','muglash SAY_MUG_START1'), -('-1000502','This will be a tough fight, $N. Follow me closely!','0','0','1','0','8555','muglash SAY_MUG_START2'), -('-1000503','This is the brazier, $N. Put it out. Vorsha is a beast, worthy of praise from no one!','0','0','1','0','8556','muglash SAY_MUG_BRAZIER'), -('-1000504','Now we must wait, $N. It won''t be long before the naga realize what we have done.','0','0','1','0','8410','muglash SAY_MUG_BRAZIER_WAIT'), -('-1000505','Be on your guard, $N!','0','0','1','0','8412','muglash SAY_MUG_ON_GUARD'), -('-1000506','Perhaps we will get a moment to rest. But I will not give up until we have faced off against Vorsha!','0','0','1','0','8413','muglash SAY_MUG_REST'), -('-1000507','We have done it, $N!','0','0','1','0','8569','muglash SAY_MUG_DONE'), -('-1000508','You have my deepest gratitude, $N. I thank you.','0','0','1','0','8558','muglash SAY_MUG_GRATITUDE'), -('-1000509','I am going to patrol the area for a while longer and ensure that things are truly safe.','0','0','1','0','8564','muglash SAY_MUG_PATROL'), -('-1000510','Please return to Zoram''gar and report our success to the Warsong Runner.','0','0','1','0','8565','muglash SAY_MUG_RETURN'), - ('-1000511','Aright, listen up! Form a circle around me and move out!','0','0','0','0','20314','letoll SAY_LE_START'), ('-1000512','Aright, $r, just keep us safe from harm while we work. We''ll pay you when we return.','0','0','0','0','20328','letoll SAY_LE_KEEP_SAFE'), ('-1000513','The dig site is just north of here.','0','0','0','0','20329','letoll SAY_LE_NORTH'), From a56fe9e72c8d1891b985334095e093e8283c06cc Mon Sep 17 00:00:00 2001 From: Miraco Date: Thu, 30 Jan 2025 19:42:30 +0100 Subject: [PATCH 5/5] no need to have this outside the switch --- src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp b/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp index 9fa7eb2c9fb..d9e0ef52498 100644 --- a/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp +++ b/src/game/AI/ScriptDevAI/scripts/kalimdor/ashenvale.cpp @@ -244,13 +244,11 @@ struct npc_muglashAI : public npc_escortAI SetEscortPaused(false); // go to next waypoint } break; - } + case NPC_VORSHA: + ResetTimer(MUGLASH_EVENT, 2000); + m_uiEventId = 6; + break; - // Vorsha killed - if (summoned->GetEntry() == NPC_VORSHA) - { - ResetTimer(MUGLASH_EVENT, 2000); - m_uiEventId = 6; } }