landsandboat/scripts/commands/zone.lua

360 lines
17 KiB
Lua

-----------------------------------
-- func: zone
-- desc: Teleports a player to the given zone.
-----------------------------------
---@type TCommand
local commandObj = {}
commandObj.cmdprops =
{
permission = 1,
parameters = 'b'
}
-----------------------------------
-- desc: List of zones with their auto-translated group and message id.
-- note: The format is as follows: groupId, messageId, zoneId
-----------------------------------
local zoneList =
{
{ 0x14, 0xA9, xi.zone.PHANAUET_CHANNEL },
{ 0x14, 0xAA, xi.zone.CARPENTERS_LANDING },
{ 0x14, 0x84, xi.zone.MANACLIPPER },
{ 0x14, 0x85, xi.zone.BIBIKI_BAY },
{ 0x14, 0x8A, xi.zone.ULEGUERAND_RANGE },
{ 0x14, 0x8B, xi.zone.BEARCLAW_PINNACLE },
{ 0x14, 0x86, xi.zone.ATTOHWA_CHASM },
{ 0x14, 0x87, xi.zone.BONEYARD_GULLY },
{ 0x14, 0x88, xi.zone.PSOXJA },
{ 0x14, 0x89, xi.zone.THE_SHROUDED_MAW },
{ 0x14, 0x8C, xi.zone.OLDTON_MOVALPOLOS },
{ 0x14, 0x8D, xi.zone.NEWTON_MOVALPOLOS },
{ 0x14, 0x8E, xi.zone.MINE_SHAFT_2716 },
{ 0x14, 0xDC, xi.zone.MINE_SHAFT_2716 },
{ 0x14, 0xAB, xi.zone.HALL_OF_TRANSFERENCE },
{ 0x14, 0x9B, xi.zone.PROMYVION_HOLLA },
{ 0x14, 0x9A, xi.zone.PROMYVION_HOLLA },
{ 0x14, 0x9C, xi.zone.SPIRE_OF_HOLLA },
{ 0x14, 0x9E, xi.zone.PROMYVION_DEM },
{ 0x14, 0x9D, xi.zone.PROMYVION_DEM },
{ 0x14, 0x9F, xi.zone.SPIRE_OF_DEM },
{ 0x14, 0xA0, xi.zone.PROMYVION_MEA },
{ 0x14, 0xA1, xi.zone.PROMYVION_MEA },
{ 0x14, 0xA2, xi.zone.SPIRE_OF_MEA },
{ 0x14, 0xA3, xi.zone.PROMYVION_VAHZL },
{ 0x14, 0xA4, xi.zone.PROMYVION_VAHZL },
{ 0x14, 0xA5, xi.zone.PROMYVION_VAHZL },
{ 0x14, 0xA6, xi.zone.PROMYVION_VAHZL },
{ 0x14, 0xA7, xi.zone.SPIRE_OF_VAHZL },
{ 0x14, 0xA8, xi.zone.SPIRE_OF_VAHZL },
{ 0x14, 0x90, xi.zone.LUFAISE_MEADOWS },
{ 0x14, 0x91, xi.zone.MISAREAUX_COAST },
{ 0x14, 0x8F, xi.zone.TAVNAZIAN_SAFEHOLD },
{ 0x14, 0x93, xi.zone.PHOMIUNA_AQUEDUCTS },
{ 0x14, 0x94, xi.zone.SACRARIUM },
{ 0x14, 0x96, xi.zone.RIVERNE_SITE_B01 },
{ 0x14, 0x95, xi.zone.RIVERNE_SITE_B01 },
{ 0x14, 0x98, xi.zone.RIVERNE_SITE_A01 },
{ 0x14, 0x97, xi.zone.RIVERNE_SITE_A01 },
{ 0x14, 0x99, xi.zone.MONARCH_LINN },
{ 0x14, 0x92, xi.zone.SEALIONS_DEN },
{ 0x14, 0xAC, xi.zone.ALTAIEU },
{ 0x14, 0xAD, xi.zone.GRAND_PALACE_OF_HUXZOI },
{ 0x14, 0xAE, xi.zone.THE_GARDEN_OF_RUHMET },
{ 0x14, 0xB0, xi.zone.EMPYREAL_PARADOX },
{ 0x14, 0xB1, xi.zone.TEMENOS },
{ 0x14, 0xB2, xi.zone.APOLLYON },
{ 0x14, 0xB4, xi.zone.DYNAMIS_VALKURM },
{ 0x14, 0xB5, xi.zone.DYNAMIS_BUBURIMU },
{ 0x14, 0xB6, xi.zone.DYNAMIS_QUFIM },
{ 0x14, 0xB7, xi.zone.DYNAMIS_TAVNAZIA },
{ 0x14, 0xAF, xi.zone.DIORAMA_ABDHALJS_GHELSBA },
{ 0x14, 0xB8, xi.zone.ABDHALJS_ISLE_PURGONORGO },
{ 0x14, 0xB9, xi.zone.OPEN_SEA_ROUTE_TO_AL_ZAHBI },
{ 0x14, 0xBA, xi.zone.OPEN_SEA_ROUTE_TO_MHAURA },
{ 0x14, 0xBB, xi.zone.AL_ZAHBI },
{ 0x14, 0xDB, xi.zone.AHT_URHGAN_WHITEGATE },
{ 0x14, 0xBC, xi.zone.AHT_URHGAN_WHITEGATE },
{ 0x14, 0xBD, xi.zone.WAJAOM_WOODLANDS },
{ 0x14, 0xBE, xi.zone.BHAFLAU_THICKETS },
{ 0x14, 0xBF, xi.zone.NASHMAU },
{ 0x14, 0xC0, xi.zone.ARRAPAGO_REEF },
{ 0x14, 0xC1, xi.zone.ILRUSI_ATOLL },
{ 0x14, 0xC2, xi.zone.PERIQIA },
{ 0x14, 0xC3, xi.zone.TALACCA_COVE },
{ 0x14, 0xC4, xi.zone.SILVER_SEA_ROUTE_TO_NASHMAU },
{ 0x14, 0xC5, xi.zone.SILVER_SEA_ROUTE_TO_AL_ZAHBI },
{ 0x14, 0xC6, xi.zone.THE_ASHU_TALIF },
{ 0x14, 0xC7, xi.zone.MOUNT_ZHAYOLM },
{ 0x14, 0xC8, xi.zone.HALVUNG },
{ 0x14, 0xC9, xi.zone.LEBROS_CAVERN },
{ 0x14, 0xCA, xi.zone.NAVUKGO_EXECUTION_CHAMBER },
{ 0x14, 0xCB, xi.zone.MAMOOK },
{ 0x14, 0xCC, xi.zone.MAMOOL_JA_TRAINING_GROUNDS },
{ 0x14, 0xCD, xi.zone.JADE_SEPULCHER },
{ 0x14, 0xCE, xi.zone.AYDEEWA_SUBTERRANE },
{ 0x14, 0xCF, xi.zone.LEUJAOAM_SANCTUM },
{ 0x27, 0x0F, xi.zone.CHOCOBO_CIRCUIT },
{ 0x27, 0x10, xi.zone.THE_COLOSSEUM },
{ 0x14, 0xDD, xi.zone.ALZADAAL_UNDERSEA_RUINS },
{ 0x14, 0xDE, xi.zone.ZHAYOLM_REMNANTS },
{ 0x14, 0xDF, xi.zone.ARRAPAGO_REMNANTS },
{ 0x14, 0xE0, xi.zone.BHAFLAU_REMNANTS },
{ 0x14, 0xE1, xi.zone.SILVER_SEA_REMNANTS },
{ 0x14, 0xE2, xi.zone.NYZUL_ISLE },
{ 0x14, 0xDA, xi.zone.HAZHALM_TESTING_GROUNDS },
{ 0x14, 0xD0, xi.zone.CAEDARVA_MIRE },
{ 0x27, 0x11, xi.zone.SOUTHERN_SAN_DORIA_S },
{ 0x27, 0x13, xi.zone.EAST_RONFAURE_S },
{ 0x27, 0x15, xi.zone.JUGNER_FOREST_S },
{ 0x27, 0x23, xi.zone.VUNKERL_INLET_S },
{ 0x27, 0x17, xi.zone.BATALLIA_DOWNS_S },
{ 0x27, 0x3E, xi.zone.LA_VAULE_S },
{ 0x27, 0x40, xi.zone.LA_VAULE_S },
{ 0x27, 0x19, xi.zone.EVERBLOOM_HOLLOW },
{ 0x27, 0x1C, xi.zone.BASTOK_MARKETS_S },
{ 0x27, 0x1E, xi.zone.NORTH_GUSTABERG_S },
{ 0x27, 0x20, xi.zone.GRAUBERG_S },
{ 0x27, 0x25, xi.zone.PASHHOW_MARSHLANDS_S },
{ 0x27, 0x27, xi.zone.ROLANBERRY_FIELDS_S },
{ 0x27, 0x42, xi.zone.BEADEAUX_S },
{ 0x27, 0x22, xi.zone.RUHOTZ_SILVERMINES },
{ 0x27, 0x2B, xi.zone.WINDURST_WATERS_S },
{ 0x27, 0x2D, xi.zone.WEST_SARUTABARUTA_S },
{ 0x27, 0x2F, xi.zone.FORT_KARUGO_NARUGO_S },
{ 0x27, 0x32, xi.zone.MERIPHATAUD_MOUNTAINS_S },
{ 0x27, 0x34, xi.zone.SAUROMUGUE_CHAMPAIGN_S },
{ 0x27, 0x44, xi.zone.CASTLE_OZTROJA_S },
{ 0x14, 0x11, xi.zone.WEST_RONFAURE },
{ 0x14, 0x0F, xi.zone.EAST_RONFAURE },
{ 0x14, 0x51, xi.zone.LA_THEINE_PLATEAU },
{ 0x14, 0x60, xi.zone.VALKURM_DUNES },
{ 0x14, 0x01, xi.zone.JUGNER_FOREST },
{ 0x14, 0x02, xi.zone.BATALLIA_DOWNS },
{ 0x14, 0x64, xi.zone.NORTH_GUSTABERG },
{ 0x14, 0x63, xi.zone.SOUTH_GUSTABERG },
{ 0x14, 0x69, xi.zone.KONSCHTAT_HIGHLANDS },
{ 0x14, 0x2B, xi.zone.PASHHOW_MARSHLANDS },
{ 0x14, 0x07, xi.zone.ROLANBERRY_FIELDS },
{ 0x14, 0x24, xi.zone.BEAUCEDINE_GLACIER },
{ 0x14, 0x4D, xi.zone.XARCABARD },
{ 0x14, 0x3D, xi.zone.CAPE_TERIGGAN },
{ 0x14, 0x3E, xi.zone.EASTERN_ALTEPA_DESERT },
{ 0x14, 0x18, xi.zone.WEST_SARUTABARUTA },
{ 0x14, 0x27, xi.zone.EAST_SARUTABARUTA },
{ 0x14, 0x17, xi.zone.TAHRONGI_CANYON },
{ 0x14, 0x16, xi.zone.BUBURIMU_PENINSULA },
{ 0x14, 0x20, xi.zone.MERIPHATAUD_MOUNTAINS },
{ 0x14, 0x2E, xi.zone.SAUROMUGUE_CHAMPAIGN },
{ 0x14, 0x3F, xi.zone.THE_SANCTUARY_OF_ZITAH },
{ 0x14, 0x7D, xi.zone.ROMAEVE },
{ 0x14, 0x7C, xi.zone.ROMAEVE },
{ 0x14, 0x40, xi.zone.YUHTUNGA_JUNGLE },
{ 0x14, 0x41, xi.zone.YHOATOR_JUNGLE },
{ 0x14, 0x42, xi.zone.WESTERN_ALTEPA_DESERT },
{ 0x14, 0x08, xi.zone.QUFIM_ISLAND },
{ 0x14, 0x0A, xi.zone.BEHEMOTHS_DOMINION },
{ 0x14, 0x43, xi.zone.VALLEY_OF_SORROWS },
{ 0x27, 0x31, xi.zone.GHOYUS_REVERIE },
{ 0x14, 0x6F, xi.zone.RUAUN_GARDENS },
{ 0x14, 0x82, xi.zone.DYNAMIS_BEAUCEDINE },
{ 0x14, 0x83, xi.zone.DYNAMIS_XARCABARD },
{ 0x27, 0x46, xi.zone.BEAUCEDINE_GLACIER_S },
{ 0x27, 0x48, xi.zone.XARCABARD_S },
{ 0x14, 0x65, xi.zone.HORLAIS_PEAK },
{ 0x14, 0x6C, xi.zone.GHELSBA_OUTPOST },
{ 0x14, 0x1F, xi.zone.FORT_GHELSBA },
{ 0x14, 0x5E, xi.zone.YUGHOTT_GROTTO },
{ 0x14, 0x66, xi.zone.PALBOROUGH_MINES },
{ 0x14, 0x1A, xi.zone.WAUGHROON_SHRINE },
{ 0x14, 0x21, xi.zone.GIDDEUS },
{ 0x14, 0x19, xi.zone.BALGAS_DAIS },
{ 0x14, 0x2A, xi.zone.BEADEAUX },
{ 0x14, 0x28, xi.zone.QULUN_DOME },
{ 0x14, 0x68, xi.zone.DAVOI },
{ 0x14, 0x6D, xi.zone.MONASTIC_CAVERN },
{ 0x14, 0x23, xi.zone.CASTLE_OZTROJA },
{ 0x14, 0x04, xi.zone.ALTAR_ROOM },
{ 0x14, 0x44, xi.zone.THE_BOYAHDA_TREE },
{ 0x14, 0x37, xi.zone.DRAGONS_AERY },
{ 0x14, 0x0C, xi.zone.MIDDLE_DELKFUTTS_TOWER },
{ 0x14, 0x0B, xi.zone.UPPER_DELKFUTTS_TOWER },
{ 0x14, 0x36, xi.zone.TEMPLE_OF_UGGALEPIH },
{ 0x14, 0x35, xi.zone.DEN_OF_RANCOR },
{ 0x14, 0x26, xi.zone.CASTLE_ZVAHL_BAILEYS },
{ 0x14, 0x25, xi.zone.CASTLE_ZVAHL_BAILEYS },
{ 0x14, 0x50, xi.zone.CASTLE_ZVAHL_KEEP },
{ 0x14, 0x4F, xi.zone.CASTLE_ZVAHL_KEEP },
{ 0x14, 0x39, xi.zone.SACRIFICIAL_CHAMBER },
{ 0x27, 0x36, xi.zone.GARLAIGE_CITADEL_S },
{ 0x14, 0x5D, xi.zone.THRONE_ROOM },
{ 0x14, 0x2D, xi.zone.RANGUEMONT_PASS },
{ 0x14, 0x32, xi.zone.BOSTAUNIEUX_OUBLIETTE },
{ 0x14, 0x3B, xi.zone.CHAMBER_OF_ORACLES },
{ 0x14, 0x1D, xi.zone.TORAIMARAI_CANAL },
{ 0x14, 0x5C, xi.zone.FULL_MOON_FOUNTAIN },
{ 0x27, 0x29, xi.zone.CRAWLERS_NEST_S },
{ 0x14, 0x61, xi.zone.ZERUHN_MINES },
{ 0x14, 0x5B, xi.zone.KORROLOKA_TUNNEL },
{ 0x14, 0x5A, xi.zone.KUFTAL_TUNNEL },
{ 0x27, 0x1A, xi.zone.THE_ELDIEME_NECROPOLIS_S },
{ 0x14, 0x59, xi.zone.SEA_SERPENT_GROTTO },
{ 0x14, 0x71, xi.zone.VELUGANNON_PALACE },
{ 0x14, 0x70, xi.zone.VELUGANNON_PALACE },
{ 0x14, 0x72, xi.zone.THE_SHRINE_OF_RUAVITAU },
{ 0x14, 0xB3, xi.zone.STELLAR_FULCRUM },
{ 0x14, 0x73, xi.zone.LALOFF_AMPHITHEATER },
{ 0x14, 0x74, xi.zone.THE_CELESTIAL_NEXUS },
{ 0x14, 0x0D, xi.zone.LOWER_DELKFUTTS_TOWER },
{ 0x14, 0x7E, xi.zone.DYNAMIS_SAN_DORIA },
{ 0x14, 0x7F, xi.zone.DYNAMIS_BASTOK },
{ 0x14, 0x80, xi.zone.DYNAMIS_WINDURST },
{ 0x14, 0x81, xi.zone.DYNAMIS_JEUNO },
{ 0x14, 0x6E, xi.zone.KING_RANPERRES_TOMB },
{ 0x14, 0x62, xi.zone.DANGRUF_WADI },
{ 0x14, 0x1C, xi.zone.INNER_HORUTOTO_RUINS },
{ 0x14, 0x03, xi.zone.ORDELLES_CAVES },
{ 0x14, 0x1B, xi.zone.OUTER_HORUTOTO_RUINS },
{ 0x14, 0x6A, xi.zone.THE_ELDIEME_NECROPOLIS },
{ 0x14, 0x67, xi.zone.GUSGEN_MINES },
{ 0x14, 0x2C, xi.zone.CRAWLERS_NEST },
{ 0x14, 0x15, xi.zone.MAZE_OF_SHAKHRAMI },
{ 0x14, 0x14, xi.zone.GARLAIGE_CITADEL },
{ 0x14, 0x77, xi.zone.CLOISTER_OF_GALES },
{ 0x14, 0x75, xi.zone.CLOISTER_OF_STORMS },
{ 0x14, 0x7A, xi.zone.CLOISTER_OF_FROST },
{ 0x14, 0x4A, xi.zone.FEIYIN },
{ 0x14, 0x58, xi.zone.IFRITS_CAULDRON },
{ 0x14, 0x6B, xi.zone.QUBIA_ARENA },
{ 0x14, 0x78, xi.zone.CLOISTER_OF_FLAMES },
{ 0x14, 0x57, xi.zone.QUICKSAND_CAVES },
{ 0x14, 0x76, xi.zone.CLOISTER_OF_TREMORS },
{ 0x14, 0x79, xi.zone.CLOISTER_OF_TIDES },
{ 0x14, 0x34, xi.zone.GUSTAV_TUNNEL },
{ 0x14, 0x33, xi.zone.LABYRINTH_OF_ONZOZO },
{ 0x14, 0x4C, xi.zone.SOUTHERN_SAN_DORIA },
{ 0x14, 0x30, xi.zone.NORTHERN_SAN_DORIA },
{ 0x14, 0x52, xi.zone.PORT_SAN_DORIA },
{ 0x14, 0x22, xi.zone.CHATEAU_DORAGUILLE },
{ 0x14, 0x46, xi.zone.BASTOK_MINES },
{ 0x14, 0x56, xi.zone.BASTOK_MARKETS },
{ 0x14, 0x3C, xi.zone.PORT_BASTOK },
{ 0x14, 0x2F, xi.zone.METALWORKS },
{ 0x14, 0x3A, xi.zone.WINDURST_WATERS },
{ 0x14, 0x54, xi.zone.WINDURST_WALLS },
{ 0x14, 0x45, xi.zone.PORT_WINDURST },
{ 0x14, 0x38, xi.zone.WINDURST_WOODS },
{ 0x14, 0x55, xi.zone.HEAVENS_TOWER },
{ 0x14, 0x13, xi.zone.RULUDE_GARDENS },
{ 0x14, 0x4E, xi.zone.UPPER_JEUNO },
{ 0x14, 0x0E, xi.zone.LOWER_JEUNO },
{ 0x14, 0x06, xi.zone.PORT_JEUNO },
{ 0x14, 0x31, xi.zone.RABAO },
{ 0x14, 0x5F, xi.zone.SELBINA },
{ 0x14, 0x1E, xi.zone.MHAURA },
{ 0x14, 0x29, xi.zone.KAZHAM },
{ 0x14, 0x7B, xi.zone.HALL_OF_THE_GODS },
{ 0x14, 0x09, xi.zone.NORG },
{ 0x27, 0x4C, xi.zone.WESTERN_ADOULIN },
{ 0x27, 0x4D, xi.zone.EASTERN_ADOULIN },
{ 0x27, 0x4E, xi.zone.RALA_WATERWAYS },
{ 0x27, 0x4F, xi.zone.YAHSE_HUNTING_GROUNDS },
{ 0x27, 0x50, xi.zone.CEIZAK_BATTLEGROUNDS },
{ 0x27, 0x51, xi.zone.FORET_DE_HENNETIEL },
{ 0x27, 0x56, xi.zone.YORCIA_WEALD },
{ 0x27, 0x52, xi.zone.MORIMAR_BASALT_FIELDS },
{ 0x27, 0x57, xi.zone.MARJAMI_RAVINE },
{ 0x27, 0x5C, xi.zone.KAMIHR_DRIFTS },
{ 0x27, 0x53, xi.zone.SIH_GATES },
{ 0x27, 0x54, xi.zone.MOH_GATES },
{ 0x27, 0x55, xi.zone.CIRDAS_CAVERNS },
{ 0x27, 0x58, xi.zone.DHO_GATES },
{ 0x27, 0x5D, xi.zone.WOH_GATES },
{ 0x27, 0x12, xi.zone.OUTER_RAKAZNAR },
{ 0x27, 0x5A, xi.zone.MOG_GARDEN },
{ 0x27, 0x59, xi.zone.CELENNIA_MEMORIAL_LIBRARY },
{ 0x27, 0x5B, xi.zone.FERETORY },
{ 0x14, 0x09, xi.zone.ESCHA_ZITAH },
{ 0x27, 0x1B, xi.zone.ESCHA_RUAUN },
{ 0x27, 0x1D, xi.zone.REISENJIMA },
}
local function error(player, msg)
player:printToPlayer(msg)
player:printToPlayer('!zone <zone ID or autotranslate phrase>')
end
local function getBytePos(s, needle)
for i = 1, string.len(s), 1 do
if string.byte(s, i) == needle then
return i
end
end
return nil
end
-----------------------------------
-- func: onTrigger
-- desc: Called when this command is invoked.
-----------------------------------
commandObj.onTrigger = function(player, bytes)
local x = 0
local y = 0
local z = 0
local rot = 0
local zone
if bytes == nil then
error(player, 'You must provide a zone ID or autotranslate phrase.')
return
end
bytes = string.sub(bytes, 6)
local atpos = getBytePos(bytes, 253)
-- validate destination
if atpos ~= nil then
-- destination is an auto-translate phrase
local groupId = string.byte(bytes, atpos + 3)
local messageId = string.byte(bytes, atpos + 4)
for k, v in pairs(zoneList) do
if v[1] == groupId and v[2] == messageId then
x = v[4] or 0
y = v[5] or 0
z = v[6] or 0
rot = 0
zone = v[3]
break
end
end
if zone == nil then
error(player, 'Auto-translated phrase is not a zone.')
return
end
else
-- destination is a zone ID.
zone = tonumber(bytes)
if zone == nil or zone < 0 or zone >= xi.zone.MAX_ZONE then
error(player, 'Invalid zone ID.')
return
end
for k, v in pairs(zoneList) do
if v[3] == zone then
x = v[4] or 0
y = v[5] or 0
z = v[6] or 0
rot = 0
zone = v[3]
break
end
end
end
-- send player to destination
player:setPos(x, y, z, rot, zone)
end
return commandObj