landsandboat/scripts/globals/waypoint.lua
Xaver ecf5424463
Merge pull request #10233 from Aeshur/western-adoulin-waypoint-swap
[lua] Fix Western Adoulin Auction House/Rent-a-Room waypoints
2026-06-06 01:03:29 +02:00

480 lines
20 KiB
Lua

-----------------------------------
-- Waypoint Teleporters
-- https://www.bg-wiki.com/ffxi/Waypoint
-----------------------------------
xi = xi or {}
xi.waypoint = xi.waypoint or {}
local waypointStartIndex =
{
[xi.zone.WESTERN_ADOULIN ] = 0,
[xi.zone.EASTERN_ADOULIN ] = 20,
[xi.zone.YAHSE_HUNTING_GROUNDS] = 30,
[xi.zone.CEIZAK_BATTLEGROUNDS ] = 40,
[xi.zone.FORET_DE_HENNETIEL ] = 50,
[xi.zone.MORIMAR_BASALT_FIELDS] = 60,
[xi.zone.YORCIA_WEALD ] = 70,
[xi.zone.MARJAMI_RAVINE ] = 80,
[xi.zone.KAMIHR_DRIFTS ] = 90,
[xi.zone.LOWER_JEUNO ] = 100,
}
-- Table Format: Index = { Offset, GroupID, EventID, { Teleport Position }, unlockTablePos }
-- Note: Group ID is unused at this time, but can be observed in the eventUpdate option. This remains
-- in case it is needed for future implementations. unlockTablePos is the location stored in char_unlocks
-- which is utilized for displaying the appropriate map marker.
local waypointInfo =
{
-- Western Adoulin
[1] = { 0, 1, 5000, { 4.896, 0, -4.789, 33, xi.zone.WESTERN_ADOULIN }, 0 }, -- Platea Triumphus
[2] = { 1, 1, 5001, { -110.5, 3.85, -13.482, 191, xi.zone.WESTERN_ADOULIN }, 1 }, -- Pioneer's Coalition
[3] = { 2, 1, 5002, { -20.982, -0.15, -79.891, 127, xi.zone.WESTERN_ADOULIN }, 2 }, -- Mummer's Coalition
[4] = { 3, 1, 5003, { 91.451, -0.15, -49.013, 0, xi.zone.WESTERN_ADOULIN }, 3 }, -- Inventor's Coalition
[5] = { 4, 1, 5004, { -68.099, 4, -73.672, 28, xi.zone.WESTERN_ADOULIN }, 4 }, -- Auction House
[6] = { 5, 1, 5005, { 5.731, 0, -123.043, 127, xi.zone.WESTERN_ADOULIN }, 5 }, -- Rent-a-Room
[7] = { 6, 1, 5006, { 174.783, 3.85, -35.788, 63, xi.zone.WESTERN_ADOULIN }, 6 }, -- Big Bridge
[8] = { 7, 1, 5007, { 14.586, 0, 162.608, 191, xi.zone.WESTERN_ADOULIN }, 7 }, -- Airship Docks
[9] = { 8, 1, 5008, { 51.094, 32, 126.299, 191, xi.zone.WESTERN_ADOULIN }, 8 }, -- Adoulin Waterfront
-- Eastern Adoulin
[21] = { 15, 2, 5000, { -101.274, -0.15, -10.726, 191, xi.zone.EASTERN_ADOULIN }, 9 }, -- Peacekeeper's Coalition
[22] = { 16, 2, 5001, { -77.944, -0.15, -63.926, 0, xi.zone.EASTERN_ADOULIN }, 10 }, -- Scout's Coalition
[23] = { 17, 2, 5002, { -46.838, -0.075, -12.767, 63, xi.zone.EASTERN_ADOULIN }, 11 }, -- Statue of the Goddess
[24] = { 18, 2, 5003, { -57.773, -0.15, 85.237, 127, xi.zone.EASTERN_ADOULIN }, 12 }, -- Yahse Wharf
[25] = { 19, 2, 5004, { -61.865, -0.15, -120.81, 127, xi.zone.EASTERN_ADOULIN }, 13 }, -- Rent-a-Room
[26] = { 20, 2, 5005, { -42.065, -0.15, -89.979, 191, xi.zone.EASTERN_ADOULIN }, 14 }, -- Auction House
[27] = { 21, 2, 5006, { 11.681, -22.15, 29.976, 127, xi.zone.EASTERN_ADOULIN }, 15 }, -- Sverdhried Hillock
[28] = { 22, 2, 5007, { 27.124, -40.15, -60.844, 127, xi.zone.EASTERN_ADOULIN }, 16 }, -- Coronal Esplanade
[29] = { 23, 2, 5008, { 95.994, -40.15, -74.541, 0, xi.zone.EASTERN_ADOULIN }, 17 }, -- Castle Gates
-- Yahse Hunting Grounds
[31] = { 38, 4, 5000, { 321, 0, -199.8, 127, xi.zone.YAHSE_HUNTING_GROUNDS }, 22 }, -- Frontier Station
[32] = { 39, 4, 5001, { 86.5, 0, 1.5, 0, xi.zone.YAHSE_HUNTING_GROUNDS }, 23 }, -- Bivouac #1
[33] = { 40, 4, 5002, { -286.5, 0, 43.5, 127, xi.zone.YAHSE_HUNTING_GROUNDS }, 24 }, -- Bivouac #2
[34] = { 41, 4, 5003, { -162.4, 0, -272.8, 191, xi.zone.YAHSE_HUNTING_GROUNDS }, 25 }, -- Bivouac #3
-- Ceizak Battlegrounds
[41] = { 32, 3, 5000, { 365, 0.448, 190, 128, xi.zone.CEIZAK_BATTLEGROUNDS }, 18 }, -- Frontier Station
[42] = { 33, 3, 5001, { -6.879, 0, -117.511, 63, xi.zone.CEIZAK_BATTLEGROUNDS }, 19 }, -- Bivouac #1
[43] = { 34, 3, 5002, { -42, 0, 155, 191, xi.zone.CEIZAK_BATTLEGROUNDS }, 20 }, -- Bivouac #2
[44] = { 35, 3, 5003, { -442, 0, -247, 191, xi.zone.CEIZAK_BATTLEGROUNDS }, 21 }, -- Bivouac #3
-- Foret de Hennetiel
[51] = { 64, 5, 5000, { 398.11, -2, 279.11, 0, xi.zone.FORET_DE_HENNETIEL }, 26 }, -- Frontier Station
[52] = { 65, 5, 5001, { 12.6, -2.4, 342, 0, xi.zone.FORET_DE_HENNETIEL }, 27 }, -- Bivouac #1
[53] = { 66, 5, 5002, { 505, -2.25, -303.5, 127, xi.zone.FORET_DE_HENNETIEL }, 28 }, -- Bivouac #2
[54] = { 67, 5, 5003, { 103, -2.2, -92.3, 63, xi.zone.FORET_DE_HENNETIEL }, 29 }, -- Bivouac #3
[55] = { 68, 5, 5004, { -251.8, -2.37, -39.25, 63, xi.zone.FORET_DE_HENNETIEL }, 30 }, -- Bivouac #4
-- Morimar Basalt Fields
[61] = { 70, 6, 5000, { 443.728, -16, -325.428, 191, xi.zone.MORIMAR_BASALT_FIELDS }, 31 }, -- Frontier Station
[62] = { 71, 6, 5001, { 368, -16, 37.5, 127, xi.zone.MORIMAR_BASALT_FIELDS }, 32 }, -- Bivouac #1
[63] = { 72, 6, 5002, { 112.8, -0.483, 324.4, 63, xi.zone.MORIMAR_BASALT_FIELDS }, 33 }, -- Bivouac #2
[64] = { 73, 6, 5003, { 175.5, -15.581, -318.2, 127, xi.zone.MORIMAR_BASALT_FIELDS }, 34 }, -- Bivouac #3
[65] = { 74, 6, 5004, { -323, -32, 2, 63, xi.zone.MORIMAR_BASALT_FIELDS }, 35 }, -- Bivouac #4
[66] = { 75, 6, 5005, { -78.2, -47.284, 303, 191, xi.zone.MORIMAR_BASALT_FIELDS }, 36 }, -- Bivouac #5
-- Yorcia Weald
[71] = { 96, 7, 5000, { 353.3, 0.2, 153.3, 223, xi.zone.YORCIA_WEALD }, 37 }, -- Frontier Station
[72] = { 97, 7, 5001, { -40.5, 0.367, 296.367, 0, xi.zone.YORCIA_WEALD }, 38 }, -- Bivouac #1
[73] = { 98, 7, 5002, { 122.132, 0.146, -287.731, 127, xi.zone.YORCIA_WEALD }, 39 }, -- Bivouac #2
[74] = { 99, 7, 5003, { -274.776, 0.357, 85.376, 127, xi.zone.YORCIA_WEALD }, 40 }, -- Bivouac #3
-- Marjami Ravine
[81] = { 102, 8, 5000, { 358, -60, 165, 63, xi.zone.MARJAMI_RAVINE }, 41 }, -- Frontier Station
[82] = { 103, 8, 5001, { 323, -20, -79, 0, xi.zone.MARJAMI_RAVINE }, 42 }, -- Bivouac #1
[83] = { 104, 8, 5002, { 6.808, 0, 78.437, 191, xi.zone.MARJAMI_RAVINE }, 43 }, -- Bivouac #2
[84] = { 105, 8, 5003, { -318.708, -20, -127.275, 63, xi.zone.MARJAMI_RAVINE }, 44 }, -- Bivouac #3
[85] = { 106, 8, 5004, { -326.022, -40.023, 201.096, 191, xi.zone.MARJAMI_RAVINE }, 45 }, -- Bivouac #4
-- Kamihr Drifts
[91] = { 134, 9, 5000, { 439.403, 63, -272.554, 63, xi.zone.KAMIHR_DRIFTS }, 46 }, -- Frontier Station
[92] = { 135, 9, 5001, { -42.574, 43, -71.319, 0, xi.zone.KAMIHR_DRIFTS }, 47 }, -- Bivouac #1
[93] = { 136, 9, 5002, { 8.24, 43, -283.017, 191, xi.zone.KAMIHR_DRIFTS }, 48 }, -- Bivouac #2
[94] = { 137, 9, 5003, { 9.24, 23, 162.803, 63, xi.zone.KAMIHR_DRIFTS }, 49 }, -- Bivouac #3
[95] = { 138, 9, 5004, { -228.942, 3.567, 364.512, 127, xi.zone.KAMIHR_DRIFTS }, 50 }, -- Bivouac #4
-- Jeuno (Special case, Default Active, uses multiple options)
[100] = { nil, 10, 10121, { -33.550, 0, -31.840, 150, xi.zone.LOWER_JEUNO } },
[101] = { nil, 10, 10121, { -33.550, 0, -31.840, 150, xi.zone.LOWER_JEUNO } },
-- Runes (One-way, bitmask determined by key items)
[200] = { nil, nil, nil, { 96.642, -0.199, -4.8, 160, xi.zone.NORTHERN_SAN_DORIA } }, -- Northern San d'Oria
[201] = { nil, nil, nil, { -176.619, -8, -30.091, 128, xi.zone.BASTOK_MARKETS } }, -- Bastok Markets
[202] = { nil, nil, nil, { -85.592, -5, 37.239, 0, xi.zone.WINDURST_WOODS } }, -- Windurst Woods
[203] = { nil, nil, nil, { 18.360, -14.559, 74.017, 64, xi.zone.SELBINA } }, -- Selbina
[204] = { nil, nil, nil, { -0.201, -4, 109.852, 64, xi.zone.MHAURA } }, -- Mhaura
[205] = { nil, nil, nil, { -51.565, -10, -104.851, 192, xi.zone.KAZHAM } }, -- Kazham
[206] = { nil, nil, nil, { -7.348, 0, -82.643, 192, xi.zone.RABAO } }, -- Rabao
[207] = { nil, nil, nil, { -19.104, 0.220, -47.464, 192, xi.zone.NORG } }, -- Norg
[208] = { nil, nil, nil, { 0, -23.5, 35.466, 64, xi.zone.TAVNAZIAN_SAFEHOLD } }, -- Tavnazian Safehold
[209] = { nil, nil, nil, { 676.982, -15.5, 220, 0, xi.zone.WAJAOM_WOODLANDS } }, -- Aht Urhgan Whitegate (Wajaom Woodlands)
[210] = { nil, nil, nil, { 13.202, -3.675, -453.439, 128, xi.zone.CAEDARVA_MIRE } }, -- Nashmau (Caedarva Mire)
-- Enigmatic Devices (One-way, so event should never be called)
-- NOTE: These are stored at the end of the teleport table internally, and are not displayed as map markers
[300] = { 128, 11, nil, { -588, -7.5, 19, 192, xi.zone.RALA_WATERWAYS }, 51 }, -- Rala Waterways
[301] = { 129, 11, nil, { -108.288, 4, -12.370, 151, xi.zone.CIRDAS_CAVERNS }, 52 }, -- Cirdas Caverns
[302] = { 130, 11, nil, { 171, 4.47, -259, 128, xi.zone.YORCIA_WEALD }, 53 }, -- Yorcia Weald
[303] = { 131, 11, nil, { -148, -170, 27, 192, xi.zone.OUTER_RAKAZNAR }, 54 }, -- Outer Ra'Kaznar
}
local function buildTeleportLookup()
local tableLookup = {}
for waypointIndex, waypointData in pairs(waypointInfo) do
if waypointData[5] then
tableLookup[waypointData[5]] = waypointIndex
end
end
return tableLookup
end
local tableIndexToWaypoint = buildTeleportLookup()
local groupStartIndex =
{
[1] = 0, -- Western Adoulin
[2] = 20, -- Eastern Adoulin
[3] = 40, -- Ceizak Battlegrounds
[4] = 30, -- Yahse Hunting Grounds
[5] = 50, -- Foret de Hennetiel
[6] = 60, -- Morimar Basalt Fields
[7] = 70, -- Yorcia Weald
[8] = 80, -- Marjami Ravine
[9] = 90, -- Kamihr Drifts
[10] = 100, -- Lower Jeuno
[11] = 300, -- Enigmatic Devices
}
local runeKeyItems =
{
xi.ki.SAN_DORIA_WARP_RUNE,
xi.ki.BASTOK_WARP_RUNE,
xi.ki.WINDURST_WARP_RUNE,
xi.ki.SELBINA_WARP_RUNE,
xi.ki.MHAURA_WARP_RUNE,
xi.ki.KAZHAM_WARP_RUNE,
xi.ki.RABAO_WARP_RUNE,
xi.ki.NORG_WARP_RUNE,
xi.ki.TAVNAZIA_WARP_RUNE,
xi.ki.WHITEGATE_WARP_RUNE,
xi.ki.NASHMAU_WARP_RUNE,
}
-- Number of Kinetic Units granted for each item trade.
local crystalTradeValues =
{
[xi.item.EARTH_CRYSTAL ] = 15,
[xi.item.FIRE_CRYSTAL ] = 15,
[xi.item.WATER_CRYSTAL ] = 15,
[xi.item.WIND_CRYSTAL ] = 15,
[xi.item.ICE_CRYSTAL ] = 30,
[xi.item.LIGHTNING_CRYSTAL] = 30,
[xi.item.DARK_CRYSTAL ] = 80,
[xi.item.LIGHT_CRYSTAL ] = 80,
[xi.item.EARTH_CLUSTER ] = 200,
[xi.item.FIRE_CLUSTER ] = 200,
[xi.item.WATER_CLUSTER ] = 200,
[xi.item.WIND_CLUSTER ] = 200,
[xi.item.ICE_CLUSTER ] = 400,
[xi.item.LIGHTNING_CLUSTER] = 400,
[xi.item.INFERNO_CRYSTAL ] = 500,
[xi.item.GLACIER_CRYSTAL ] = 500,
[xi.item.CYCLONE_CRYSTAL ] = 500,
[xi.item.TERRA_CRYSTAL ] = 500,
[xi.item.PLASMA_CRYSTAL ] = 500,
[xi.item.TORRENT_CRYSTAL ] = 500,
[xi.item.AURORA_CRYSTAL ] = 500,
[xi.item.TWILIGHT_CRYSTAL ] = 500,
[xi.item.DARK_CLUSTER ] = 1000,
[xi.item.LIGHT_CLUSTER ] = 1000,
}
local function getWaypointIndex(npcObj)
local waypointNpcId = npcObj:getID()
local zoneObject = npcObj:getZone()
local waypointList = zoneObject:queryEntitiesByName('Waypoint')
for indexVal, npcData in ipairs(waypointList) do
if npcData:getID() == waypointNpcId then
return waypointStartIndex[zoneObject:getID()] + indexVal
end
end
return nil
end
-- Teleports are stored in an array of uint32, but referenced in-game using multiple
-- methods. This will return a table of 5 parameters corresponding to what the event
-- onTrigger uses.
local function getUnlockedWaypointParameters(player)
local unlockedWaypoints = player:getTeleportTable(xi.teleport.type.WAYPOINT)
local parameterTable = { 0, 0, 0, 0, 0 }
for indexVal, waypointField in ipairs(unlockedWaypoints) do
for bitPos = 0, 31 do
if bit.band(bit.rshift(waypointField, bitPos), 1) == 1 then
local waypointIndex = tableIndexToWaypoint[32 * (indexVal - 1) + bitPos]
local waypointOffset = waypointInfo[waypointIndex][1]
local parameterIndex = math.floor(waypointOffset / 32) + 1
local parameterBitPos = waypointOffset % 32
parameterTable[parameterIndex] = utils.mask.setBit(parameterTable[parameterIndex], parameterBitPos, true)
end
end
end
return parameterTable
end
local function getRuneMask(player)
local resultMask = utils.MAX_UINT32 - 1
for bitIndex, keyItem in ipairs(runeKeyItems) do
if player:hasKeyItem(keyItem) then
resultMask = utils.mask.setBit(resultMask, bitIndex, false)
end
end
return resultMask
end
-- The below functions are used by all Waypoint NPCs
xi.waypoint.onTrade = function(player, npc, trade)
local ID = zones[player:getZoneID()]
local currentUnits = player:getCurrency('kinetic_unit')
local kineticValue = 0
if currentUnits == 50000 then
player:messageSpecial(ID.text.REACHED_KINETIC_UNIT_LIMIT)
return
end
for crystalId, crystalValue in pairs(crystalTradeValues) do
local numCrystals = trade:getItemQty(crystalId)
if numCrystals > 0 then
kineticValue = kineticValue + numCrystals * crystalValue
trade:confirmItem(crystalId, numCrystals)
end
end
if kineticValue > 0 then
player:confirmTrade()
if currentUnits + kineticValue > 50000 then
local lostUnits = currentUnits + kineticValue - 50000
player:messageSpecial(ID.text.ARTIFACT_TERMINAL_VOLUME)
player:messageSpecial(ID.text.SURPLUS_LOST_TO_AETHER, lostUnits)
player:setCurrency('kinetic_unit', 50000)
else
player:messageName(ID.text.ARTIFACT_HAS_BEEN_CHARGED, nil, kineticValue, kineticValue + currentUnits)
player:addCurrency('kinetic_unit', kineticValue)
end
else
player:messageName(ID.text.CANNOT_RECEIVE_KINETIC, nil)
end
end
xi.waypoint.onTrigger = function(player, npc)
local waypointIndex = getWaypointIndex(npc)
local zoneId = player:getZoneID()
if
zoneId == xi.zone.LOWER_JEUNO or
player:hasTeleport(xi.teleport.type.WAYPOINT, waypointInfo[waypointIndex][5])
then
local unlockedWaypoints = getUnlockedWaypointParameters(player)
local destConfirmation = player:getTeleportMenu(xi.teleport.type.WAYPOINT)[1] and 1 or 0
-- Note: The '4' Value is setting the discount value for waypoints, which appears to always
-- be the case on retail now.
local menuParams = bit.bor(4, bit.lshift(destConfirmation, 3))
-- Waypoint Event ID
local eventId = waypointInfo[waypointIndex][3]
-- First event parameters packs the player's kinetic units, two bits that determine teleportation cost,
-- and the Index value of the waypoint (See: waypointInfo table)
local p0 = bit.lshift(player:getCurrency('kinetic_unit'), 16) + bit.lshift(menuParams, 12) + waypointIndex
-- Eastern and Western Adoulin Waypoints
local p1 = unlockedWaypoints[1]
-- Third event parameter is an inverted bitfield for all but bit 0, the remainder of the field is set
-- by the key items for warp runes.
local p2 = getRuneMask(player)
-- Unlock all non-city Waypoints
local p3 = unlockedWaypoints[2]
local p4 = unlockedWaypoints[3]
local p5 = unlockedWaypoints[4]
local p6 = unlockedWaypoints[5]
player:startEvent(eventId, p0, p1, p2, p3, p4, p5, p6)
elseif zoneId ~= xi.zone.LOWER_JEUNO then
local ID = zones[zoneId]
player:addTeleport(xi.teleport.type.WAYPOINT, waypointInfo[waypointIndex][5])
player:messageSpecial(ID.text.WAYPOINT_ATTUNED, waypointIndex - waypointStartIndex[zoneId], xi.ki.GEOMAGNETRON)
end
end
-- Note: There is additional data packed into the event update option that is unused at this time (below):
-- currentWaypointIndex = bit.band(option, 0x7F)
-- destinationGroup = bit.band(bit.rshift(option, 7), 0xF)
-- destinationOffset = bit.band(bit.rshift(option, 11), 0xF)
local function isFieldWaypoint(groupId)
return groupId ~= nil and groupId >= 3 and groupId <= 9
end
local function isAdoulinCity(groupId)
return groupId == 1 or groupId == 2
end
local function getWaypointTravelCost(sourceIndex, destIndex)
local dest = waypointInfo[destIndex]
if dest == nil then
return 0
end
if destIndex >= 300 then
return 150 -- Enigmatic Devices
end
if destIndex >= 200 then
return 100 -- Warp Runes
end
local source = waypointInfo[sourceIndex]
if source == nil then
return 0
end
local sourceZone = source[4][5]
local destZone = dest[4][5]
local sameZone = sourceZone == destZone or (isAdoulinCity(source[2]) and isAdoulinCity(dest[2]))
if isFieldWaypoint(dest[2]) then
return sameZone and 2 or 50 -- Field: 2 intra-zone, 50 cross-zone
else
return sameZone and 1 or 15 -- City: 1 intra-zone, 15 cross-zone
end
end
xi.waypoint.onEventUpdate = function(player, csid, option, npc)
local ID = zones[player:getZoneID()]
local destGroup = bit.band(bit.rshift(option, 7), 0xF)
local destOffset = bit.band(bit.rshift(option, 11), 0xF)
local start = groupStartIndex[destGroup]
local destIndex = start and start + destOffset or nil
local waypoint = destIndex and waypointInfo[destIndex]
if waypoint == nil then
return
end
-- Validate destination is unlocked
if waypoint[5] ~= nil then
if not player:hasTeleport(xi.teleport.type.WAYPOINT, waypoint[5]) then
return
end
elseif destIndex >= 200 and destIndex <= 210 then
local runeIndex = destIndex - 199
if
runeKeyItems[runeIndex] and
not player:hasKeyItem(runeKeyItems[runeIndex])
then
return
end
end
local sourceIndex = getWaypointIndex(npc)
local source = waypointInfo[sourceIndex]
local sourceGroup = source and source[2]
local destWaypointGrp = waypoint[2]
-- Field destinations only reachable from Adoulin city waypoints
if isFieldWaypoint(destWaypointGrp) and not isAdoulinCity(sourceGroup) then
return
end
-- Lower Jeuno can only reach Adoulin cities
if sourceGroup == 10 and not isAdoulinCity(destWaypointGrp) then
return
end
local travelCost = getWaypointTravelCost(sourceIndex, destIndex)
if player:getCurrency('kinetic_unit') < travelCost then
player:messageSpecial(ID.text.INSUFFICIENT_UNITS)
return
end
player:delCurrency('kinetic_unit', travelCost)
player:setLocalVar('waypointPaid', 1)
player:messageSpecial(ID.text.EXPENDED_KINETIC_UNITS, travelCost)
player:updateEvent(0, 0, 0, 0, 0, 0, 0, 1)
end
xi.waypoint.onEventFinish = function(player, csid, option, npc)
if option > 0 and option <= 303 then
local waypoint = waypointInfo[option]
if waypoint == nil then
return
end
-- Validate destination is unlocked
if waypoint[5] ~= nil then
if not player:hasTeleport(xi.teleport.type.WAYPOINT, waypoint[5]) then
return
end
elseif option >= 200 and option <= 210 then
local runeIndex = option - 199
if
runeKeyItems[runeIndex] and
not player:hasKeyItem(runeKeyItems[runeIndex])
then
return
end
end
-- Validate route
local sourceIndex = getWaypointIndex(npc)
local source = waypointInfo[sourceIndex]
local sourceGroup = source and source[2]
local destGroup = waypoint[2]
if isFieldWaypoint(destGroup) and not isAdoulinCity(sourceGroup) then
return
end
if sourceGroup == 10 and not isAdoulinCity(destGroup) then
return
end
if player:getLocalVar('waypointPaid') == 0 then
local travelCost = getWaypointTravelCost(sourceIndex, option)
if player:getCurrency('kinetic_unit') < travelCost then
return
end
player:delCurrency('kinetic_unit', travelCost)
end
player:setLocalVar('waypointPaid', 0)
player:setPos(unpack(waypoint[4]))
elseif option == 1000 then
-- Decline Confirmation (Default Off)
player:setTeleportMenu(xi.teleport.type.WAYPOINT, true)
elseif option == 1001 then
player:setTeleportMenu(xi.teleport.type.WAYPOINT, false)
end
end