From 2deb0371df63670956053d200365da7df702a20d Mon Sep 17 00:00:00 2001 From: ThrisStraizo <45871917+ThrisStraizo@users.noreply.github.com> Date: Sun, 12 Apr 2026 16:19:28 -0700 Subject: [PATCH] Return to the Depths implementation This PR implements the quest Return to the Depths and the framework for the battlefield fight. --- .../Mine_Shaft_2716/return_to_the_depths.lua | 69 ++++ scripts/enum/item.lua | 2 + scripts/globals/quests.lua | 2 +- .../quests/bastok/Return_to_the_Depths.lua | 306 ++++++++++++++++++ scripts/zones/Mine_Shaft_2716/IDs.lua | 1 + sql/mob_spawn_points.sql | 42 +-- 6 files changed, 400 insertions(+), 22 deletions(-) create mode 100644 scripts/battlefields/Mine_Shaft_2716/return_to_the_depths.lua create mode 100644 scripts/quests/bastok/Return_to_the_Depths.lua diff --git a/scripts/battlefields/Mine_Shaft_2716/return_to_the_depths.lua b/scripts/battlefields/Mine_Shaft_2716/return_to_the_depths.lua new file mode 100644 index 00000000000..0340cb85e51 --- /dev/null +++ b/scripts/battlefields/Mine_Shaft_2716/return_to_the_depths.lua @@ -0,0 +1,69 @@ +----------------------------------- +-- Return to the Depths +-- Quest 1 78 +-- Uncapped on retail, but capped at 40 in 75 era. +----------------------------------- +local mineshaftID = zones[xi.zone.MINE_SHAFT_2716] +----------------------------------- + +local content = BattlefieldQuest:new({ + zoneId = xi.zone.MINE_SHAFT_2716, + battlefieldId = xi.battlefield.id.RETURN_TO_THE_DEPTHS, + maxPlayers = 6, + levelCap = 99, + timeLimit = utils.minutes(30), + index = 1, + entryNpc = '_0d0', + exitNpcs = { '_0d1', '_0d2', '_0d3' }, + + questArea = xi.questLog.BASTOK, + quest = xi.quest.id.bastok.RETURN_TO_THE_DEPTHS, + requiredVar = 'Quest[1][78]Prog', + requiredValue = 9, +}) + +content.groups = +{ + { + mobIds = + { + { + mineshaftID.mob.TWILOTAK, + mineshaftID.mob.TWILOTAK + 1, + mineshaftID.mob.TWILOTAK + 2, + mineshaftID.mob.TWILOTAK + 3, + mineshaftID.mob.TWILOTAK + 4, + mineshaftID.mob.TWILOTAK + 5, + mineshaftID.mob.TWILOTAK + 6, + }, + + { + mineshaftID.mob.TWILOTAK + 7, + mineshaftID.mob.TWILOTAK + 8, + mineshaftID.mob.TWILOTAK + 9, + mineshaftID.mob.TWILOTAK + 10, + mineshaftID.mob.TWILOTAK + 11, + mineshaftID.mob.TWILOTAK + 12, + mineshaftID.mob.TWILOTAK + 13, + }, + + { + mineshaftID.mob.TWILOTAK + 14, + mineshaftID.mob.TWILOTAK + 15, + mineshaftID.mob.TWILOTAK + 16, + mineshaftID.mob.TWILOTAK + 17, + mineshaftID.mob.TWILOTAK + 18, + mineshaftID.mob.TWILOTAK + 19, + mineshaftID.mob.TWILOTAK + 20, + }, + }, + + superlink = true, + + allDeath = function(battlefield, mob) + battlefield:setStatus(xi.battlefield.status.WON) + end, + }, +} + +return content:register() diff --git a/scripts/enum/item.lua b/scripts/enum/item.lua index cffba610cf7..959adc64e62 100644 --- a/scripts/enum/item.lua +++ b/scripts/enum/item.lua @@ -1096,6 +1096,7 @@ xi.item = SEALION_CREST_KEY = 1658, CORAL_CREST_KEY = 1659, BRONZE_KEY = 1660, + MISAREAUX_GARLIC = 1661, CATHEDRAL_TAPESTRY = 1662, ARNICA_ROOT = 1663, EASTERN_GEM = 1664, @@ -6301,6 +6302,7 @@ xi.item = VARIABLE_RING = 14653, VENERER_RING = 14655, DUCAL_GUARDS_RING = 14657, + BOWYER_RING = 14660, TELEPORT_RING_HOLLA = 14661, TELEPORT_RING_DEM = 14662, TELEPORT_RING_MEA = 14663, diff --git a/scripts/globals/quests.lua b/scripts/globals/quests.lua index 27d775b971f..01c706b2984 100644 --- a/scripts/globals/quests.lua +++ b/scripts/globals/quests.lua @@ -201,7 +201,7 @@ xi.quest.id = OUT_OF_THE_DEPTHS = 75, -- + Converted ALL_BY_MYSELF = 76, A_QUESTION_OF_FAITH = 77, -- + Converted - RETURN_OF_THE_DEPTHS = 78, + RETURN_TO_THE_DEPTHS = 78, -- + Converted TEAK_ME_TO_THE_STARS = 79, -- + Converted HYPER_ACTIVE = 80, THE_NAMING_GAME = 81, diff --git a/scripts/quests/bastok/Return_to_the_Depths.lua b/scripts/quests/bastok/Return_to_the_Depths.lua new file mode 100644 index 00000000000..9fa3b75e821 --- /dev/null +++ b/scripts/quests/bastok/Return_to_the_Depths.lua @@ -0,0 +1,306 @@ +----------------------------------- +-- Return to the Depths +----------------------------------- +-- Log ID: 1, Quest ID: 78 +----------------------------------- +-- Area: Metalworks +-- NPC: Ayame !pos 132 -18 33 237 +-- NPC: Rakorok !pos 158 13 -42 11 +----------------------------------- + +local quest = Quest:new(xi.questLog.BASTOK, xi.quest.id.bastok.RETURN_TO_THE_DEPTHS) + +quest.reward = +{ + fame = 50, + fameArea = xi.fameArea.BASTOK, + item = xi.item.BOWYER_RING, + title = xi.title.GOBLIN_IN_DISGUISE, +} + +quest.sections = +{ + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_AVAILABLE and + player:getFameLevel(xi.fameArea.BASTOK) >= 5 and + player:hasCompletedQuest(xi.questLog.BASTOK, xi.quest.id.bastok.A_QUESTION_OF_FAITH) + end, + + [xi.zone.METALWORKS] = + { + ['Ayame'] = quest:progressEvent(879), + + onEventFinish = + { + [879] = function(player, csid, option, npc) + quest:begin(player) + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED + end, + + [xi.zone.METALWORKS] = + { + ['Ayame'] = + { + onTrigger = function(player, npc) + local progress = quest:getVar(player, 'Prog') + + if progress == 0 then + return quest:event(880) + elseif progress == 10 then + return quest:progressEvent(881) + end + end, + }, + + onEventFinish = + { + [881] = function(player, csid, option, npc) + quest:complete(player) + end, + }, + }, + + [xi.zone.OLDTON_MOVALPOLOS] = + { + onZoneIn = function(player) + local progress = quest:getVar(player, 'Prog') + + if progress == 0 then + return 40 + elseif progress == 5 then + return 41 + end + end, + + ['Tarnotik'] = + { + onTrade = function(player, npc, trade) + if + quest:getVar(player, 'Prog') >= 7 and + npcUtil.tradeHas(trade, { xi.item.BOTTLE_OF_AHRIMAN_TEARS }) + then + return quest:progressEvent(44) + end + end, + + onTrigger = function(player, npc) + local progress = quest:getVar(player, 'Prog') + + if progress == 6 then + return quest:progressEvent(42, 11, 131456, 384, 0, xi.item.MISAREAUX_GARLIC) + elseif progress >= 7 then + return quest:event(43):oncePerZone() + end + end, + }, + + onEventFinish = + { + [40] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 1) + end, + + [41] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 6) + end, + + [42] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 7) + end, + + [44] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 8) + player:tradeComplete() + player:setPos(-93.657, -120.000, -583.561, 232, xi.zone.MINE_SHAFT_2716) + end, + }, + }, + + [xi.zone.LOWER_JEUNO] = + { + ['Muckvix'] = + { + onTrade = function(player, npc, trade) + if + quest:getVar(player, 'Prog') == 1 and + npcUtil.tradeHas(trade, { xi.item.MISAREAUX_GARLIC }) + then + return quest:progressEvent(99, 1, 1, 3, 0, xi.item.MISAREAUX_GARLIC) + end + end, + + onTrigger = function(player, npc) + local progress = quest:getVar(player, 'Prog') + + if progress == 2 then + return quest:event(46):oncePerZone() + elseif + progress == 4 and + player:hasKeyItem(xi.ki.LETTER_FROM_MAGRIFFON) and + player:hasKeyItem(xi.ki.PROVIDENCE_POT) + then + return quest:progressEvent(100) + elseif progress == 5 then + return quest:event(47):oncePerZone() + end + end, + }, + + onEventFinish = + { + [99] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 2) + player:tradeComplete() + npcUtil.giveKeyItem(player, xi.ki.LETTER_FROM_MUCKVIX) + npcUtil.giveCurrency(player, 'gil', 2000) + end, + + [100] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 5) + npcUtil.giveKeyItem(player, xi.ki.PUNGENT_PROVIDENCE_POT) + player:delKeyItem(xi.ki.PROVIDENCE_POT) + player:delKeyItem(xi.ki.LETTER_FROM_MAGRIFFON) + end, + }, + }, + + [xi.zone.KAZHAM] = + { + ['Magriffon'] = + { + onTrade = function(player, npc, trade) + if + quest:getVar(player, 'Prog') == 3 and + trade:getGil() == 10000 + then + return quest:progressEvent(301, 1, xi.ki.PROVIDENCE_POT) + end + end, + + onTrigger = function(player, npc) + if + quest:getVar(player, 'Prog') == 2 and + player:hasKeyItem(xi.ki.LETTER_FROM_MUCKVIX) + then + return quest:progressEvent(299, 75, xi.ki.PROVIDENCE_POT, 10000) + end + end, + }, + + onEventFinish = + { + [299] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 3) + player:delKeyItem(xi.ki.LETTER_FROM_MUCKVIX) + end, + + [301] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 4) + player:tradeComplete() + npcUtil.giveKeyItem(player, xi.ki.PROVIDENCE_POT) + npcUtil.giveKeyItem(player, xi.ki.LETTER_FROM_MAGRIFFON) + end, + }, + }, + + [xi.zone.MINE_SHAFT_2716] = + { + ['_0d0'] = + { + onTrigger = function(player, npc) + if quest:getVar(player, 'Prog') == 8 then + return quest:progressEvent(5, 1, 131456, 384, 0, xi.item.MISAREAUX_GARLIC) + end + end, + }, + + onEventFinish = + { + [5] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 9) + end, + + [32001] = function(player, csid, option, npc) + if player:getLocalVar('battlefieldWin') == xi.battlefield.id.RETURN_TO_THE_DEPTHS then + quest:setVar(player, 'Prog', 10) + npcUtil.giveCurrency(player, 'gil', 10000) + end + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_COMPLETED + end, + + [xi.zone.METALWORKS] = + { + ['Ayame'] = + { + onTrigger = function(player, npc) + return quest:event(882) + end, + }, + }, + + [xi.zone.OLDTON_MOVALPOLOS] = + { + ['Tarnotik'] = + { + onTrade = function(player, npc, trade) + if npcUtil.tradeHas(trade, { xi.item.BOTTLE_OF_AHRIMAN_TEARS }) then + return quest:event(44) + end + end, + + onTrigger = function(player, npc) + return quest:event(45):oncePerZone() + end, + }, + + onEventFinish = + { + [44] = function(player, csid, option, npc) + player:tradeComplete() + player:setPos(-93.657, -120.000, -583.561, 232, xi.zone.MINE_SHAFT_2716) + end, + }, + }, + + [xi.zone.PORT_BASTOK] = + { + ['Ravorara'] = + { + onTrigger = function(player, npc) + if player:hasKeyItem(xi.ki.PUNGENT_PROVIDENCE_POT) then + return quest:progressEvent(313, 0, 0, 0, xi.ki.PUNGENT_PROVIDENCE_POT) + else + return quest:event(314) + end + end, + }, + + onEventFinish = + { + [313] = function(player, csid, option, npc) + if option == 1 then + npcUtil.giveCurrency(player, 'gil', 1000) + player:delKeyItem(xi.ki.PUNGENT_PROVIDENCE_POT) + end + end, + }, + }, + }, +} + +return quest diff --git a/scripts/zones/Mine_Shaft_2716/IDs.lua b/scripts/zones/Mine_Shaft_2716/IDs.lua index e0ba3c96e1e..8aff21c071b 100644 --- a/scripts/zones/Mine_Shaft_2716/IDs.lua +++ b/scripts/zones/Mine_Shaft_2716/IDs.lua @@ -44,6 +44,7 @@ zones[xi.zone.MINE_SHAFT_2716] = MOVAMUQ = GetFirstID('Movamuq'), SWIPOSTIK = GetFirstID('Swipostik'), TRIKOTRAK = GetFirstID('Trikotrak'), + TWILOTAK = GetFirstID('Twilotak'), }, npc = { diff --git a/sql/mob_spawn_points.sql b/sql/mob_spawn_points.sql index 546651b3a0b..100acf6a8d4 100644 --- a/sql/mob_spawn_points.sql +++ b/sql/mob_spawn_points.sql @@ -2722,27 +2722,27 @@ INSERT INTO `mob_spawn_points` VALUES (16830478,0,'Swipostik','Swipostik',4,62,6 INSERT INTO `mob_spawn_points` VALUES (16830479,0,'Bugbby','Bugbby',5,63,64,499.802,-117.968,20.198,67); -- Return to the Depths -INSERT INTO `mob_spawn_points` VALUES (16830480,0,'Twilotak','Twilotak',6,40,40,-460.000,121.532,20.000,64); -INSERT INTO `mob_spawn_points` VALUES (16830481,0,'Moblin_Wisewoman','Moblin Wisewoman',7,40,40,-465.500,121.500,28.000,64); -INSERT INTO `mob_spawn_points` VALUES (16830482,0,'Moblin_Clergyman','Moblin Clergyman',8,40,40,-463.500,121.500,30.000,64); -INSERT INTO `mob_spawn_points` VALUES (16830483,0,'Moblin_Wisewoman','Moblin Wisewoman',7,40,40,-461.500,121.486,32.000,64); -INSERT INTO `mob_spawn_points` VALUES (16830484,0,'Moblin_Clergyman','Moblin Clergyman',8,40,40,-458.500,121.500,32.000,64); -INSERT INTO `mob_spawn_points` VALUES (16830485,0,'Moblin_Wisewoman','Moblin Wisewoman',7,40,40,-456.500,121.500,30.000,64); -INSERT INTO `mob_spawn_points` VALUES (16830486,0,'Moblin_Clergyman','Moblin Clergyman',8,40,40,-454.500,121.500,28.000,64); -INSERT INTO `mob_spawn_points` VALUES (16830487,0,'Twilotak','Twilotak',6,40,40,0.000,0.000,0.000,64); -INSERT INTO `mob_spawn_points` VALUES (16830488,0,'Moblin_Wisewoman','Moblin Wisewoman',7,40,40,14.482,1.500,27.937,64); -INSERT INTO `mob_spawn_points` VALUES (16830489,0,'Moblin_Clergyman','Moblin Clergyman',8,40,40,16.482,1.500,29.937,64); -INSERT INTO `mob_spawn_points` VALUES (16830490,0,'Moblin_Wisewoman','Moblin Wisewoman',7,40,40,18.482,1.486,31.937,64); -INSERT INTO `mob_spawn_points` VALUES (16830491,0,'Moblin_Clergyman','Moblin Clergyman',8,40,40,21.482,1.500,31.937,64); -INSERT INTO `mob_spawn_points` VALUES (16830492,0,'Moblin_Wisewoman','Moblin Wisewoman',7,40,40,23.482,1.500,29.937,64); -INSERT INTO `mob_spawn_points` VALUES (16830493,0,'Moblin_Clergyman','Moblin Clergyman',8,40,40,25.482,1.500,27.937,64); -INSERT INTO `mob_spawn_points` VALUES (16830494,0,'Twilotak','Twilotak',6,40,40,499.951,-118.468,19.941,64); -INSERT INTO `mob_spawn_points` VALUES (16830495,0,'Moblin_Wisewoman','Moblin Wisewoman',7,40,40,494.451,-118.500,27.941,64); -INSERT INTO `mob_spawn_points` VALUES (16830496,0,'Moblin_Clergyman','Moblin Clergyman',8,40,40,496.451,-118.500,29.941,64); -INSERT INTO `mob_spawn_points` VALUES (16830497,0,'Moblin_Wisewoman','Moblin Wisewoman',7,40,40,498.451,-118.514,31.941,64); -INSERT INTO `mob_spawn_points` VALUES (16830498,0,'Moblin_Clergyman','Moblin Clergyman',8,40,40,501.451,-118.500,31.941,64); -INSERT INTO `mob_spawn_points` VALUES (16830499,0,'Moblin_Wisewoman','Moblin Wisewoman',7,40,40,503.451,-118.500,29.941,64); -INSERT INTO `mob_spawn_points` VALUES (16830500,0,'Moblin_Clergyman','Moblin Clergyman',8,40,40,505.451,-118.500,27.941,64); +INSERT INTO `mob_spawn_points` VALUES (16830480,0,'Twilotak','Twilotak',6,45,45,-460.000,122.032,20.000,64); +INSERT INTO `mob_spawn_points` VALUES (16830481,0,'Moblin_Wisewoman','Moblin Wisewoman',7,39,41,-465.500,122.000,28.000,64); +INSERT INTO `mob_spawn_points` VALUES (16830482,0,'Moblin_Clergyman','Moblin Clergyman',8,39,41,-463.500,122.000,30.000,64); +INSERT INTO `mob_spawn_points` VALUES (16830483,0,'Moblin_Wisewoman','Moblin Wisewoman',7,39,41,-461.500,121.986,32.000,64); +INSERT INTO `mob_spawn_points` VALUES (16830484,0,'Moblin_Clergyman','Moblin Clergyman',8,39,41,-458.500,122.000,32.000,64); +INSERT INTO `mob_spawn_points` VALUES (16830485,0,'Moblin_Wisewoman','Moblin Wisewoman',7,39,41,-456.500,122.000,30.000,64); +INSERT INTO `mob_spawn_points` VALUES (16830486,0,'Moblin_Clergyman','Moblin Clergyman',8,39,41,-454.500,122.000,28.000,64); +INSERT INTO `mob_spawn_points` VALUES (16830487,0,'Twilotak','Twilotak',6,45,45,9.000,1.500,20.000,64); +INSERT INTO `mob_spawn_points` VALUES (16830488,0,'Moblin_Wisewoman','Moblin Wisewoman',7,39,41,14.482,1.500,27.937,64); +INSERT INTO `mob_spawn_points` VALUES (16830489,0,'Moblin_Clergyman','Moblin Clergyman',8,39,41,16.482,1.500,29.937,64); +INSERT INTO `mob_spawn_points` VALUES (16830490,0,'Moblin_Wisewoman','Moblin Wisewoman',7,39,41,18.482,1.486,31.937,64); +INSERT INTO `mob_spawn_points` VALUES (16830491,0,'Moblin_Clergyman','Moblin Clergyman',8,39,41,21.482,1.500,31.937,64); +INSERT INTO `mob_spawn_points` VALUES (16830492,0,'Moblin_Wisewoman','Moblin Wisewoman',7,39,41,23.482,1.500,29.937,64); +INSERT INTO `mob_spawn_points` VALUES (16830493,0,'Moblin_Clergyman','Moblin Clergyman',8,39,41,25.482,1.500,27.937,64); +INSERT INTO `mob_spawn_points` VALUES (16830494,0,'Twilotak','Twilotak',6,45,45,499.951,-118.468,19.941,64); +INSERT INTO `mob_spawn_points` VALUES (16830495,0,'Moblin_Wisewoman','Moblin Wisewoman',7,39,41,494.451,-118.500,27.941,64); +INSERT INTO `mob_spawn_points` VALUES (16830496,0,'Moblin_Clergyman','Moblin Clergyman',8,39,41,496.451,-118.500,29.941,64); +INSERT INTO `mob_spawn_points` VALUES (16830497,0,'Moblin_Wisewoman','Moblin Wisewoman',7,39,41,498.451,-118.514,31.941,64); +INSERT INTO `mob_spawn_points` VALUES (16830498,0,'Moblin_Clergyman','Moblin Clergyman',8,39,41,501.451,-118.500,31.941,64); +INSERT INTO `mob_spawn_points` VALUES (16830499,0,'Moblin_Wisewoman','Moblin Wisewoman',7,39,41,503.451,-118.500,29.941,64); +INSERT INTO `mob_spawn_points` VALUES (16830500,0,'Moblin_Clergyman','Moblin Clergyman',8,39,41,505.451,-118.500,27.941,64); -- Bionic Bug INSERT INTO `mob_spawn_points` VALUES (16830501,0,'Bugboy','Bugboy',9,80,80,-460,121.532,20,64);