landsandboat/scripts/missions/cop/helpers.lua
Skold177 03d5c10bcf PromyvionXPFix
Removes duplicate XP gains from Promyvions while preserving helper XP
2026-05-20 12:09:17 -04:00

182 lines
6.6 KiB
Lua

-----------------------------------
-- Chains of Promathia Helpers
-----------------------------------
local hallID = zones[xi.zone.HALL_OF_TRANSFERENCE]
-----------------------------------
xi = xi or {}
xi.cop = xi.cop or {}
xi.cop.helpers = xi.cop.helpers or {}
xi.cop.helpers.promyvionCrags =
{
HOLLA = 1,
DEM = 2,
MEA = 3,
}
xi.cop.helpers.shatteredTelepointInfo =
{
[xi.zone.LA_THEINE_PLATEAU ] = { xi.cop.helpers.promyvionCrags.HOLLA, 202, 212, { -266.76, -0.635, 280.058, 0, 14 }, xi.ki.LIGHT_OF_HOLLA },
[xi.zone.KONSCHTAT_HIGHLANDS] = { xi.cop.helpers.promyvionCrags.DEM, 913, 918, { -267.194, -40.634, -280.019, 0, 14 }, xi.ki.LIGHT_OF_DEM },
[xi.zone.TAHRONGI_CANYON ] = { xi.cop.helpers.promyvionCrags.MEA, 913, 918, { 280.066, -80.635, -67.096, 191, 14 }, xi.ki.LIGHT_OF_MEA },
}
xi.cop.helpers.numPromyvionCompleted = function(player, excludeArea)
local numKeyItems = 0
for keyItem = xi.ki.LIGHT_OF_HOLLA, xi.ki.LIGHT_OF_MEA do
if player:hasKeyItem(keyItem) then
if
excludeArea == nil or
excludeArea and xi.ki.LIGHT_OF_HOLLA + excludeArea - 1 ~= keyItem
then
numKeyItems = numKeyItems + 1
end
end
end
return numKeyItems
end
xi.cop.helpers.hasCompletedPromyvion = function(player, zoneId)
return player:hasKeyItem(xi.cop.helpers.shatteredTelepointInfo[zoneId][5])
end
xi.cop.helpers.promyvionOnZoneIn = function(player, prevZone)
local missionOption = xi.mission.getVar(player, xi.mission.log_id.COP, player:getCurrentMission(xi.mission.log_id.COP), 'Option')
if
missionOption == 0
then
return 50 + xi.cop.helpers.numPromyvionCompleted(player)
end
end
xi.cop.helpers.sendToPromyvionZone = function(player, promyvionOffset)
if promyvionOffset == xi.cop.helpers.promyvionCrags.HOLLA then
player:setPos(92.033, 0, 80.380, 255, 16)
elseif promyvionOffset == xi.cop.helpers.promyvionCrags.DEM then
player:setPos(185.891, 0, -52.331, 128, 18)
elseif promyvionOffset == xi.cop.helpers.promyvionCrags.MEA then
player:setPos(-93.268, 0, 170.749, 162, 20)
end
end
xi.cop.helpers.sendToZoneOnFinish = function(player, csid, option, npc)
if option == 0 then
xi.cop.helpers.sendToPromyvionZone(player, player:getLocalVar('toPromyvion'))
end
end
xi.cop.helpers.shatteredTelepointOnTrigger = function(mission, player, npc)
local zoneId = player:getZoneID()
local promyvionOffset = xi.cop.helpers.shatteredTelepointInfo[zoneId][1] - 1
local currentMemory = mission:getVar(player, 'Option')
if
player:hasKeyItem(xi.ki.LIGHT_OF_HOLLA + promyvionOffset)
then
return mission:progressEvent(xi.cop.helpers.shatteredTelepointInfo[zoneId][2])
elseif
currentMemory == 0 or
currentMemory == xi.cop.helpers.shatteredTelepointInfo[zoneId][1] or
xi.cop.helpers.numPromyvionCompleted(player) == 2
then
local firstEntry = (currentMemory == 0 and player:getCurrentMission(xi.mission.log_id.COP) == xi.mission.id.cop.BELOW_THE_ARKS) and 1 or 0
return mission:progressEvent(xi.cop.helpers.shatteredTelepointInfo[zoneId][2], 0, 0, firstEntry)
else
return mission:progressEvent(xi.cop.helpers.shatteredTelepointInfo[zoneId][3], currentMemory - 1)
end
end
xi.cop.helpers.shatteredTelepointEntry = function(player, csid, option, npc)
if option == 0 then
local zoneId = player:getZoneID()
player:setPos(unpack(xi.cop.helpers.shatteredTelepointInfo[zoneId][4]))
end
end
xi.cop.helpers.shatteredTelepointSealMemory = function(mission, player, csid, option, npc)
if option == 0 then
local zoneId = player:getZoneID()
mission:setVar(player, 'Option', 0)
player:messageSpecial(zones[zoneId].text.MEMORIES_SEALED_OFF)
end
end
xi.cop.helpers.cermetGateOnTrigger = function(mission, player, npc)
local cermetLocation = tonumber(string.sub(npc:getName(), -1)) + 1
local currentMemory = mission:getVar(player, 'Option')
if currentMemory ~= cermetLocation then
return mission:messageSpecial(hallID.text.DOOR_FIRMLY_SHUT):setPriority(1000)
end
end
xi.cop.helpers.largeApparatusOnTrigger = function(mission, player, npc)
local currentMemory = mission:getVar(player, 'Option')
if
currentMemory == 0 and
player:getCurrentMission(xi.mission.log_id.COP) == xi.mission.id.cop.BELOW_THE_ARKS
then
return mission:progressEvent(160)
elseif
xi.cop.helpers.numPromyvionCompleted(player) < 2
then
local cragLocation = math.ceil(tonumber(string.sub(npc:getName(), -1)) / 3)
-- TODO: Assumption is that previously-completed promyvions do not require sealing of memories
-- for "The Mothercrystals."
if
currentMemory == cragLocation and
not player:hasKeyItem(xi.ki.LIGHT_OF_HOLLA + cragLocation - 1)
then
player:setLocalVar('exitOffset', cragLocation)
return mission:progressEvent(122 + 3 * (cragLocation - 1))
end
end
end
xi.cop.helpers.largeApparatusOnEventFinish = function(mission, player, csid, option, npc)
if option == 0 then
local exitOffset = player:getLocalVar('exitOffset') - 1
mission:setVar(player, 'Option', 0)
xi.teleport.to(player, xi.teleport.id.EXITPROMHOLLA + exitOffset)
end
end
xi.cop.helpers.spireEventFinish = function(mission, player, csid, option, npc)
if player:getLocalVar('newPromy') == 1 then
-- This variable is an offset based on a 0-indexed version promyvionCrags table.
local promyvionId = (player:getZoneID() - 17) / 2
local teleportLocation = xi.teleport.id.EXITPROMHOLLA + promyvionId
player:addKeyItem(xi.ki.LIGHT_OF_HOLLA + promyvionId)
player:messageSpecial(zones[player:getZoneID()].text.CANT_REMEMBER, xi.ki.LIGHT_OF_HOLLA + promyvionId)
mission:setVar(player, 'Option', 0)
local numCompletedPromyvions = xi.cop.helpers.numPromyvionCompleted(player)
if
(player:getCurrentMission(xi.mission.log_id.COP) == xi.mission.id.cop.BELOW_THE_ARKS and
numCompletedPromyvions == 1) or
numCompletedPromyvions == 3
then
mission:complete(player)
end
if numCompletedPromyvions == 3 then
-- We need to make sure the fallthrough does not trigger an overriding
-- teleport.
player:setLocalVar('toLufaise', 1)
teleportLocation = xi.teleport.id.LUFAISE
end
xi.teleport.to(player, teleportLocation)
end
end