From 3ddbeab547776b2c82c7d412320a708538b7045f Mon Sep 17 00:00:00 2001 From: Kipling Date: Wed, 9 Sep 2026 16:43:17 -0700 Subject: [PATCH] Under the Sea Quest Line Fixes --- .../quests/otherAreas/Inside_the_Belly.lua | 9 +- scripts/quests/otherAreas/The_Gift.lua | 3 +- scripts/quests/otherAreas/The_Real_Gift.lua | 40 +++-- scripts/quests/otherAreas/Under_the_Sea.lua | 161 ++++++++++++------ 4 files changed, 146 insertions(+), 67 deletions(-) diff --git a/scripts/quests/otherAreas/Inside_the_Belly.lua b/scripts/quests/otherAreas/Inside_the_Belly.lua index a762e44d3de..c08228031b1 100644 --- a/scripts/quests/otherAreas/Inside_the_Belly.lua +++ b/scripts/quests/otherAreas/Inside_the_Belly.lua @@ -629,8 +629,7 @@ quest.sections = check = function(player, status, vars) return status == xi.questStatus.QUEST_AVAILABLE and player:getQuestStatus(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.THE_REAL_GIFT) == xi.questStatus.QUEST_COMPLETED and - xi.crafting.getTotalSkill(player, xi.skill.FISHING) >= 30 and - xi.settings.map.FISHING_ENABLE == true + xi.crafting.getTotalSkill(player, xi.skill.FISHING) >= 30 end, [xi.zone.SELBINA] = @@ -649,8 +648,7 @@ quest.sections = { check = function(player, status, vars) return status == xi.questStatus.QUEST_ACCEPTED and - xi.crafting.getTotalSkill(player, xi.skill.FISHING) >= 30 and - xi.settings.map.FISHING_ENABLE == true + xi.crafting.getTotalSkill(player, xi.skill.FISHING) >= 30 end, [xi.zone.SELBINA] = @@ -689,8 +687,7 @@ quest.sections = { check = function(player, status, vars) - return status == xi.questStatus.QUEST_COMPLETED and - xi.settings.map.FISHING_ENABLE == true + return status == xi.questStatus.QUEST_COMPLETED end, [xi.zone.SELBINA] = diff --git a/scripts/quests/otherAreas/The_Gift.lua b/scripts/quests/otherAreas/The_Gift.lua index ceea0718ed3..591815a5bee 100644 --- a/scripts/quests/otherAreas/The_Gift.lua +++ b/scripts/quests/otherAreas/The_Gift.lua @@ -21,8 +21,7 @@ quest.sections = check = function(player, status, vars) return status == xi.questStatus.QUEST_AVAILABLE and player:getQuestStatus(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.UNDER_THE_SEA) == xi.questStatus.QUEST_COMPLETED and - player:getQuestStatus(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.THE_SAND_CHARM) >= xi.questStatus.QUEST_ACCEPTED and - xi.settings.map.FISHING_ENABLE == true + player:getQuestStatus(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.THE_SAND_CHARM) >= xi.questStatus.QUEST_ACCEPTED end, [xi.zone.SELBINA] = diff --git a/scripts/quests/otherAreas/The_Real_Gift.lua b/scripts/quests/otherAreas/The_Real_Gift.lua index 4ba1f0fd124..2c2ba2d7acd 100644 --- a/scripts/quests/otherAreas/The_Real_Gift.lua +++ b/scripts/quests/otherAreas/The_Real_Gift.lua @@ -11,7 +11,6 @@ local quest = Quest:new(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.THE_REAL quest.reward = { - item = xi.item.GLASS_FIBER_FISHING_ROD, title = xi.title.THE_LOVE_DOCTOR, } @@ -21,8 +20,7 @@ quest.sections = check = function(player, status, vars) return status == xi.questStatus.QUEST_AVAILABLE and player:getQuestStatus(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.UNDER_THE_SEA) == xi.questStatus.QUEST_COMPLETED and - player:getQuestStatus(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.THE_SAND_CHARM) >= xi.questStatus.QUEST_COMPLETED and - xi.settings.map.FISHING_ENABLE == true + player:getQuestStatus(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.THE_SAND_CHARM) == xi.questStatus.QUEST_COMPLETED end, [xi.zone.SELBINA] = @@ -49,24 +47,46 @@ quest.sections = { ['Oswald'] = { - onTrigger = function(player, npc) - return quest:event(74, xi.item.SHALL_SHELL) -- Shall shells yield pearls + onTrade = function(player, npc, trade) + if + quest:getVar(player, 'Prog') ~= 0 or + not npcUtil.tradeMatches(trade, { { xi.item.SHALL_SHELL, 1 } }) + then + return + end + + -- Retail gives the rod and takes the shell before the event starts. + if not npcUtil.giveItem(player, xi.item.GLASS_FIBER_FISHING_ROD, { silent = true }) then + player:messageSpecial(zones[xi.zone.SELBINA].text.ITEM_CANNOT_BE_OBTAINED + 4, xi.item.GLASS_FIBER_FISHING_ROD) + return + end + + player:tradeComplete() + quest:setVar(player, 'Prog', 1) + + return quest:progressEvent(75) end, - onTrade = function(player, npc, trade) - if npcUtil.tradeHasExactly(trade, xi.item.SHALL_SHELL) then - return quest:progressEvent(75) -- You're so fantastic! Thank you! + onTrigger = function(player, npc) + -- The reward was already given if the player disconnected during the event. + if quest:getVar(player, 'Prog') == 1 then + return quest:progressEvent(75) end + + return quest:event(74, xi.item.SHALL_SHELL) -- Shall shells yield pearls end, }, onEventFinish = { [75] = function(player, csid, option, npc) - if quest:complete(player) then + if + quest:getVar(player, 'Prog') == 1 and + quest:complete(player) + then player:addFame(xi.fameArea.SANDORIA, 10) player:addFame(xi.fameArea.BASTOK, 10) - player:confirmTrade() + player:messageSpecial(zones[xi.zone.SELBINA].text.ITEM_OBTAINED, xi.item.GLASS_FIBER_FISHING_ROD) end end, }, diff --git a/scripts/quests/otherAreas/Under_the_Sea.lua b/scripts/quests/otherAreas/Under_the_Sea.lua index bf44994277b..1cd2f6b5278 100644 --- a/scripts/quests/otherAreas/Under_the_Sea.lua +++ b/scripts/quests/otherAreas/Under_the_Sea.lua @@ -7,14 +7,12 @@ -- Oswald : !pos 47.119 -15.273 7.989 248 -- Jimaida : !pos -17.342 -2.597 -18.766 248 -- Zaldon : !pos -11.810 -7.287 -6.742 248 --- TODO: The quest is NOT supposed to appear in your log after talking to Yaya. Verify if/when it does appear. ----------------------------------- local quest = Quest:new(xi.questLog.OTHER_AREAS, xi.quest.id.otherAreas.UNDER_THE_SEA) quest.reward = { - item = xi.item.AMBER_EARRING, title = xi.title.LIL_CUPID, } @@ -23,18 +21,57 @@ quest.sections = { check = function(player, status, vars) return status == xi.questStatus.QUEST_AVAILABLE and - player:getFameLevel(xi.fameArea.SELBINA_RABAO) >= 2 and - xi.settings.map.FISHING_ENABLE == true + player:getFameLevel(xi.fameArea.SELBINA_RABAO) >= 2 end, [xi.zone.SELBINA] = { - ['Yaya'] = quest:progressEvent(31), + ['Yaya'] = + { + onTrigger = function(player, npc) + if quest:getVar(player, 'Prog') == 0 then + return quest:progressEvent(31) + end + end, + }, + + ['Oswald'] = + { + onTrigger = function(player, npc) + if quest:getVar(player, 'Prog') == 1 then + return quest:progressEvent(32) -- Oswald is looking for his ring + end + end, + }, + + ['Jimaida'] = + { + onTrigger = function(player, npc) + if quest:getVar(player, 'Prog') == 2 then + return quest:progressEvent(33) -- Go see Zaldon + end + end, + }, onEventFinish = { [31] = function(player, csid, option, npc) - quest:begin(player) + if option == 50 then + quest:setVar(player, 'Prog', 1) + end + end, + + [32] = function(player, csid, option, npc) + if option == 50 then + quest:setVar(player, 'Prog', 2) + end + end, + + [33] = function(player, csid, option, npc) + if option == 51 then + quest:begin(player) + quest:setVar(player, 'Prog', 3) + end end, }, }, @@ -50,74 +87,100 @@ quest.sections = ['Oswald'] = { onTrigger = function(player, npc) - if quest:getVar(player, 'Prog') == 0 then - return quest:progressEvent(32) -- Oswald is looking for his ring - elseif player:hasKeyItem(xi.keyItem.ETCHED_RING) then - return quest:progressEvent(37) -- You found it! + if + not player:hasKeyItem(xi.keyItem.ETCHED_RING) and + quest:getVar(player, 'Prog') ~= 6 + then + return end - end, - }, - ['Jimaida'] = - { - onTrigger = function(player, npc) - if quest:getVar(player, 'Prog') == 1 then - return quest:progressEvent(33) -- Go see Zaldon + local event = quest:progressEvent(37) + + -- Give the reward only when this event is chosen. + event.perform = function(self, playerArg, npcArg) + -- The reward was already given if the player disconnected during the event. + if quest:getVar(playerArg, 'Prog') == 6 then + return Event.perform(self, playerArg, npcArg) + end + + if not npcUtil.giveItem(playerArg, xi.item.AMBER_EARRING, { silent = true }) then + playerArg:messageSpecial(zones[xi.zone.SELBINA].text.ITEM_CANNOT_BE_OBTAINED, xi.item.AMBER_EARRING) + return + end + + playerArg:addFame(xi.fameArea.SANDORIA, 10) + playerArg:addFame(xi.fameArea.BASTOK, 10) + playerArg:delKeyItem(xi.keyItem.ETCHED_RING) + quest:setVar(playerArg, 'Prog', 6) + + return Event.perform(self, playerArg, npcArg) end + + return event end, }, ['Zaldon'] = { - onTrigger = function(player, npc) - if quest:getVar(player, 'Prog') == 2 then - return quest:progressEvent(34, xi.item.FAT_GREEDIE) - end - end, - onTrade = function(player, npc, trade) if - quest:getVar(player, 'Prog') == 3 and - npcUtil.tradeHasExactly(trade, xi.item.FAT_GREEDIE) + quest:getVar(player, 'Prog') ~= 4 or + player:hasKeyItem(xi.keyItem.ETCHED_RING) then - if math.randomInt(1, 100) <= 20 then - return quest:progressEvent(35) -- Ring found ! - else - return quest:event(36) -- Ring not found + return + end + + local event + if npcUtil.tradeMatches(trade, { { xi.item.FAT_GREEDIE, 1 } }) then + event = quest:progressEvent(35) + elseif npcUtil.tradeMatches(trade, { { xi.item.GREEDIE, 1 } }) then + event = quest:progressEvent(36) + else + return + end + + -- Take the fish only when this event is chosen. + event.perform = function(self, playerArg, npcArg) + playerArg:tradeComplete() + + if self.id == 35 then + playerArg:addKeyItem(xi.keyItem.ETCHED_RING) + quest:setVar(playerArg, 'Prog', 5) end + + return Event.perform(self, playerArg, npcArg) end - end, - }, - onEventFinish = - { - [32] = function(player, csid, option, npc) - quest:setVar(player, 'Prog', 1) + return event end, - [33] = function(player, csid, option, npc) - quest:setVar(player, 'Prog', 2) + onTrigger = function(player, npc) + if quest:getVar(player, 'Prog') == 3 then + return quest:progressEvent(34, xi.item.GREEDIE, 1, 0, 0, xi.item.LU_SHANGS_FISHING_ROD, xi.item.MINNOW, 6, 0) + end end, + }, + onEventFinish = + { [34] = function(player, csid, option, npc) - quest:setVar(player, 'Prog', 3) + if option == 50 then + quest:setVar(player, 'Prog', 4) + end end, [35] = function(player, csid, option, npc) - player:confirmTrade() - npcUtil.giveKeyItem(player, xi.keyItem.ETCHED_RING) - quest:setVar(player, 'Prog', 4) - end, - - [36] = function(player, csid, option, npc) - player:confirmTrade() + if quest:getVar(player, 'Prog') == 5 then + player:messageSpecial(zones[xi.zone.SELBINA].text.KEYITEM_OBTAINED, xi.keyItem.ETCHED_RING) + end end, [37] = function(player, csid, option, npc) - if quest:complete(player) then - player:addFame(xi.fameArea.SANDORIA, 10) - player:addFame(xi.fameArea.BASTOK, 10) - player:delKeyItem(xi.keyItem.ETCHED_RING) + if + quest:getVar(player, 'Prog') == 6 and + quest:complete(player) + then + player:messageSpecial(zones[xi.zone.SELBINA].text.ITEM_OBTAINED, xi.item.AMBER_EARRING) end end, },