landsandboat/scripts/globals/conquest.lua
2026-05-04 14:53:30 -04:00

1712 lines
80 KiB
Lua

-----------------------------------
-- Functions for Conquest system
-----------------------------------
require('scripts/globals/extravaganza')
require('scripts/globals/garrison')
require('scripts/globals/teleports')
require('scripts/globals/missions')
require('scripts/globals/npc_util')
-----------------------------------
xi = xi or {}
xi.conquest = xi.conquest or {}
-----------------------------------
-- (LOCAL) constants
-----------------------------------
local conquestConstants =
{
TALLY_START = 0,
TALLY_END = 1,
UPDATE = 2,
}
-----------------------------------
-- (LOCAL) expeditionary forces
-- TODO: implement this menu
-----------------------------------
--[[
local exForceMenuData =
{
0x20006, ZULK_EF, 103, 0x000040, 20, xi.ki.ZULKHEIM_EF_INSIGNIA,
0x20007, NORV_EF, 104, 0x000080, 25, xi.ki.NORVALLEN_EF_INSIGNIA,
0x20009, DERF_EF, 109, 0x000200, 25, xi.ki.DERFLAND_EF_INSIGNIA,
0x2000B, KOLS_EF, 118, 0x000800, 20, xi.ki.KOLSHUSHU_EF_INSIGNIA,
0x2000C, ARAG_EF, 119, 0x001000, 25, xi.ki.ARAGONEU_EF_INSIGNIA,
0x2000D, FAUR_EF, 111, 0x002000, 35, xi.ki.FAUREGANDI_EF_INSIGNIA,
0x2000E, VALD_EF, 112, 0x004000, 40, xi.ki.VALDEAUNIA_EF_INSIGNIA,
0x2000F, QUFI_EF, 126, 0x008000, 25, xi.ki.QUFIM_EF_INSIGNIA,
0x20010, LITE_EF, 121, 0x010000, 35, xi.ki.LITELOR_EF_INSIGNIA,
0x20011, KUZO_EF, 114, 0x020000, 40, xi.ki.KUZOTZ_EF_INSIGNIA,
0x20012, VOLL_EF, 113, 0x040000, 65, xi.ki.VOLLBOW_EF_INSIGNIA,
0x20013, ELLO_EF, 123, 0x080000, 35, xi.ki.ELSHIMO_LOWLANDS_EF_INSIGNIA,
0x20014, ELUP_EF, 124, 0x100000, 45, xi.ki.ELSHIMO_UPLANDS_EF_INSIGNIA
}
]]--
local function getExForceAvailable(player, guardNation)
return 0
end
local function getExForceReward(player, guardNation)
return 0
end
-----------------------------------
-- (LOCAL) outposts
-----------------------------------
local outposts =
{
[xi.region.RONFAURE] = { zone = xi.zone.WEST_RONFAURE, ki = xi.ki.RONFAURE_SUPPLIES, cp = 10, lvl = 10, fee = 100 },
[xi.region.ZULKHEIM] = { zone = xi.zone.VALKURM_DUNES, ki = xi.ki.ZULKHEIM_SUPPLIES, cp = 30, lvl = 10, fee = 100 },
[xi.region.NORVALLEN] = { zone = xi.zone.JUGNER_FOREST, ki = xi.ki.NORVALLEN_SUPPLIES, cp = 40, lvl = 15, fee = 150 },
[xi.region.GUSTABERG] = { zone = xi.zone.NORTH_GUSTABERG, ki = xi.ki.GUSTABERG_SUPPLIES, cp = 10, lvl = 10, fee = 100 },
[xi.region.DERFLAND] = { zone = xi.zone.PASHHOW_MARSHLANDS, ki = xi.ki.DERFLAND_SUPPLIES, cp = 40, lvl = 15, fee = 150 },
[xi.region.SARUTABARUTA] = { zone = xi.zone.WEST_SARUTABARUTA, ki = xi.ki.SARUTABARUTA_SUPPLIES, cp = 10, lvl = 10, fee = 100 },
[xi.region.KOLSHUSHU] = { zone = xi.zone.BUBURIMU_PENINSULA, ki = xi.ki.KOLSHUSHU_SUPPLIES, cp = 40, lvl = 10, fee = 100 },
[xi.region.ARAGONEU] = { zone = xi.zone.MERIPHATAUD_MOUNTAINS, ki = xi.ki.ARAGONEU_SUPPLIES, cp = 40, lvl = 15, fee = 150 },
[xi.region.FAUREGANDI] = { zone = xi.zone.BEAUCEDINE_GLACIER, ki = xi.ki.FAUREGANDI_SUPPLIES, cp = 70, lvl = 35, fee = 350 },
[xi.region.VALDEAUNIA] = { zone = xi.zone.XARCABARD, ki = xi.ki.VALDEAUNIA_SUPPLIES, cp = 50, lvl = 40, fee = 400 },
[xi.region.QUFIMISLAND] = { zone = xi.zone.QUFIM_ISLAND, ki = xi.ki.QUFIM_SUPPLIES, cp = 60, lvl = 15, fee = 150 },
[xi.region.LITELOR] = { zone = xi.zone.THE_SANCTUARY_OF_ZITAH, ki = xi.ki.LITELOR_SUPPLIES, cp = 40, lvl = 25, fee = 250 },
[xi.region.KUZOTZ] = { zone = xi.zone.EASTERN_ALTEPA_DESERT, ki = xi.ki.KUZOTZ_SUPPLIES, cp = 70, lvl = 30, fee = 300 },
[xi.region.VOLLBOW] = { zone = xi.zone.CAPE_TERIGGAN, ki = xi.ki.VOLLBOW_SUPPLIES, cp = 70, lvl = 50, fee = 500 },
[xi.region.ELSHIMO_LOWLANDS] = { zone = xi.zone.YUHTUNGA_JUNGLE, ki = xi.ki.ELSHIMO_LOWLANDS_SUPPLIES, cp = 70, lvl = 25, fee = 250 },
[xi.region.ELSHIMO_UPLANDS] = { zone = xi.zone.YHOATOR_JUNGLE, ki = xi.ki.ELSHIMO_UPLANDS_SUPPLIES, cp = 70, lvl = 35, fee = 350 },
[xi.region.TULIA] = { zone = xi.zone.RUAUN_GARDENS, cp = 0, lvl = 70, fee = 500 },
[xi.region.MOVALPOLOS] = { zone = xi.zone.OLDTON_MOVALPOLOS, cp = 40, lvl = 25, fee = 250 },
[xi.region.TAVNAZIANARCH] = { zone = xi.zone.LUFAISE_MEADOWS, ki = xi.ki.TAVNAZIAN_ARCHIPELAGO_SUPPLIES, cp = 70, lvl = 30, fee = 300 },
}
local function hasOutpost(player, region)
local hasOP = player:hasTeleport(player:getNation(), region + 5)
if not hasOP then
if xi.settings.main.UNLOCK_OUTPOST_WARPS == 2 then
hasOP = true
elseif xi.settings.main.UNLOCK_OUTPOST_WARPS == 1 then
hasOP = region <= xi.region.ELSHIMO_UPLANDS
end
end
return hasOP
end
local function setHomepointFee(player, guardNation)
local pNation = player:getNation()
local fee = 0
if
pNation ~= guardNation and
not xi.conquest.areAllies(pNation, guardNation)
then
local rank = player:getRank(player:getNation())
if rank <= 5 then
fee = 100 * math.pow(2, rank - 1)
else
fee = (800 * rank) - 2400
end
end
return fee
end
local function getRegionsMask(nation)
local mask = 0
for region = xi.region.RONFAURE, xi.region.TAVNAZIANARCH do
if GetRegionOwner(region) == nation then
mask = bit.bor(mask, bit.lshift(1, region + 5)) -- Region bits start at 5th bit
end
end
return mask
end
local function getAllowedTeleports(player, nation)
local allowedTeleports = 0x3F40001F -- All outposts set (0 indicates allowed)
if xi.settings.main.UNLOCK_OUTPOST_WARPS == 2 then
return allowedTeleports -- Allow all outposts
elseif xi.settings.main.UNLOCK_OUTPOST_WARPS == 1 then
return 0x3FE0001F -- Allow all outposts except for Tulia and Tavnazia
end
for region = xi.region.RONFAURE, xi.region.TAVNAZIANARCH do
if not xi.conquest.canTeleportToOutpost(player, region) then
allowedTeleports = bit.bor(allowedTeleports, bit.lshift(1, region + 5)) -- Region bits start at 5th bit
end
end
return allowedTeleports
end
-----------------------------------
-- (LOCAL) supply runs
-----------------------------------
-- produce supply quest mask for the nation based on current conquest standings
local function suppliesAvailableBitmask(player, nation)
local mask = 0x7F00001F
if player:getCharVar('supplyQuest_started') == VanadielUniqueDay() then
mask = 0xFFFFFFFF -- Need to wait 1 vanadiel day
end
for k, v in pairs(outposts) do
if v.ki and player:hasKeyItem(v.ki) then
mask = -1
break
end
end
if mask ~= -1 and mask ~= 0xFFFFFFFF then
for i = 0, 18 do
if
GetRegionOwner(i) ~= nation or
i == 16 or
i == 17 or
(
i == 18 and
not player:hasCompletedMission(xi.mission.log_id.COP, xi.mission.id.cop.DARKNESS_NAMED)
)
then
mask = mask + 2^(i + 5)
end
end
end
return mask
end
local function areSuppliesRotten(player, npc, guardType)
local fresh = player:getCharVar('supplyQuest_fresh')
local region = player:getCharVar('supplyQuest_region')
local rotten = false
local text = zones[player:getZoneID()].text
if region > 0 and fresh <= GetSystemTime() then
rotten = true
end
if rotten then
if guardType <= xi.conquest.guard.FOREIGN then
player:showText(npc, text.CONQUEST + 40) -- 'We will dispose of those unusable supplies.'
else
player:showText(npc, text.CONQUEST - 1) -- 'Hmm... These supplies you have brought us are too old to be of any use.'
end
local ki = outposts[region].ki
player:delKeyItem(ki)
player:messageSpecial(text.KEYITEM_LOST, ki)
player:setCharVar('supplyQuest_started', 0)
player:setCharVar('supplyQuest_region', 0)
player:setCharVar('supplyQuest_fresh', 0)
end
return rotten
end
local function canDeliverSupplies(player, guardNation, guardEvent, guardRegion)
local delivered = false
local region = player:getCharVar('supplyQuest_region')
if region == guardRegion and player:hasKeyItem(outposts[region].ki) then
delivered = true
player:startEvent(guardEvent, 16, 0, 0, 0, 1, 0, 0, 255) -- 'you have brought us supplies!'
end
return delivered
end
-----------------------------------
-- (LOCAL) overseers
-----------------------------------
local overseerOffsets =
{
[xi.region.RONFAURE] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Doladepaiton, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Ballie, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- Flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- Flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Yoshihiro, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Molting Moth, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- Flag
{ offset = 12, nation = xi.nation.BASTOK }, -- Flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Kyanta-Pakyanta, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Tottoto, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- Flag
{ offset = 13, nation = xi.nation.WINDURST }, -- Flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- Flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- Flag
{ offset = 10, nation = xi.nation.OTHER }, -- Harvetour
},
[xi.region.ZULKHEIM] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Quanteilleron, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Prunilla, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Tsunashige, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Fighting Ant, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 13, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Nyata-Mobuta, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Tebubu, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 14, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 15, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Medicine Axe
},
[xi.region.NORVALLEN] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Chaplion, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Taumiale, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Takamoto, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Pure Heart, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Bubchu-Bibinchu, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Geruru, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Mionie
},
[xi.region.GUSTABERG] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Ennigreaud, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Quellebie, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Shigezane, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Heavy Fog, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Kuuwari-Aori, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Butsutsu, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Kuleo
},
[xi.region.DERFLAND] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Mesachedeau, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Ioupie, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Souun, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Sharp Tooth, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Mokto-Lankto, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Shikoko, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Tahmasp
},
[xi.region.SARUTABARUTA] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Naguipeillont, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Banege, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Ryokei, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Slow Axe, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Roshina-Kuleshuna, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Darumomo, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Mahien-Uhien
},
[xi.region.KOLSHUSHU] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Bonbavour, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Craigine, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Ishin, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Wise Turtle, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Ganemu-Punnemu, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Mashasha, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Lobho Ukipturi
},
[xi.region.ARAGONEU] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Chegourt, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Buliame, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Akane, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Three Steps, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Donmo-Boronmo, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Daruru, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Mushosho
},
[xi.region.FAUREGANDI] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Parledaire, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Leaufetie, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Akane, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Rattling Rain, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Ryunchi-Pauchi, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Chopapa, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Gueriette
},
[xi.region.VALDEAUNIA] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Jeantelas, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Pilcha, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Kaya, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Heavy Bear, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Magumo-Yagimo, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Tememe, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Pelogrant
},
[xi.region.QUFIMISLAND] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Pitoire, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Matica, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Sasa, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Singing Blade, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Tsonga-Hoponga, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Numumu, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Jiwon
},
[xi.region.LITELOR] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Credaurion, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Limion, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Calliope, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Dedden, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Ajimo-Majimo, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Ochocho, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Kasim
},
[xi.region.KUZOTZ] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Eaulevisat, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Laimeve, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Lindgard, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Daborn, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Variko-Njariko, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Sahgygy, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Sowande
},
[xi.region.VOLLBOW] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Salimardi, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Paise, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Sarmistha, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Dultwa, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Voranbo-Natanbo, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Orukeke, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Bright Moon
},
[xi.region.ELSHIMO_LOWLANDS] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Zorchorevi, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Mupia, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Mahol, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Bammiro, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Uphra-Kophra, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Richacha, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Robino-Mobino
},
[xi.region.ELSHIMO_UPLANDS] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Ilieumort, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Emila, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Mintoo, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Guddal, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Etaj-Pohtaj, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Ghantata, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Mugha Dovajaiho
},
[xi.region.TULIA] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- flag
{ offset = 3, nation = xi.nation.BEASTMEN }, -- flag
},
[xi.region.MOVALPOLOS] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- flag
{ offset = 3, nation = xi.nation.BEASTMEN }, -- flag
},
[xi.region.TAVNAZIANARCH] =
{
{ offset = 0, nation = xi.nation.SANDORIA }, -- Jemmoquel, R.K.
{ offset = 7, nation = xi.nation.SANDORIA }, -- Chilaumme, R.K.
{ offset = 3, nation = xi.nation.SANDORIA }, -- flag
{ offset = 11, nation = xi.nation.SANDORIA }, -- flag
{ offset = 1, nation = xi.nation.BASTOK }, -- Yoram, I.M.
{ offset = 8, nation = xi.nation.BASTOK }, -- Ghost Talker, I.M.
{ offset = 4, nation = xi.nation.BASTOK }, -- flag
{ offset = 12, nation = xi.nation.BASTOK }, -- flag
{ offset = 2, nation = xi.nation.WINDURST }, -- Teldo-Moroldo, W.W.
{ offset = 9, nation = xi.nation.WINDURST }, -- Cotete, W.W.
{ offset = 5, nation = xi.nation.WINDURST }, -- flag
{ offset = 13, nation = xi.nation.WINDURST }, -- flag
{ offset = 6, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 14, nation = xi.nation.BEASTMEN }, -- flag
{ offset = 10, nation = xi.nation.OTHER }, -- Jersey
},
}
local crystals =
{
[xi.item.FIRE_CRYSTAL] = 12,
[xi.item.ICE_CRYSTAL] = 12,
[xi.item.WIND_CRYSTAL] = 12,
[xi.item.EARTH_CRYSTAL] = 12,
[xi.item.LIGHTNING_CRYSTAL] = 12,
[xi.item.WATER_CRYSTAL] = 12,
[xi.item.LIGHT_CRYSTAL] = 16,
[xi.item.DARK_CRYSTAL] = 16,
[xi.item.INFERNO_CRYSTAL] = 12,
[xi.item.GLACIER_CRYSTAL] = 12,
[xi.item.CYCLONE_CRYSTAL] = 12,
[xi.item.TERRA_CRYSTAL] = 12,
[xi.item.PLASMA_CRYSTAL] = 12,
[xi.item.TORRENT_CRYSTAL] = 12,
[xi.item.AURORA_CRYSTAL] = 16,
[xi.item.TWILIGHT_CRYSTAL] = 16,
}
local expRings =
{
[xi.item.CHARIOT_BAND] = { chargesWhenFull = 7, costPerCharge = 50 },
[xi.item.EMPRESS_BAND] = { chargesWhenFull = 7, costPerCharge = 100 },
[xi.item.EMPEROR_BAND] = { chargesWhenFull = 3, costPerCharge = 200 },
}
local function conquestRanking()
-- computes part of argument 3 for gate guard events. represents the conquest standing of the 3 nations. Verified.
return GetNationRank(xi.nation.SANDORIA) + 4 * GetNationRank(xi.nation.BASTOK) + 16 * GetNationRank(xi.nation.WINDURST)
end
xi.conquest.toggleRegionalNPCs = function(zone)
-- Show/Hide regional NPCs
-- If there is a draw or a 1st place Alliance, those NPCs won't be available anywhere.
local id = zone:getID()
if
id == xi.zone.PORT_BASTOK or
id == xi.zone.SOUTHERN_SAN_DORIA or
id == xi.zone.WINDURST_WOODS
then
local regionalNPCNames =
{
'Nokkhi_Jinjahl',
'Ominous_Cloud',
'Valeriano',
'Mokop-Sankop',
'Cheh_Raihah',
'Nalta',
'Dahjal'
}
-- TODO: Do we need to worry about beastmen's rank?
local rankings =
{
{ GetNationRank(xi.nation.SANDORIA), xi.zone.SOUTHERN_SAN_DORIA },
{ GetNationRank(xi.nation.BASTOK), xi.zone.PORT_BASTOK },
{ GetNationRank(xi.nation.WINDURST), xi.zone.WINDURST_WOODS },
}
table.sort(rankings, function(a, b)
return a[1] < b[1]
end)
local firstPlaceZone = rankings[1][2]
-- check if the first and second are both rank 1 (thus a tie)
local firstAndSecondTie = rankings[1][1] == rankings[2][1]
if
firstPlaceZone == id and
not firstAndSecondTie
then
print('Showing regional conquest NPCs in: ' .. zone:getName())
else
print('Hiding regional conquest NPCs in: ' .. zone:getName())
end
for _, name in pairs(regionalNPCNames) do
local results = zone:queryEntitiesByName(name)
for _, entity in pairs(results) do
-- Will be the real entity if it has an X position
if math.abs(entity:getXPos()) > 0 then
-- Hide all of these NPCs by default
entity:setStatus(xi.status.DISAPPEAR)
-- If there is a clear winner, and not a tie, show the NPCs
if
id == firstPlaceZone and
not firstAndSecondTie
then
entity:setStatus(xi.status.NORMAL)
end
end
end
end
end
end
local function getArg1(player, guardNation, guardType)
local pNation = player:getNation()
local output = 0
local signet = 0
local cipher = xi.extravaganza.campaignActive() * 20 * 65536
local voucher = player:hasKeyItem(xi.ki.CONQUEST_PROMOTION_VOUCHER) and 0x20000 or 0
if guardNation == xi.nation.WINDURST then
output = 33
elseif guardNation == xi.nation.SANDORIA then
output = 1
elseif guardNation == xi.nation.BASTOK then
output = 17
end
if guardNation == pNation then
signet = 0
else
signet = 7
if xi.conquest.areAllies(pNation, guardNation) then
signet = 2^(2 - pNation)
end
end
if guardNation == xi.nation.OTHER then
output = (pNation * 16) + (3 * 256) + 65537
else
output = output + 256 * signet
end
if guardType == xi.conquest.guard.CITY then
output = output + voucher
end
if guardType >= xi.conquest.guard.OUTPOST then
output = output - 1
end
if output >= 1792 and guardType >= xi.conquest.guard.OUTPOST then
output = 1808
end
return output + cipher
end
-- arg6 encodes a player's rank and nationality:
-- bits 1-4 encode the rank of the player (verified that bit 4 is part of the rank number so ranks could have gone up to 31.)
-- bits 5-6 seem to encode the citizenship as below. This part needs more testing and verification.
local function getArg6(player)
return player:getRank(player:getNation()) + (player:getNation() * 32)
end
-----------------------------------
-- (LOCAL) overseer stock
-----------------------------------
---@class overseerInvComming : { [integer] : { cp: integer, lvl: integer, item: xi.item, rank: integer? } }
local overseerInvCommon =
{
[32928] = { cp = 7, lvl = 1, item = xi.item.SCROLL_OF_INSTANT_RERAISE },
[32929] = { cp = 10, lvl = 1, item = xi.item.SCROLL_OF_INSTANT_WARP },
[32930] = { cp = 2500, lvl = 1, item = xi.item.RETURN_RING },
[32931] = { cp = 9000, lvl = 1, item = xi.item.HOMING_RING },
[32933] = { cp = 500, lvl = 1, item = xi.item.CHARIOT_BAND },
[32934] = { cp = 1000, lvl = 1, item = xi.item.EMPRESS_BAND },
[32935] = { cp = 2000, lvl = 1, item = xi.item.EMPEROR_BAND },
[32936] = { cp = 5000, lvl = 1, item = xi.item.WARP_RING },
[32937] = { cp = 1000, lvl = 1, item = xi.item.CIPHER_OF_TENZENS_ALTER_EGO },
[32938] = { cp = 1000, lvl = 1, item = xi.item.CIPHER_OF_RAHALS_ALTER_EGO },
[32939] = { cp = 1000, lvl = 1, item = xi.item.CIPHER_OF_KUKKIS_ALTER_EGO },
[32941] = { cp = 20000, lvl = 1, item = xi.item.REFINED_CHAIR_SET, rank = 10 },
[32942] = { cp = 1000, lvl = 1, item = xi.item.CIPHER_OF_MAKKIS_ALTER_EGO },
}
---@class overseerInvNation : { [xi.nation] : { [integer]: { rank: integer, cp: integer, lvl: integer, item: xi.item, place: integer? } } }
local overseerInvNation =
{
[xi.nation.SANDORIA] =
{
[32768] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.ROYAL_ARCHERS_LONGBOW },
[32769] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.ROYAL_ARCHERS_SWORD },
[32770] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.ROYAL_FOOTMANS_BANDANA },
[32771] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.ROYAL_FOOTMANS_GLOVES },
[32772] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.ROYAL_FOOTMANS_BOOTS },
[32773] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.ROYAL_ARCHERS_CESTI, place = 2 },
[32774] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.ROYAL_FOOTMANS_TUNIC, place = 1 },
[32784] = { rank = 2, cp = 2000, lvl = 18, item = xi.item.ROYAL_SPEARMANS_SPEAR },
[32785] = { rank = 2, cp = 2000, lvl = 10, item = xi.item.ROYAL_FOOTMANS_VEST },
[32786] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.ROYAL_FOOTMANS_TROUSERS },
[32787] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.ROYAL_SPEARMANS_HORN, place = 2 },
[32788] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.ROYAL_FOOTMANS_CLOGS, place = 1 },
[32800] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.ROYAL_SQUIRES_HALBERD },
[32801] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.ROYAL_SQUIRES_COLLAR },
[32802] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.ROYAL_SQUIRES_HELM },
[32803] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.ROYAL_SQUIRES_MUFFLERS },
[32804] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.ROYAL_SQUIRES_SOLLERETS },
[32805] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.ROYAL_SQUIRES_DAGGER, place = 2 },
[32806] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.ROYAL_SQUIRES_MACE, place = 1 },
[32807] = { rank = 3, cp = 4000, lvl = 1, item = xi.item.SAN_DORIAN_RING, place = 1 },
[32816] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.ROYAL_SWORDSMANS_BLADE },
[32817] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.ROYAL_SQUIRES_CHAINMAIL },
[32818] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.ROYAL_SQUIRES_BREECHES },
[32819] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.ROYAL_SQUIRES_ROBE, place = 2 },
[32820] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.ROYAL_SQUIRES_SHIELD, place = 1 },
[32832] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.ROYAL_KNIGHT_ARMY_LANCE },
[32833] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TEMPLE_KNIGHT_ARMY_SWORD },
[32834] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.ROYAL_KNIGHT_ARMY_SHIELD },
[32835] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TEMPLE_KNIGHT_ARMY_SHIELD },
[32836] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.ROYAL_KNIGHT_ARMY_COLLAR },
[32837] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TEMPLE_KNIGHT_ARMY_COLLAR },
[32838] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.ROYAL_KNIGHTS_MUFFLERS },
[32839] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.ROYAL_KNIGHTS_SOLLERETS },
[32840] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.ROYAL_KNIGHTS_BELT, place = 2 },
[32841] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.ROYAL_KNIGHTS_CLOAK, place = 1 },
[32848] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.ROYAL_ARMY_MANTLE },
[32849] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.ROYAL_GUARDS_COLLAR },
[32850] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.ROYAL_KNIGHTS_BASCINET },
[32851] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.ROYAL_KNIGHTS_AKETON },
[32852] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.ROYAL_KNIGHTS_CHAINMAIL, place = 1 },
[32853] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.ROYAL_KNIGHTS_BREECHES, place = 1 },
[32854] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.ROYAL_GUARDS_SHIELD, place = 2 },
[32855] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.ROYAL_GUARDS_ROD, place = 1 },
[32856] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.ROYAL_GUARDS_SWORD, place = 1 },
[32857] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.ROYAL_GUARDS_FLEURET, place = 1 },
[32864] = { rank = 7, cp = 32000, lvl = 60, item = xi.item.TEMPLE_KNIGHTS_QUIVER },
[32865] = { rank = 7, cp = 32000, lvl = 60, item = xi.item.GRAND_KNIGHTS_LANCE, place = 2 },
[32866] = { rank = 7, cp = 32000, lvl = 60, item = xi.item.GRAND_KNIGHTS_RING, place = 1 },
[32880] = { rank = 8, cp = 40000, lvl = 65, item = xi.item.GRAND_TEMPLE_KNIGHTS_GAUNTLETS },
[32881] = { rank = 8, cp = 40000, lvl = 65, item = xi.item.GRAND_TEMPLE_KNIGHTS_BANGLES, place = 2 },
[32882] = { rank = 8, cp = 40000, lvl = 65, item = xi.item.GRAND_TEMPLE_KNIGHTS_COLLAR, place = 1 },
[32896] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.RESERVE_CAPTAINS_GREATSWORD },
[32897] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.RESERVE_CAPTAINS_PICK },
[32898] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.RESERVE_CAPTAINS_MACE, place = 2 },
[32899] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.RESERVE_CAPTAINS_LANCE, place = 1 },
[32912] = { rank = 10, cp = 56000, lvl = 1, item = xi.item.KINGDOM_AKETON, place = 1 },
[32932] = { rank = 10, cp = 5000, lvl = 1, item = xi.item.KINGDOM_SIGNET_STAFF },
[32940] = { rank = 10, cp = 10000, lvl = 1, item = xi.item.IMPERIAL_CHAIR_SET },
},
[xi.nation.BASTOK] =
{
[32768] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.LEGIONNAIRES_KNUCKLES },
[32769] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.LEGIONNAIRES_CROSSBOW },
[32770] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.LEGIONNAIRES_AXE },
[32771] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.LEGIONNAIRES_CAP },
[32772] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.LEGIONNAIRES_MITTENS },
[32773] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.LEGIONNAIRES_LEGGINGS },
[32774] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.LEGIONNAIRES_STAFF, place = 2 },
[32775] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.LEGIONNAIRES_SCYTHE, place = 1 },
[32784] = { rank = 2, cp = 2000, lvl = 18, item = xi.item.DECURIONS_HAMMER },
[32785] = { rank = 2, cp = 2000, lvl = 10, item = xi.item.LEGIONNAIRES_HARNESS },
[32786] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.LEGIONNAIRES_SUBLIGAR },
[32787] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.DECURIONS_DAGGER, place = 2 },
[32788] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.DECURIONS_SHIELD, place = 1 },
[32800] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.CENTURIONS_AXE },
[32801] = { rank = 3, cp = 4000, lvl = 10, item = xi.item.REPUBLICAN_BRONZE_MEDAL },
[32802] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.CENTURIONS_VISOR },
[32803] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.CENTURIONS_SCALE_MAIL },
[32804] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.CENTURIONS_FINGER_GAUNTLETS },
[32805] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.CENTURIONS_CUISSES },
[32806] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.CENTURIONS_GREAVES },
[32807] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.CENTURIONS_SWORD, place = 2 },
[32808] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.LEGIONNAIRES_CIRCLET, place = 1 },
[32809] = { rank = 3, cp = 4000, lvl = 1, item = xi.item.BASTOKAN_RING, place = 1 },
[32816] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.JUNIOR_MUSKETEERS_TUCK },
[32817] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.IRON_MUSKETEERS_ARMET },
[32818] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.IRON_MUSKETEERS_GAUNTLETS },
[32819] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.IRON_MUSKETEERS_SABATONS },
[32820] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.IRON_MUSKETEERS_GAMBISON, place = 2 },
[32821] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.JUNIOR_MUSKETEERS_CHAKRAM, place = 1 },
[32832] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.MUSKETEERS_SWORD },
[32833] = { rank = 5, cp = 16000, lvl = 30, item = xi.item.REPUBLICAN_IRON_MEDAL },
[32834] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.IRON_MUSKETEERS_CUIRASS },
[32835] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.IRON_MUSKETEERS_CUISSES },
[32836] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.MUSKETEERS_POLE, place = 2 },
[32837] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.MUSKETEER_GUN, place = 1 },
[32848] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.REPUBLICAN_MYTHRIL_MEDAL },
[32849] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.REPUBLICAN_ARMY_MANTLE },
[32850] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.MUSKETEER_COMMANDERS_FALCHION, place = 2 },
[32851] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.MUSKETEER_COMMANDERS_SHIELD, place = 2 },
[32852] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.MUSKETEER_COMMANDERS_ROD, place = 1 },
[32853] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.IRON_MUSKETEERS_GORGET, place = 1 },
[32864] = { rank = 7, cp = 32000, lvl = 60, item = xi.item.IRON_MUSKETEERS_QUIVER },
[32865] = { rank = 7, cp = 32000, lvl = 60, item = xi.item.GOLD_MUSKETEERS_UCHIGATANA, place = 2 },
[32866] = { rank = 7, cp = 32000, lvl = 60, item = xi.item.GOLD_MUSKETEERS_RING, place = 1 },
[32880] = { rank = 8, cp = 40000, lvl = 65, item = xi.item.PRAEFECTUSS_GLOVES },
[32881] = { rank = 8, cp = 40000, lvl = 65, item = xi.item.PRESIDENTIAL_HAIRPIN, place = 2 },
[32882] = { rank = 8, cp = 40000, lvl = 65, item = xi.item.REPUBLICAN_GOLD_MEDAL, place = 1 },
[32896] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.SENIOR_GOLD_MUSKETEERS_SCYTHE },
[32897] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.SENIOR_GOLD_MUSKETEERS_ROD },
[32898] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.SENIOR_GOLD_MUSKETEERS_AXE, place = 2 },
[32899] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.SENIOR_GOLD_MUSKETEERS_SCIMITAR, place = 1 },
[32912] = { rank = 10, cp = 56000, lvl = 1, item = xi.item.REPUBLIC_AKETON, place = 1 },
[32932] = { rank = 10, cp = 5000, lvl = 1, item = xi.item.REPUBLIC_SIGNET_STAFF },
[32940] = { rank = 10, cp = 10000, lvl = 1, item = xi.item.DECORATIVE_CHAIR_SET },
},
[xi.nation.WINDURST] =
{
[32768] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.FREESWORDS_BOW },
[32769] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.FREESWORDS_CLUB },
[32770] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.FREESWORDS_BAGHNAKHS },
[32771] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.FREESWORDS_SLOPS, place = 2 },
[32772] = { rank = 1, cp = 1000, lvl = 10, item = xi.item.FREESWORDS_STAFF, place = 1 },
[32784] = { rank = 2, cp = 2000, lvl = 18, item = xi.item.MERCENARYS_POLE },
[32785] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.MERCENARYS_HACHIMAKI },
[32786] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.MERCENARYS_GI },
[32787] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.MERCENARYS_TEKKO },
[32788] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.MERCENARYS_SITABAKI },
[32789] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.MERCENARYS_KYAHAN },
[32790] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.MERCENARYS_KNIFE, place = 2 },
[32791] = { rank = 2, cp = 2000, lvl = 20, item = xi.item.MERCENARYS_GREATSWORD, place = 1 },
[32800] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.MERCENARY_CAPTAINS_SCYTHE },
[32801] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.MERCENARY_CAPTAINS_HEADGEAR },
[32802] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.MERCENARY_CAPTAINS_DOUBLET },
[32803] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.MERCENARY_CAPTAINS_GLOVES },
[32804] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.MERCENARY_CAPTAINS_HOSE },
[32805] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.MERCENARY_CAPTAINS_GAITERS },
[32806] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.MERCENARY_CAPTAINS_KUKRI, place = 2 },
[32807] = { rank = 3, cp = 4000, lvl = 30, item = xi.item.MERCENARY_CAPTAINS_BELT, place = 1 },
[32808] = { rank = 3, cp = 4000, lvl = 1, item = xi.item.WINDURSTIAN_RING, place = 1 },
[32816] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.COMBAT_CASTERS_DAGGER },
[32817] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.COMBAT_CASTERS_BOOMERANG },
[32818] = { rank = 4, cp = 8000, lvl = 10, item = xi.item.GREEN_SCARF },
[32819] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.COMBAT_CASTERS_CLOAK },
[32820] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.COMBAT_CASTERS_MITTS },
[32821] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.COMBAT_CASTERS_SLACKS },
[32822] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.COMBAT_CASTERS_SHOES },
[32823] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.COMBAT_CASTERS_SCIMITAR, place = 2 },
[32824] = { rank = 4, cp = 8000, lvl = 40, item = xi.item.COMBAT_CASTERS_AXE, place = 1 },
[32832] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TACTICIAN_MAGICIANS_WAND, place = 2 },
[32833] = { rank = 5, cp = 16000, lvl = 30, item = xi.item.PAISLEY_SCARF },
[32834] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TACTICIAN_MAGICIANS_HAT, place = 2 },
[32835] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TACTICIAN_MAGICIANS_COAT },
[32836] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TACTICIAN_MAGICIANS_CUFFS },
[32837] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TACTICIAN_MAGICIANS_SLOPS },
[32838] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TACTICIAN_MAGICIANS_PIGACHES },
[32839] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TACTICIAN_MAGICIANS_ESPADON },
[32840] = { rank = 5, cp = 16000, lvl = 50, item = xi.item.TACTICIAN_MAGICIANS_HOOKS, place = 1 },
[32848] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.CHECKERED_SCARF },
[32849] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.FEDERAL_ARMY_MANTLE },
[32850] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.WISE_WIZARDS_STAFF, place = 2 },
[32851] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.WISE_WIZARDS_BILBO, place = 2 },
[32852] = { rank = 6, cp = 24000, lvl = 55, item = xi.item.WISE_WIZARDS_ANELACE, place = 1 },
[32864] = { rank = 7, cp = 32000, lvl = 60, item = xi.item.COMBAT_CASTERS_QUIVER },
[32865] = { rank = 7, cp = 32000, lvl = 60, item = xi.item.PATRIARCH_PROTECTORS_SHIELD, place = 2 },
[32866] = { rank = 7, cp = 32000, lvl = 60, item = xi.item.PATRIARCH_PROTECTORS_RING, place = 1 },
[32880] = { rank = 8, cp = 40000, lvl = 65, item = xi.item.MASTER_CASTERS_MITTS },
[32881] = { rank = 8, cp = 40000, lvl = 65, item = xi.item.MASTER_CASTERS_BRACELETS, place = 2 },
[32882] = { rank = 8, cp = 40000, lvl = 65, item = xi.item.WINDURSTIAN_SCARF, place = 1 },
[32896] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.MASTER_CASTERS_BOW },
[32897] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.MASTER_CASTERS_POLE },
[32898] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.MASTER_CASTERS_BAGHNAKHS, place = 2 },
[32899] = { rank = 9, cp = 48000, lvl = 71, item = xi.item.MASTER_CASTERS_KNIFE, place = 1 },
[32912] = { rank = 10, cp = 56000, lvl = 1, item = xi.item.FEDERATION_AKETON, place = 1 },
[32932] = { rank = 10, cp = 5000, lvl = 1, item = xi.item.FEDERATION_SIGNET_STAFF },
[32940] = { rank = 10, cp = 10000, lvl = 1, item = xi.item.ORNATE_STOOL_SET },
},
}
local titlesGranted =
{
[0] = -- San d'Oria
{
[1] = xi.title.ROYAL_ARCHER,
[2] = xi.title.ROYAL_SPEARMAN,
[3] = xi.title.ROYAL_SQUIRE,
[4] = xi.title.ROYAL_SWORDSMAN,
[5] = xi.title.ROYAL_CAVALIER,
[6] = xi.title.ROYAL_GUARD,
[7] = xi.title.GRAND_KNIGHT_OF_THE_REALM,
[8] = xi.title.GRAND_TEMPLE_KNIGHT,
[9] = xi.title.RESERVE_KNIGHT_CAPTAIN,
[10] = xi.title.ELITE_ROYAL_GUARD,
},
[1] = -- Bastok
{
[1] = xi.title.LEGIONNAIRE,
[2] = xi.title.DECURION,
[3] = xi.title.CENTURION,
[4] = xi.title.JUNIOR_MUSKETEER,
[5] = xi.title.SENIOR_MUSKETEER,
[6] = xi.title.MUSKETEER_COMMANDER,
[7] = xi.title.GOLD_MUSKETEER,
[8] = xi.title.PRAEFECTUS,
[9] = xi.title.SENIOR_GOLD_MUSKETEER,
[10] = xi.title.PRAEFECTUS_CASTRORUM,
},
[2] = -- Windurst
{
[1] = xi.title.FREESWORD,
[2] = xi.title.MERCENARY,
[3] = xi.title.MERCENARY_CAPTAIN,
[4] = xi.title.COMBAT_CASTER,
[5] = xi.title.TACTICIAN_MAGICIAN,
[6] = xi.title.WISE_WIZARD,
[7] = xi.title.PATRIARCH_PROTECTOR,
[8] = xi.title.CASTER_CAPTAIN,
[9] = xi.title.MASTER_CASTER,
[10] = xi.title.MERCENARY_MAJOR,
},
}
local function getStock(player, guardNation, option)
local r = overseerInvCommon[option]
if r == nil then
if guardNation == xi.nation.OTHER then
r = overseerInvNation[player:getNation()][option]
else
r = overseerInvNation[guardNation][option]
end
end
return r
end
local function canBuyExpRing(player, item)
local text = zones[player:getZoneID()].text
-- check exp ring count
if xi.settings.main.ALLOW_MULTIPLE_EXP_RINGS ~= 1 then
for i = 15761, 15763 do
if player:hasItem(i) then
player:messageSpecial(text.CONQUEST + 60, 0, 0, item) -- You do not meet the requirements to purchase the <item>.
player:messageSpecial(text.CONQUEST + 50, 0, 0, item) -- Due to its special nature, you can only purchase or recharge <item> once until the conquest results tally is performed. Also, you cannot purchase this item if a similar item is already in your possession.
return false
end
end
end
-- one exp ring per conquest tally
if
xi.settings.main.BYPASS_EXP_RING_ONE_PER_WEEK ~= 1 and
player:getCharVar('CONQUEST_RING_RECHARGE') ~= 0
then
player:messageSpecial(text.CONQUEST + 60, 0, 0, item)
player:messageSpecial(text.CONQUEST + 50, 0, 0, item)
return false
end
return true
end
-----------------------------------
-- (PUBLIC) conquest
-----------------------------------
xi.conquest.guard =
{
CITY = 1,
FOREIGN = 2,
OUTPOST = 3,
BORDER = 4,
}
xi.conquest.areAllies = function(nationA, nationB)
return IsConquestAlliance() and
GetNationRank(nationA) > 1 and
GetNationRank(nationB) > 1
end
xi.conquest.outpostFee = function(player, region)
if not hasOutpost(player, region) then
return 0
end
local fee = outposts[region].fee
if GetRegionOwner(region) == player:getNation() then
return fee
else
return fee * 3
end
end
xi.conquest.canTeleportToOutpost = function(player, region)
local outpost = outposts[region]
if
outpost == nil or
player:getMainLvl() < outpost.lvl or
not hasOutpost(player, region)
then
return false
end
return true
end
xi.conquest.setRegionalConquestOverseers = function(region)
local zone = outposts[region].zone
if zone then
local base = zones[zone].npc.OVERSEER_BASE
local npcs = overseerOffsets[region]
if base and npcs then
-- update the npcs
local owner = GetRegionOwner(region)
for _, v in pairs(npcs) do
local npc = GetNPCByID(base + v.offset)
if npc then
if v.nation == owner then
npc:setStatus(xi.status.NORMAL)
else
npc:setStatus(xi.status.DISAPPEAR)
end
if v.nation == xi.nation.OTHER then
if owner ~= xi.nation.BEASTMEN then
npc:setStatus(xi.status.NORMAL)
else
npc:setStatus(xi.status.DISAPPEAR)
end
end
end
end
end
end
end
-----------------------------------
-- (PUBLIC) overseer
-----------------------------------
xi.conquest.overseerOnTrade = function(player, npc, trade, guardNation, guardType)
if xi.garrison.onTrade(player, npc, trade, guardNation) then
return
end
if player:getNation() == guardNation or guardNation == xi.nation.OTHER then
local item = trade:getItemId()
local tradeConfirmed = false
local mOffset = zones[player:getZoneID()].text.CONQUEST
-- DONATE CRYSTALS FOR RANK OR CONQUEST POINTS
if guardType <= xi.conquest.guard.FOREIGN and crystals[item] then
local pRank = player:getRank(player:getNation())
local pRankPoints = player:getRankPoints()
local addPoints = 0
for crystalId, crystalWorth in pairs(crystals) do
local count = trade:getItemQty(crystalId)
if count > 0 then
if pRank == 1 then
player:showText(npc, mOffset - 7) -- 'I cannot accept crystals from someone whose rank is still 1.'
break
elseif pRankPoints == 4000 then
player:showText(npc, mOffset + 43) -- 'You do not need to donate any more crystals at your current rank.'
break
else
trade:confirmItem(crystalId, count)
addPoints = addPoints + count * math.floor(4000 / (player:getRank(player:getNation()) * 12 - crystalWorth))
end
end
end
if addPoints > 0 and pRank ~= 1 and pRankPoints < 4000 then
if pRankPoints + addPoints >= 4000 then
player:setRankPoints(4000)
player:addCP(pRankPoints + addPoints - 4000)
player:showText(npc, mOffset + 44) -- 'Your rank points are full. We've added the excess to your conquest points.'
else
player:addRankPoints(addPoints)
player:showText(npc, mOffset + 45) -- 'We've awarded you rank points for the crystals you've donated.'
end
player:confirmTrade()
tradeConfirmed = true
end
end
-- RECHARGE EXP RING
if not tradeConfirmed and expRings[item] and npcUtil.tradeHas(trade, item) then
if
xi.settings.main.BYPASS_EXP_RING_ONE_PER_WEEK == 1 or
player:getCharVar('CONQUEST_RING_RECHARGE') == 0
then
local ring = expRings[item]
-- find the item so can determine the actual charges used
-- (if still some charges left then recharging is proportionally less CP)
local ringItem = player:findItem(item)
if ringItem then
-- by default assume all charges used and calculate CP cost for a full recharge
local cpCost = ring.chargesWhenFull * ring.costPerCharge
-- calculate the charges used (clamp to ensure no strangeness)
local chargesLeft = utils.clamp(ringItem:getCurrentCharges(), 0, ring.chargesWhenFull)
local chargesUsed = ring.chargesWhenFull - chargesLeft
-- player trying to recharge a full ring so notify player and exit
if chargesUsed == 0 then
player:showText(npc, mOffset + 57, item) -- 'The <item> is already fully charged.'
return
-- player has used some but not all charges so calculate the CP cost for recharge
elseif
chargesUsed > 0 and
chargesUsed < ring.chargesWhenFull
then
cpCost = chargesUsed * ring.costPerCharge
end
-- if enough CP then perform the recharge
if player:getCP() >= cpCost then
player:delCP(cpCost)
player:confirmTrade()
player:addItem(item)
player:setCharVar('CONQUEST_RING_RECHARGE', 1, NextConquestTally())
player:showText(npc, mOffset + 58, item, cpCost, chargesUsed) -- 'Your ring is now fully recharged.'
else
player:showText(npc, mOffset + 55, item, cpCost) -- 'You do not have the required conquest points to recharge.'
end
-- could not find the player's current ring so stop attempt
else
return
end
else
player:showText(npc, mOffset + 56, item) -- 'Please be aware that you can only purchase or recharge <item> once during the period between each conquest results tally.
end
end
end
end
xi.conquest.overseerOnTrigger = function(player, npc, guardNation, guardType, guardEvent, guardRegion)
local pNation = player:getNation()
if xi.garrison.onTrigger(player, npc) then
return
end
-- SUPPLY RUNS
if
pNation == guardNation and
areSuppliesRotten(player, npc, guardType)
then
-- do nothing else
elseif
pNation == guardNation and
guardType >= xi.conquest.guard.OUTPOST and
canDeliverSupplies(player, guardNation, guardEvent, guardRegion)
then
-- do nothing else
-- JEUNO OVERSEERS
elseif guardType == xi.conquest.guard.CITY and guardNation == xi.nation.OTHER then
local a1 = getArg1(player, guardNation, guardType)
local a3 = conquestRanking()
local a6 = getArg6(player)
local a7 = player:getCP()
player:startEvent(guardEvent, a1, 0, a3, 0, 0, a6, a7, 0)
-- CITY AND FOREIGN OVERSEERS
elseif guardType <= xi.conquest.guard.FOREIGN then
local a1 = getArg1(player, guardNation, guardType)
local a2 = getExForceAvailable(player, guardNation)
local a3 = conquestRanking()
local a4 = suppliesAvailableBitmask(player, guardNation)
local a5 = player:getTeleport(guardNation)
local a6 = getArg6(player)
local a7 = player:getCP()
local a8 = getExForceReward(player, guardNation)
player:startEvent(guardEvent, a1, a2, a3, a4, a5, a6, a7, a8)
-- OUTPOST AND BORDER OVERSEERS
elseif guardType >= xi.conquest.guard.OUTPOST then
local a1 = getArg1(player, guardNation, guardType)
if a1 == 1808 then -- non-allied nation
player:startEvent(guardEvent, a1, 0, 0, 0, 0, player:getRank(player:getNation()), 0, 0)
else
player:startEvent(guardEvent, a1, 0, 0x3F0000, 0, 0, getArg6(player), 0, 0)
end
end
end
xi.conquest.overseerOnEventUpdate = function(player, csid, option, guardNation)
local pNation = player:getNation()
if guardNation == xi.nation.OTHER then
guardNation = pNation
end
local stock = getStock(player, guardNation, option)
if stock ~= nil then
local pRank = GetNationRank(pNation)
local u1 = 2 -- default: player is correct job and level to equip item
local u2 = 0 -- default: player has enough CP for item
local u3 = stock.item -- default: the item ID we're purchasing
if not player:canEquipItem(stock.item, false) then -- can't equip
u1 = 0 -- can't equip due to job
elseif stock.lvl > player:getMainLvl() then
u1 = 1 -- can't equip due to level
end
if stock.cp > player:getCP() then
u2 = 1
end
if
option >= 32933 and
option <= 32935 and
player:hasKeyItem(xi.ki.CONQUEST_PROMOTION_VOUCHER)
then
u2 = 0
end
local rankCheck = true
if
guardNation ~= xi.nation.OTHER and
guardNation ~= pNation and
GetNationRank(guardNation) <= pRank
then -- buy from other nation, must be higher ranked
rankCheck = false
elseif
guardNation ~= xi.nation.OTHER and
stock.place ~= nil and
guardNation ~= pNation
then -- buy from other nation, cannot buy items with nation rank requirement
rankCheck = false
elseif stock.place ~= nil and pRank > stock.place then -- buy from own nation, check nation rank
rankCheck = false
end
if rankCheck and u2 == 0 then
player:setLocalVar('boughtItemCP', stock.item) -- set localVar for later cheat prevention
end
player:updateEvent(u1, u2, u3)
end
end
-- Additional checks to ensure that the player can actually purchase the item requested from the overseer.
-- Returns price of the item if valid, -1 if invalid.
local function canPurchaseItem(player, stock, pRank, guardNation, mOffset, option)
-- Validate stock
if stock == nil then
return -1
end
-- validate localVar (cheat protection)
local boughtItem = player:getLocalVar('boughtItemCP')
player:setLocalVar('boughtItemCP', 0)
if stock.item ~= boughtItem then
player:messageSpecial(mOffset + 61, stock.item) -- 'Your rank is too low to purchase the <item>.'
return -1
end
-- validate rank
if stock.rank and pRank < stock.rank then
player:messageSpecial(mOffset + 61, stock.item) -- 'Your rank is too low to purchase the <item>.'
return -1
end
-- validate price
local price = stock.cp
if
stock.rank ~= nil and
player:getNation() ~= guardNation and
guardNation ~= xi.nation.OTHER
then
if price <= 8000 then
price = price * 2
else
price = price + 8000
end
end
if player:getCP() < price then
if
option <= 32933 and
option >= 32935 and
not player:hasKeyItem(xi.ki.CONQUEST_PROMOTION_VOUCHER)
then
player:messageSpecial(mOffset + 62, 0, 0, stock.item) -- 'You do not have enough conquest points to purchase the <item>.'
return -1
end
end
return price
end
xi.conquest.overseerOnEventFinish = function(player, csid, option, guardNation, guardType, guardRegion)
local pNation = player:getNation()
local pRank = player:getRank(pNation)
local sRegion = player:getCharVar('supplyQuest_region')
local sOutpost = outposts[sRegion]
local mOffset = zones[player:getZoneID()].text.CONQUEST
if xi.garrison.onEventFinish(player, csid, option, guardNation, guardType, guardRegion) then
return
end
-- SIGNET
if option == 1 then
local duration = (pRank + GetNationRank(pNation) + 3) * 3600
player:delStatusEffectsByFlag(xi.effectFlag.INFLUENCE, true)
player:addStatusEffect(xi.effect.SIGNET, { duration = duration, origin = player })
player:messageSpecial(mOffset + 1) -- 'You've received your nation's Signet!'
if player:getEminenceProgress(3367) then
xi.roe.onRecordTrigger(player, 3367) -- Complete Weekly Signet, brb objective. This might be able to move to a status effect trigger
end
-- BEGIN SUPPLY RUN
elseif
option >= 65541 and
option <= 65565 and
guardType <= xi.conquest.guard.FOREIGN
then
local region = option - 65541
local outpost = outposts[region]
if outpost ~= nil then
npcUtil.giveKeyItem(player, outpost.ki)
player:setCharVar('supplyQuest_started', VanadielUniqueDay())
player:setCharVar('supplyQuest_region', region)
player:setCharVar('supplyQuest_fresh', NextConquestTally())
end
-- FINISH SUPPLY RUN
elseif
option == 2 and
guardType >= xi.conquest.guard.OUTPOST and
sRegion == guardRegion and
sOutpost ~= nil and
player:hasKeyItem(sOutpost.ki) and
guardNation == pNation
then
player:delKeyItem(sOutpost.ki)
player:addCP(sOutpost.cp)
player:messageSpecial(mOffset) -- 'You've earned conquest points!'
player:setCharVar('supplyQuest_started', 0)
player:setCharVar('supplyQuest_region', 0)
player:setCharVar('supplyQuest_fresh', 0)
if not player:hasTeleport(guardNation, sRegion + 5) then
player:addTeleport(guardNation, sRegion + 5)
end
-- SET HOMEPOINT
elseif option == 4 then
if player:delGil(setHomepointFee(player, guardNation)) then
player:setHomePoint()
player:messageSpecial(mOffset + 94) -- 'Your home point has been set.'
else
player:messageSpecial(mOffset + 95) -- 'You do not have enough gil to set your home point here.'
end
-- PURCHASE CP ITEM
elseif option >= 32768 and option <= 32944 then
local stock = getStock(player, guardNation, option)
local price = canPurchaseItem(player, stock, pRank, guardNation, mOffset, option) -- Validation included.
if price < 0 then
return
end
-- validate exp rings
if
option >= 32933 and
option <= 32935 and
not canBuyExpRing(player, stock.item)
then
return
end
-- make sale
if npcUtil.giveItem(player, stock.item) then
if option >= 32933 and option <= 32935 then
player:setCharVar('CONQUEST_RING_RECHARGE', 1, NextConquestTally())
if player:hasKeyItem(xi.ki.CONQUEST_PROMOTION_VOUCHER) then
player:delKeyItem(xi.ki.CONQUEST_PROMOTION_VOUCHER)
return
end
end
player:delCP(price)
if stock.rank ~= nil then
player:setTitle(titlesGranted[pNation][stock.rank])
end
end
end
end
-----------------------------------
-- (PUBLIC) vendor
-----------------------------------
xi.conquest.vendorOnTrigger = function(player, vendorRegion, vendorEvent)
local pNation = player:getNation()
local owner = GetRegionOwner(vendorRegion)
local nation = 0
local fee = xi.conquest.outpostFee(player, vendorRegion)
if owner == pNation then
nation = 1
elseif xi.conquest.areAllies(pNation, owner) then
nation = 2
end
player:startEvent(vendorEvent, nation, fee, 0, fee, player:getCP(), 0, 0, 0)
end
xi.conquest.vendorOnEventUpdate = function(player, vendorRegion)
local fee = xi.conquest.outpostFee(player, vendorRegion)
player:updateEvent(player:getGil(), fee, 0, fee, player:getCP())
end
xi.conquest.vendorOnEventFinish = function(player, option, vendorRegion)
local fee = xi.conquest.outpostFee(player, vendorRegion)
if option == 1 then
xi.shop.outpost(player)
elseif option == 2 then
if player:delGil(fee) then
player:addStatusEffect(xi.effect.TELEPORT, { power = xi.teleport.id.HOME_NATION, duration = 1, origin = player, icon = 0, subPower = vendorRegion })
end
elseif option == 6 then
player:delCP(fee)
player:addStatusEffect(xi.effect.TELEPORT, { power = xi.teleport.id.HOME_NATION, duration = 1, origin = player, icon = 0, subPower = vendorRegion })
end
end
-----------------------------------
-- (PUBLIC) outpost teleport NPC
-----------------------------------
xi.conquest.teleporterOnTrigger = function(player, teleporterNation, teleporterEvent)
local sandyRegions = getRegionsMask(xi.nation.SANDORIA)
local bastokRegions = getRegionsMask(xi.nation.BASTOK)
local windyRegions = getRegionsMask(xi.nation.WINDURST)
local beastmenRegions = getRegionsMask(xi.nation.BEASTMEN)
local allowedTeleports = getAllowedTeleports(player, teleporterNation)
local nationBits = player:getNation() + bit.lshift(teleporterNation, 8)
player:startEvent(teleporterEvent, sandyRegions, bastokRegions, windyRegions, beastmenRegions, 0, nationBits, player:getMainLvl(), allowedTeleports)
end
xi.conquest.teleporterOnEventUpdate = function(player, csid, option, teleporterEvent)
if csid == teleporterEvent then
local region = option - 1073741829
local fee = xi.conquest.outpostFee(player, region)
local cpFee = fee / 10
player:updateEvent(player:getGil(), fee, 0, cpFee, player:getCP())
end
end
xi.conquest.teleporterOnEventFinish = function(player, csid, option, teleporterEvent)
if csid == teleporterEvent then
-- TELEPORT WITH GIL
if option >= 5 and option <= 23 then
local region = option - 5
local fee = xi.conquest.outpostFee(player, region)
if
xi.conquest.canTeleportToOutpost(player, region) and
player:delGil(fee)
then
player:addStatusEffect(xi.effect.TELEPORT, { power = xi.teleport.id.OUTPOST, duration = 1, origin = player, icon = 0, subPower = region })
end
-- TELEPORT WITH CP
elseif option >= 1029 and option <= 1047 then
local region = option - 1029
local cpFee = xi.conquest.outpostFee(player, region) / 10
if
xi.conquest.canTeleportToOutpost(player, region) and
player:getCP() >= cpFee
then
player:delCP(cpFee)
player:addStatusEffect(xi.effect.TELEPORT, { power = xi.teleport.id.OUTPOST, duration = 1, origin = player, icon = 0, subPower = region })
end
end
end
end
-----------------------------------
-- (PUBLIC) conquest messages
-----------------------------------
xi.conquest.sendConquestTallyStartMessage = function(player, messageBase)
player:messageText(player, messageBase, 5)
end
-- City areas, though not technically conquest areas, should show the tally end message.
xi.conquest.sendCityConquestTallyEndMessage = function(player, messageBase, ranking, isConquestAlliance)
-- Tallying conquest results...
player:messageText(player, messageBase + 1, 5)
-- Global balance of power message
xi.conquest.sendBalanceOfPowerMessage(player, messageBase, ranking, isConquestAlliance)
end
-- Used for non city conquest areas. shows tally end message + owner of the region.
xi.conquest.sendConquestTallyEndMessage = function(player, messageBase, owner, ranking, isConquestAlliance)
-- Tallying conquest results...
player:messageText(player, messageBase + 1, 5)
if owner <= 3 then
player:messageText(player, messageBase + 2 + owner, 5) -- This region is currently under <nation> control.
else
player:messageText(player, messageBase + 6, 5) -- This region is currently under beastman control.
end
-- Global balance of power message
xi.conquest.sendBalanceOfPowerMessage(player, messageBase, ranking, isConquestAlliance)
end
-- Helper method for sendConquestTallyUpdateMessage and sendConquestTallyEndMessage
xi.conquest.sendBalanceOfPowerMessage = function(player, messageBase, ranking, isConquestAlliance)
local offset = 0
if bit.band(ranking, 0x03) == 0x01 then
offset = offset + 7 -- 7
if bit.band(ranking, 0x30) == 0x10 then
offset = offset + 1 -- 8
if bit.band(ranking, 0x0C) == 0x0C then
offset = offset + 1 -- 9
end
elseif bit.band(ranking, 0x0C) == 0x08 then
offset = offset + 3 -- 10
if bit.band(ranking, 0x30) == 0x30 then
offset = offset + 1 -- 11
end
elseif bit.band(ranking, 0x0C) == 0x04 then
offset = offset + 6 -- 13
end
elseif bit.band(ranking, 0x0C) == 0x04 then
offset = offset + 15 -- 15
if bit.band(ranking, 0x30) == 0x02 then
offset = offset + 3 -- 18
if bit.band(ranking, 0x03) == 0x03 then
offset = offset + 1 -- 19
end
elseif bit.band(ranking, 0x30) == 0x10 then
offset = offset + 6 -- 21
end
elseif bit.band(ranking, 0x30) == 0x10 then
offset = offset + 23 -- 23
if bit.band(ranking, 0x0C) == 0x08 then
offset = offset + 3 -- 26
if bit.band(ranking, 0x30) == 0x30 then
offset = offset + 1 -- 27
end
end
end
player:messageText(player, messageBase + offset, 5) -- Global balance of power:
if isConquestAlliance then
if bit.band(ranking, 0x03) == 0x01 then
player:messageText(player, messageBase + 50, 5) -- Bastok and Windurst have formed an alliance.
elseif bit.band(ranking, 0x0C) == 0x04 then
player:messageText(player, messageBase + 51, 5) -- San d'Oria and Windurst have formed an alliance.
elseif bit.band(ranking, 0x30) == 0x10 then
player:messageText(player, messageBase + 52, 5) -- San d'Oria and Bastok have formed an alliance.
end
end
end
xi.conquest.sendConquestTallyUpdateMessage = function(player, messageBase, owner, ranking, influence, isConquestAlliance)
-- don't send regional influence for city zones -- nobody can gain influence here.
if owner == 255 then
return
end
if owner <= 3 then
player:messageText(player, messageBase + 32 + owner, 5) -- This region is currently under <nation> control.
else
player:messageText(player, messageBase + 31, 5) -- This region is currently under beastman control.
end
if influence >= 64 then
player:messageText(player, messageBase + 37, 5) -- The beastmen are on the rise.
elseif influence == 0 then
player:messageText(player, messageBase + 36, 5) -- All three nations are at a deadlock.
else
local sandoria = bit.band(influence, 0x03)
local bastok = bit.rshift(bit.band(influence, 0x0C), 2)
local windurst = bit.rshift(bit.band(influence, 0x30), 4)
player:messageText(player, messageBase + 41 - sandoria, 5) -- Regional influence: San d'Oria
player:messageText(player, messageBase + 45 - bastok, 5) -- Regional influence: Bastok
player:messageText(player, messageBase + 49 - windurst, 5) -- Regional influence: Windurst
end
if isConquestAlliance then
if bit.band(ranking, 0x03) == 0x01 then
player:messageText(player, messageBase + 53, 5) -- Bastok and Windurst are currently allies.
elseif bit.band(ranking, 0x0C) == 0x04 then
player:messageText(player, messageBase + 54, 5) -- San d'Oria and Windurst are currently allies.
elseif bit.band(ranking, 0x30) == 0x10 then
player:messageText(player, messageBase + 55, 5) -- San d'Oria and Bastok are currently allies.
end
end
end
xi.conquest.onConquestUpdate = function(zone, updatetype, influence, owner, ranking, isConquestAlliance)
-- onConquestUpdate is called for zones in city regions as well
-- in such cases, owner and influence is undetermined, so we call a city specific method.
local regionId = zone:getRegionID()
if regionId > xi.region.TAVNAZIANARCH and regionId < xi.region.DYNAMIS then
xi.conquest.onCityConquestUpdate(zone, updatetype, ranking, isConquestAlliance)
return
end
local messageBase = zones[zone:getID()].text.CONQUEST_BASE
local players = zone:getPlayers()
-----------------------------------
-- WARNING: This is iterating every player in a zone, be careful not
-- : to put expensive operations like db reads in here!
-----------------------------------
for _, player in pairs(players) do
if updatetype == conquestConstants.TALLY_START then
xi.conquest.sendConquestTallyStartMessage(player, messageBase)
elseif updatetype == conquestConstants.TALLY_END then
xi.conquest.sendConquestTallyEndMessage(player, messageBase, owner, ranking, isConquestAlliance)
elseif updatetype == conquestConstants.UPDATE then
xi.conquest.sendConquestTallyUpdateMessage(player, messageBase, owner, ranking, influence, isConquestAlliance)
end
end
end
xi.conquest.onCityConquestUpdate = function(zone, updatetype, ranking, isconquestAlliance)
local messageBase = zones[zone:getID()].text.CONQUEST_BASE
local players = zone:getPlayers()
-----------------------------------
-- Once per zone logic
-----------------------------------
-- Triggers regional npc updates for city zones only
if updatetype == conquestConstants.TALLY_END then
xi.conquest.toggleRegionalNPCs(zone)
end
-----------------------------------
-- WARNING: This is iterating every player in a zone, be careful not
-- : to put expensive operations like db reads in here!
-----------------------------------
for _, player in pairs(players) do
if updatetype == conquestConstants.TALLY_START then
xi.conquest.sendConquestTallyStartMessage(player, messageBase)
elseif updatetype == conquestConstants.TALLY_END then
xi.conquest.sendCityConquestTallyEndMessage(player, messageBase, ranking, isconquestAlliance)
end
end
end