From 6b9735b280f41377c737bb78694c0409df5308de Mon Sep 17 00:00:00 2001 From: Aeshur Date: Tue, 17 Feb 2026 21:40:53 -0500 Subject: [PATCH] [lua] Abyssea - Main story quests Part 4 --- scripts/globals/abyssea.lua | 19 +-- scripts/globals/quests.lua | 4 +- scripts/quests/abyssea/A_Sea_Dogs_Summons.lua | 3 - .../abyssea/An_Officer_and_a_Pirate.lua | 3 - .../abyssea/Beneath_a_Blood_Red_Sky.lua | 3 - scripts/quests/abyssea/Death_and_Rebirth.lua | 3 - scripts/quests/abyssea/Emissaries_of_God.lua | 4 - scripts/quests/abyssea/First_Contact.lua | 3 - .../abyssea/Meanwhile_Back_on_Abyssea.lua | 108 ++++++++++++++++++ scripts/quests/abyssea/Tenuous_Existence.lua | 3 - scripts/quests/abyssea/The_Wyrm_God.lua | 82 +++++++++++++ .../DefaultActions.lua | 5 + .../zones/Abyssea-Empyreal_Paradox/IDs.lua | 6 + .../zones/Abyssea-Empyreal_Paradox/Zone.lua | 6 + .../npcs/Atma_Infusionist.lua | 25 ++++ .../npcs/Cavernous_Maw.lua | 18 +++ .../npcs/Cruor_Prospector.lua | 23 ++++ 17 files changed, 285 insertions(+), 33 deletions(-) create mode 100644 scripts/quests/abyssea/Meanwhile_Back_on_Abyssea.lua create mode 100644 scripts/quests/abyssea/The_Wyrm_God.lua create mode 100644 scripts/zones/Abyssea-Empyreal_Paradox/DefaultActions.lua create mode 100644 scripts/zones/Abyssea-Empyreal_Paradox/npcs/Atma_Infusionist.lua create mode 100644 scripts/zones/Abyssea-Empyreal_Paradox/npcs/Cavernous_Maw.lua create mode 100644 scripts/zones/Abyssea-Empyreal_Paradox/npcs/Cruor_Prospector.lua diff --git a/scripts/globals/abyssea.lua b/scripts/globals/abyssea.lua index 75f65006a7d..5cf2ba0a720 100644 --- a/scripts/globals/abyssea.lua +++ b/scripts/globals/abyssea.lua @@ -1287,15 +1287,16 @@ end ----------------------------------- local abysseaExitMawData = { - [xi.zone.ABYSSEA_LA_THEINE ] = { exitCsid = 200, dest = { -561.837, 0.000, 641.772, 158, xi.zone.LA_THEINE_PLATEAU } }, - [xi.zone.ABYSSEA_KONSCHTAT ] = { exitCsid = 200, dest = { 91, -68, -582, 237, xi.zone.KONSCHTAT_HIGHLANDS } }, - [xi.zone.ABYSSEA_TAHRONGI ] = { exitCsid = 200, dest = { -28.597, 46.166, -680.254, 192, xi.zone.TAHRONGI_CANYON } }, - [xi.zone.ABYSSEA_VUNKERL ] = { exitCsid = 200, dest = { 242.979, 0.235, 8.721, 157, xi.zone.JUGNER_FOREST } }, - [xi.zone.ABYSSEA_MISAREAUX ] = { exitCsid = 200, dest = { 362, 0.001, -119, 4, xi.zone.VALKURM_DUNES } }, - [xi.zone.ABYSSEA_ATTOHWA ] = { exitCsid = 200, dest = { -339.979, -23.372, 48.493, 31, xi.zone.BUBURIMU_PENINSULA } }, - [xi.zone.ABYSSEA_ALTEPA ] = { exitCsid = 200, dest = { 343, 0, -679, 199, xi.zone.SOUTH_GUSTABERG } }, - [xi.zone.ABYSSEA_ULEGUERAND] = { exitCsid = 200, dest = { 269, -7, -75, 192, xi.zone.XARCABARD } }, - [xi.zone.ABYSSEA_GRAUBERG ] = { exitCsid = 200, dest = { -72.890, 0.057, 600.131, 122, xi.zone.NORTH_GUSTABERG } }, + [xi.zone.ABYSSEA_LA_THEINE ] = { exitCsid = 200, dest = { -561.837, 0.000, 641.772, 158, xi.zone.LA_THEINE_PLATEAU } }, + [xi.zone.ABYSSEA_KONSCHTAT ] = { exitCsid = 200, dest = { 91, -68, -582, 237, xi.zone.KONSCHTAT_HIGHLANDS } }, + [xi.zone.ABYSSEA_TAHRONGI ] = { exitCsid = 200, dest = { -28.597, 46.166, -680.254, 192, xi.zone.TAHRONGI_CANYON } }, + [xi.zone.ABYSSEA_VUNKERL ] = { exitCsid = 200, dest = { 242.979, 0.235, 8.721, 157, xi.zone.JUGNER_FOREST } }, + [xi.zone.ABYSSEA_MISAREAUX ] = { exitCsid = 200, dest = { 362, 0.001, -119, 4, xi.zone.VALKURM_DUNES } }, + [xi.zone.ABYSSEA_ATTOHWA ] = { exitCsid = 200, dest = { -339.979, -23.372, 48.493, 31, xi.zone.BUBURIMU_PENINSULA } }, + [xi.zone.ABYSSEA_ALTEPA ] = { exitCsid = 200, dest = { 343, 0, -679, 199, xi.zone.SOUTH_GUSTABERG } }, + [xi.zone.ABYSSEA_ULEGUERAND ] = { exitCsid = 200, dest = { 269, -7, -75, 192, xi.zone.XARCABARD } }, + [xi.zone.ABYSSEA_GRAUBERG ] = { exitCsid = 200, dest = { -72.890, 0.057, 600.131, 122, xi.zone.NORTH_GUSTABERG } }, + [xi.zone.ABYSSEA_EMPYREAL_PARADOX ] = { exitCsid = 200, dest = { -256.128, -20.000, 225.053, 218, xi.zone.QUFIM_ISLAND } }, } xi.abyssea.exitMawOnTrigger = function(player, npc) diff --git a/scripts/globals/quests.lua b/scripts/globals/quests.lua index 9da42b5c55e..30f32b5dc6c 100644 --- a/scripts/globals/quests.lua +++ b/scripts/globals/quests.lua @@ -994,8 +994,8 @@ xi.quest.id = DEATH_AND_REBIRTH = 181, -- + Converted EMISSARIES_OF_GOD = 182, -- + Converted BENEATH_A_BLOOD_RED_SKY = 183, -- + Converted - THE_WYRM_GOD = 184, - MEANWHILE_BACK_ON_ABYSSEA = 185, + THE_WYRM_GOD = 184, -- + Converted + MEANWHILE_BACK_ON_ABYSSEA = 185, -- + Converted A_MOONLIGHT_REQUITE = 186, DOMINION_OP_10_GRAUBERG = 187, -- + Converted DOMINION_OP_11_GRAUBERG = 188, -- + Converted diff --git a/scripts/quests/abyssea/A_Sea_Dogs_Summons.lua b/scripts/quests/abyssea/A_Sea_Dogs_Summons.lua index d087f6e9dfb..25f62713c2c 100644 --- a/scripts/quests/abyssea/A_Sea_Dogs_Summons.lua +++ b/scripts/quests/abyssea/A_Sea_Dogs_Summons.lua @@ -6,9 +6,6 @@ -- Zone into the Hall of the Gods between 18:00 and 5:00. Flags Death and Rebirth upon completion. ----------------------------------- -require('scripts/globals/quests') -require('scripts/globals/interaction/quest') - local quest = Quest:new(xi.questLog.ABYSSEA, xi.quest.id.abyssea.A_SEA_DOGS_SUMMONS) quest.reward = {} diff --git a/scripts/quests/abyssea/An_Officer_and_a_Pirate.lua b/scripts/quests/abyssea/An_Officer_and_a_Pirate.lua index ab3d35e6b3e..271a9eb372c 100644 --- a/scripts/quests/abyssea/An_Officer_and_a_Pirate.lua +++ b/scripts/quests/abyssea/An_Officer_and_a_Pirate.lua @@ -7,9 +7,6 @@ -- Flags Heart of Madness upon completion. ----------------------------------- -require('scripts/globals/quests') -require('scripts/globals/interaction/quest') - local quest = Quest:new(xi.questLog.ABYSSEA, xi.quest.id.abyssea.AN_OFFICER_AND_A_PIRATE) quest.reward = {} diff --git a/scripts/quests/abyssea/Beneath_a_Blood_Red_Sky.lua b/scripts/quests/abyssea/Beneath_a_Blood_Red_Sky.lua index 03c646724d8..b74b66729bc 100644 --- a/scripts/quests/abyssea/Beneath_a_Blood_Red_Sky.lua +++ b/scripts/quests/abyssea/Beneath_a_Blood_Red_Sky.lua @@ -7,9 +7,6 @@ -- Zone into Abyssea - Empyreal Paradox. Flag The Wyrm God upon completion. ----------------------------------- -require('scripts/globals/quests') -require('scripts/globals/interaction/quest') - local quest = Quest:new(xi.questLog.ABYSSEA, xi.quest.id.abyssea.BENEATH_A_BLOOD_RED_SKY) quest.reward = {} diff --git a/scripts/quests/abyssea/Death_and_Rebirth.lua b/scripts/quests/abyssea/Death_and_Rebirth.lua index ba589078f34..e6703b56057 100644 --- a/scripts/quests/abyssea/Death_and_Rebirth.lua +++ b/scripts/quests/abyssea/Death_and_Rebirth.lua @@ -7,9 +7,6 @@ -- Complete all 9 zone quests, then talk to Joachim. Zone into the Hall of the Gods between 18:00 and 5:00. Flags Emissaries of God upon completion. ----------------------------------- -require('scripts/globals/quests') -require('scripts/globals/interaction/quest') - local quest = Quest:new(xi.questLog.ABYSSEA, xi.quest.id.abyssea.DEATH_AND_REBIRTH) quest.reward = {} diff --git a/scripts/quests/abyssea/Emissaries_of_God.lua b/scripts/quests/abyssea/Emissaries_of_God.lua index 9de6e5effee..20435352465 100644 --- a/scripts/quests/abyssea/Emissaries_of_God.lua +++ b/scripts/quests/abyssea/Emissaries_of_God.lua @@ -14,10 +14,6 @@ -- Obtain all 6 caturae titles, then talk to Joachim for CS and Abyssite of Discernment. Zone into the Hall of the Gods between 18:00 and 5:00. Flags Beneath a Blood-red Sky upon completion. ----------------------------------- -require('scripts/globals/quests') -require('scripts/globals/npc_util') -require('scripts/globals/interaction/quest') - local quest = Quest:new(xi.questLog.ABYSSEA, xi.quest.id.abyssea.EMISSARIES_OF_GOD) quest.reward = {} -- Key item given in first cutscene, not on quest complete diff --git a/scripts/quests/abyssea/First_Contact.lua b/scripts/quests/abyssea/First_Contact.lua index 4d522ba2a68..406672a5e12 100644 --- a/scripts/quests/abyssea/First_Contact.lua +++ b/scripts/quests/abyssea/First_Contact.lua @@ -7,9 +7,6 @@ -- Click ??? in La Theine Plateau between 18:00 and 5:00. Flags An Officer and a Pirate upon completion. ----------------------------------- -require('scripts/globals/quests') -require('scripts/globals/interaction/quest') - local quest = Quest:new(xi.questLog.ABYSSEA, xi.quest.id.abyssea.FIRST_CONTACT) quest.reward = {} diff --git a/scripts/quests/abyssea/Meanwhile_Back_on_Abyssea.lua b/scripts/quests/abyssea/Meanwhile_Back_on_Abyssea.lua new file mode 100644 index 00000000000..735abcf6bca --- /dev/null +++ b/scripts/quests/abyssea/Meanwhile_Back_on_Abyssea.lua @@ -0,0 +1,108 @@ +----------------------------------- +-- Meanwhile, Back on Abyssea +----------------------------------- +-- !addquest 8 185 +-- Joachim : !pos -52.844 0 -9.978 246 +-- Prishe : !pos 536.353 -499.999 -591.338 255 +-- Flagged on completion of The Wyrm God. +-- Talk to Joachim. Zone into the Hall of the Gods between 18:00 and 5:00. Talk to Prishe to flag A Moonlight Requite. +-- A Moonlight Requite signifies that you have completed the main Abyssea story, it cannot be completed. +----------------------------------- + +local quest = Quest:new(xi.questLog.ABYSSEA, xi.quest.id.abyssea.MEANWHILE_BACK_ON_ABYSSEA) + +quest.reward = +{ + keyItem = xi.ki.ABYSSITE_OF_THE_COSMOS, +} + +quest.sections = +{ + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED + end, + + [xi.zone.PORT_JEUNO] = + { + ['Joachim'] = + { + onTrigger = function(player, npc) + if quest:getVar(player, 'Prog') == 0 then + return quest:progressEvent(345) + end + end, + }, + + onEventFinish = + { + [345] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 1) + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED and + quest:getVar(player, 'Prog') == 1 + end, + + [xi.zone.HALL_OF_THE_GODS] = + { + onZoneIn = function(player, prevZone) + local hour = VanadielHour() + if hour >= 18 or hour < 5 then + return 9 + end + end, + + onEventFinish = + { + [9] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 2) + end, + }, + }, + }, + + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED and + quest:getVar(player, 'Prog') == 2 + end, + + [xi.zone.ABYSSEA_EMPYREAL_PARADOX] = + { + ['Prishe'] = + { + onTrigger = function(player, npc) + return quest:progressEvent(204) + end, + }, + + onEventFinish = + { + [204] = function(player, csid, option, npc) + if quest:complete(player) then + player:addQuest(xi.questLog.ABYSSEA, xi.quest.id.abyssea.A_MOONLIGHT_REQUITE) + end + end, + }, + }, + }, + + { + check = function(player, status) + return status == xi.questStatus.QUEST_COMPLETED + end, + + [xi.zone.ABYSSEA_EMPYREAL_PARADOX] = + { + ['Prishe'] = quest:event(207):replaceDefault() + }, + }, +} + +return quest diff --git a/scripts/quests/abyssea/Tenuous_Existence.lua b/scripts/quests/abyssea/Tenuous_Existence.lua index 94c3b359e32..7a0b0ca0dd8 100644 --- a/scripts/quests/abyssea/Tenuous_Existence.lua +++ b/scripts/quests/abyssea/Tenuous_Existence.lua @@ -8,9 +8,6 @@ -- Click ??? in La Theine Plateau between 18:00 and 5:00, then return to Joachim. Flags Champions of Abyssea upon completion. ----------------------------------- -require('scripts/globals/quests') -require('scripts/globals/interaction/quest') - local quest = Quest:new(xi.questLog.ABYSSEA, xi.quest.id.abyssea.TENUOUS_EXISTENCE) quest.reward = {} diff --git a/scripts/quests/abyssea/The_Wyrm_God.lua b/scripts/quests/abyssea/The_Wyrm_God.lua new file mode 100644 index 00000000000..90ecda13946 --- /dev/null +++ b/scripts/quests/abyssea/The_Wyrm_God.lua @@ -0,0 +1,82 @@ +----------------------------------- +-- The Wyrm God +----------------------------------- +-- !addquest 8 184 +-- TR_Entrance : !pos 539.861 -500.000 -594.576 255 +-- Prishe : !pos 536.353 -499.999 -591.338 255 +-- Flagged on completion of Beneath a Blood Red Sky. +-- Defeat Shinryu in the Abyssea-Empyreal Paradox within The Wyrm God battlefield. Talk to Prishe for a CS. Flags "Meanwhile, back on Abyssea" upon completion. +----------------------------------- + +local quest = Quest:new(xi.questLog.ABYSSEA, xi.quest.id.abyssea.THE_WYRM_GOD) + +quest.reward = {} + +quest.sections = +{ + { + check = function(player, status, vars) + return status == xi.questStatus.QUEST_ACCEPTED + end, + + [xi.zone.ABYSSEA_EMPYREAL_PARADOX] = + { + ['TR_Entrance'] = + { + onTrigger = function(player, npc) + if quest:getVar(player, 'Prog') == 0 then + return quest:progressEvent(208) + end + end, + }, + + ['Prishe'] = + { + onTrigger = function(player, npc) + if quest:getVar(player, 'Prog') == 2 then + return quest:progressEvent(203) + end + end, + }, + + onEventFinish = + { + [208] = function(player, csid, option, npc) + quest:setVar(player, 'Prog', 1) + end, + + [32001] = function(player, csid, option, npc) + -- TODO: 'battlefieldWin' local var should be set on successful completion of + -- the BCNM with its BCNM ID. See other examples of this pattern implemented + -- in various missions. + + if + player:getLocalVar('battlefieldWin') == xi.battlefield.id.THE_WYRM_GOD and + quest:getVar(player, 'Prog') == 1 + then + quest:setVar(player, 'Prog', 2) + end + end, + + [203] = function(player, csid, option, npc) + if quest:complete(player) then + player:addQuest(xi.questLog.ABYSSEA, xi.quest.id.abyssea.MEANWHILE_BACK_ON_ABYSSEA) + end + end, + }, + }, + }, + + { + check = function(player, status) + return status == xi.questStatus.QUEST_COMPLETED + end, + + [xi.zone.ABYSSEA_EMPYREAL_PARADOX] = + { + ['Prishe'] = quest:event(206):replaceDefault() + }, + }, +} + +return quest diff --git a/scripts/zones/Abyssea-Empyreal_Paradox/DefaultActions.lua b/scripts/zones/Abyssea-Empyreal_Paradox/DefaultActions.lua new file mode 100644 index 00000000000..05732b2ac28 --- /dev/null +++ b/scripts/zones/Abyssea-Empyreal_Paradox/DefaultActions.lua @@ -0,0 +1,5 @@ +-- local ID = zones[xi.zone.ABYSSEA_EMPYREAL_PARADOX] + +return { + ['Prishe'] = { event = 205 }, +} diff --git a/scripts/zones/Abyssea-Empyreal_Paradox/IDs.lua b/scripts/zones/Abyssea-Empyreal_Paradox/IDs.lua index c3f7fb21ccf..25c598a330a 100644 --- a/scripts/zones/Abyssea-Empyreal_Paradox/IDs.lua +++ b/scripts/zones/Abyssea-Empyreal_Paradox/IDs.lua @@ -17,8 +17,14 @@ zones[xi.zone.ABYSSEA_EMPYREAL_PARADOX] = LOGIN_NUMBER = 7004, -- In celebration of your most recent login (login no. ), we have provided you with points! You currently have a total of points. MEMBERS_LEVELS_ARE_RESTRICTED = 7024, -- Your party is unable to participate because certain members' levels are restricted. CRUOR_OBTAINED = 7415, -- obtained cruor. + TIME_IN_THE_BATTLEFIELD_IS_UP = 7720, -- Your time in the battlefield is up! Now exiting... + PARTY_MEMBERS_ARE_ENGAGED = 7721, -- The battlefield where your party members are engaged in combat is locked. Access is denied. + MEMBERS_OF_YOUR_PARTY = 8026, -- Currently, # members of your party (including yourself) have clearance to enter the battlefield. + MEMBERS_OF_YOUR_ALLIANCE = 8027, -- Currently, # members of your alliance (including yourself) have clearance to enter the battlefield. + TIME_LIMIT_FOR_THIS_BATTLE_IS = 8029, -- The time limit for this battle is minutes. PARTY_MEMBERS_HAVE_FALLEN = 8065, -- All party members have fallen in battle. Now leaving the battlefield. THE_PARTY_WILL_BE_REMOVED = 8072, -- If all party members' HP are still zero after # minute[/s], the party will be removed from the battlefield. + ENTERING_THE_BATTLEFIELD_FOR = 8092, -- Entering the battlefield for [The Wyrm God]! }, mob = { diff --git a/scripts/zones/Abyssea-Empyreal_Paradox/Zone.lua b/scripts/zones/Abyssea-Empyreal_Paradox/Zone.lua index d628e52b642..82c9546ce2f 100644 --- a/scripts/zones/Abyssea-Empyreal_Paradox/Zone.lua +++ b/scripts/zones/Abyssea-Empyreal_Paradox/Zone.lua @@ -21,6 +21,12 @@ zoneObject.onZoneIn = function(player, prevZone) return cs end +zoneObject.afterZoneIn = function(player) + if not player:hasStatusEffect(xi.effect.VISITANT) then + player:addStatusEffectEx(xi.effect.VISITANT, xi.effect.VISITANT, 0, 0, 0) + end +end + zoneObject.onTriggerAreaEnter = function(player, triggerArea) end diff --git a/scripts/zones/Abyssea-Empyreal_Paradox/npcs/Atma_Infusionist.lua b/scripts/zones/Abyssea-Empyreal_Paradox/npcs/Atma_Infusionist.lua new file mode 100644 index 00000000000..237230d7830 --- /dev/null +++ b/scripts/zones/Abyssea-Empyreal_Paradox/npcs/Atma_Infusionist.lua @@ -0,0 +1,25 @@ +----------------------------------- +-- Zone: Abyssea - Empyreal Paradox +-- NPC: Atma Infusionist +-- !pos 545.000 -500.500 -584.000 255 +----------------------------------- +---@type TNpcEntity +local entity = {} + +entity.onTrade = function(player, npc, trade) + xi.atma.onTrade(player, npc, trade) +end + +entity.onTrigger = function(player, npc) + xi.atma.onTrigger(player, npc) +end + +entity.onEventUpdate = function(player, csid, option, npc) + xi.atma.onEventUpdate(player, csid, option, npc) +end + +entity.onEventFinish = function(player, csid, option, npc) + xi.atma.onEventFinish(player, csid, option, npc) +end + +return entity diff --git a/scripts/zones/Abyssea-Empyreal_Paradox/npcs/Cavernous_Maw.lua b/scripts/zones/Abyssea-Empyreal_Paradox/npcs/Cavernous_Maw.lua new file mode 100644 index 00000000000..278aeadbe24 --- /dev/null +++ b/scripts/zones/Abyssea-Empyreal_Paradox/npcs/Cavernous_Maw.lua @@ -0,0 +1,18 @@ +----------------------------------- +-- Area: Abyssea - Empyreal Paradox +-- NPC: Cavernous Maw +-- !pos 540.018 -499.999 -565.867 255 +-- Teleports players to Qufim Island +----------------------------------- +---@type TNpcEntity +local entity = {} + +entity.onTrigger = function(player, npc) + xi.abyssea.exitMawOnTrigger(player, npc) +end + +entity.onEventFinish = function(player, csid, option, npc) + xi.abyssea.exitMawOnEventFinish(player, csid, option, npc) +end + +return entity diff --git a/scripts/zones/Abyssea-Empyreal_Paradox/npcs/Cruor_Prospector.lua b/scripts/zones/Abyssea-Empyreal_Paradox/npcs/Cruor_Prospector.lua new file mode 100644 index 00000000000..c73fbcc775d --- /dev/null +++ b/scripts/zones/Abyssea-Empyreal_Paradox/npcs/Cruor_Prospector.lua @@ -0,0 +1,23 @@ +----------------------------------- +-- Area: Abyssea - Empyreal Paradox +-- NPC: Cruor Prospector +-- !pos 535.000 -500.500 -584.000 255 +----------------------------------- +---@type TNpcEntity +local entity = {} + +local localProspectorItems = +{ + [xi.abyssea.itemType.TEMP ] = xi.abyssea.visionsCruorProspectorTemps, + [xi.abyssea.itemType.ENHANCEMENT] = xi.abyssea.visionsCruorProspectorBuffs, +} + +entity.onTrigger = function(player, npc) + xi.abyssea.visionsCruorProspectorOnTrigger(player, npc) +end + +entity.onEventFinish = function(player, csid, option, npc) + xi.abyssea.visionsCruorProspectorOnEventFinish(player, csid, option, localProspectorItems) +end + +return entity