1
Fork 0
mirror of https://bitbucket.org/Ioncannon/project-meteor-server.git synced 2025-04-24 21:57:45 +00:00

Updated Map Server namespace. Moved all other data folders (www and sql) to data folder. Renamed boot name to Project Meteor.

This commit is contained in:
Filip Maj 2019-06-19 01:10:15 -04:00
parent 18ef69f3d1
commit 91549bff7a
1823 changed files with 102704 additions and 901 deletions

11
Data/lobby_config.ini Normal file
View file

@ -0,0 +1,11 @@
[General]
server_ip=0.0.0.0
showtimestamp = true
[Database]
worldid=1
host=127.0.0.1
port=3306
database=ffxiv_server
username=root
password=

11
Data/map_config.ini Normal file
View file

@ -0,0 +1,11 @@
[General]
server_ip=127.0.0.1
showtimestamp = true
[Database]
worldid=1
host=127.0.0.1
port=3306
database=ffxiv_server
username=root
password=

58
Data/scripts/ability.lua Normal file
View file

@ -0,0 +1,58 @@
-- todo: add enums for status effects in global.lua
require("global")
require("battleutils")
--[[
statId - see BattleTemp.cs
modifier - Modifier.Intelligence, Modifier.Mind (see Modifier.cs)
multiplier -
]]
function HandleHealingSkill(caster, target, skill, action, statId, modifierId, multiplier, baseAmount)
potency = potency or 1.0;
healAmount = baseAmount;
-- todo: shit based on mnd
local mind = caster.GetMod(Modifier.Mind);
end;
function HandleAttackSkill(caster, target, skill, action, statId, modifierId, multiplier, baseAmount)
-- todo: actually handle this
damage = baseAmount or math.random(1,10) * 10;
return damage;
end;
function HandleStoneskin(caster, target, skill, action, statId, modifierId, damage)
--[[
if target.statusEffects.HasStatusEffect(StatusEffect.Stoneskin) then
-- todo: damage reduction
return true;
end;
]]
return false;
end;
--For abilities that inflict statuses, like aegis boon or taunt
function onStatusAbilityFinish(caster, target, skill, action)
--action.CalcHitType(caster, target, skill);
action.DoAction(caster, target, skill);
action.TryStatus(caster, target, skill, false);
return action.amount;
end;
function onAttackAbilityFinish(caster, target, skill, action)
local damage = math.random(50, 150);
action.amount = damage;
action.DoAction(caster, target, skill);
return action.amount;
end;
function onHealAbilityFinish(caster, target, skill, action)
local amount = math.random(150, 250);
action.amount = amount;
action.DoAction(caster, target, skill);
action.TryStatus(caster, target, skill, true);
return action.amount;
end;

205
Data/scripts/aetheryte.lua Normal file
View file

@ -0,0 +1,205 @@
--[[
Aetheryte related info
--]]
aetheryteParentLinks = {
--La Noscea
[1280001] = nil,
[1280002] = {1280007, 1280008, 1280009, 0, 0},
[1280003] = {1280010, 0, 0, 0, 0},
[1280004] = {1280011, 1280018, 0, 0, 0},
[1280005] = {1280020, 1280012, 1280013, 1280014, 0},
[1280006] = {1280015, 1280016, 1280017, 0, 0},
--Thanalan
[1280031] = nil,
[1280032] = {1280037, 1280038, 1280052, 0, 0},
[1280033] = {1280039, 1280040, 1280041, 0, 0},
[1280034] = {1280042, 1280043, 1280044, 1280054, 0},
[1280035] = {1280045, 1280046, 1280047, 0, 0},
[1280036] = {1280048, 1280049, 1280050, 0, 0},
--Black Shroud
[1280061] = nil,
[1280062] = {1280067, 1280068, 1280069, 1280083, 0},
[1280063] = {1280070, 1280071, 1280072, 0, 0},
[1280064] = {1280073, 1280074, 1280075, 1280082, 0},
[1280065] = {1280076, 1280077, 1280078, 0, 0},
[1280066] = {1280079, 1280080, 1280081, 0, 0},
--Coerthas
[1280092] = {1280097, 1280098, 1280099, 0, 0},
[1280093] = {1280100, 1280101, 1280102, 0, 0},
[1280094] = {1280103, 1280104, 0, 0, 0},
[1280095] = {1280105, 1280106, 1280107, 0, 0},
[1280096] = {1280108, 1280109, 1280110, 0, 0},
--Mor Dhona
[1280121] = {1280124, 1280125, 0, 0, 0},
[1280122] = {1280123, 0, 0, 0, 0}
}
aetheryteChildLinks = {
--La Noscea
[1280007] = 1280002,
[1280008] = 1280002,
[1280009] = 1280002,
[1280010] = 1280003,
[1280011] = 1280004,
[1280012] = 1280005,
[1280013] = 1280005,
[1280014] = 1280005,
[1280015] = 1280006,
[1280016] = 1280006,
[1280017] = 1280006,
[1280018] = 1280004,
[1280020] = 1280005,
--Thanalan
[1280037] = 1280032,
[1280038] = 1280032,
[1280039] = 1280033,
[1280040] = 1280033,
[1280041] = 1280033,
[1280042] = 1280034,
[1280043] = 1280034,
[1280044] = 1280034,
[1280045] = 1280035,
[1280046] = 1280035,
[1280047] = 1280035,
[1280048] = 1280036,
[1280049] = 1280036,
[1280050] = 1280036,
[1280052] = 1280032,
[1280054] = 1280034,
--Black Shroud
[1280067] = 1280062,
[1280068] = 1280062,
[1280069] = 1280062,
[1280070] = 1280063,
[1280071] = 1280063,
[1280072] = 1280063,
[1280073] = 1280064,
[1280074] = 1280064,
[1280075] = 1280064,
[1280076] = 1280065,
[1280077] = 1280065,
[1280078] = 1280065,
[1280079] = 1280066,
[1280080] = 1280066,
[1280081] = 1280066,
[1280082] = 1280064,
[1280083] = 1280062,
--Coerthas
[1280097] = 1280092,
[1280098] = 1280092,
[1280099] = 1280092,
[1280100] = 1280093,
[1280101] = 1280093,
[1280102] = 1280093,
[1280103] = 1280094,
[1280104] = 1280094,
[1280105] = 1280095,
[1280106] = 1280095,
[1280107] = 1280095,
[1280108] = 1280096,
[1280109] = 1280096,
[1280110] = 1280096,
--Mor Dhona
[1280123] = 1280122,
[1280124] = 1280121,
[1280125] = 1280121
}
aetheryteTeleportPositions = {
--La Noscea
[1280001] = {230, -407, 42.5, 337}, -- CAP
[1280002] = {128, 29.97, 45.83, -35.47}, -- CAP
[1280003] = {129, -991.88, 61.71, -1120.79}, -- CAP
[1280004] = {129, -1883.47, 53.77, -1372.68}, -- CAP
[1280005] = {130, 1123.29, 45.7, -928.69}, -- CAP
[1280006] = {135, -278.181, 77.63, -2260.79}, -- CAP
[1280007] = {128, 582.47, 54.52, -1.2},
[1280008] = {128, 962.836, 46.507, 832.206}, -- Widow Cliffs http://ic.pics.livejournal.com/eijih/14054410/1355/1355_original.jpg
[1280009] = {128, 318, 24.5, 581}, -- Moraby Bay http://ic.pics.livejournal.com/eijih/14054410/1092/1092_original.jpg
[1280010] = {129, -636, 48.8, -1287}, -- Woad Whisper Canyon
[1280011] = {129, -2016.72, 60.055, -766.962}, -- Isles of Umbra http://ic.pics.livejournal.com/eijih/14054410/2243/2243_original.jpg
[1280012] = {130, 1628, 60.3, -449}, -- Tiger Helm Island http://ic.pics.livejournal.com/eijih/14054410/2032/2032_original.jpg
[1280013] = {130, 1522, 1.7, -669},-- Bloodshore http://ic.pics.livejournal.com/eijih/14054410/1607/1607_original.jpg
[1280014] = {130, 1410, 53.3, -1650}, -- Agelyss Wise
[1280015] = {135, -123.315, 60.061, -1438.8}, -- Zelma's Run https://youtu.be/97Ju0Xv-aaQ?t=102
[1280016] = {135, -320.322, 52.835, -1823.68}, -- Bronze Lake http://ic.pics.livejournal.com/eijih/14054410/2503/2503_original.jpg
[1280017] = {135, -894, 41.2, -2188}, -- Oakwood
[1280018] = {131, -1694.5, -19.9, -1534.}, -- Mistbeard Cove
[1280020] = {132, 1343.5, -54.38, -870.84}, -- CAP
--Thanalan
[1280031] = {175, -235, 185, -3.9}, -- CAP
[1280032] = {170, 33, 200.1, -482}, -- Camp Black Brush
[1280033] = {171, 1250.9, 264, -544.2}, -- CAP
[1280034] = {172, -1313.91, 56.023, -145.597}, -- Camp Horizon https://www.youtube.com/watch?v=mQAK4QVnx3c
[1280035] = {173, -165.816, 280.002, -1698.45}, -- Camp Bluefog
[1280036] = {174, 1687.64, 296.002, 992.283}, -- Camp Brokenwater https://www.youtube.com/watch?v=YyBYHg9h2AM
[1280037] = {170, 639, 183.9, 122}, -- Cactus Basin
[1280038] = {170, 539, 215.8, -14}, -- Four Sisters
[1280039] = {171, 1599, 256.7, -233}, -- Halatali
[1280040] = {171, 2010, 280.3, -768}, -- Burning Wall
[1280041] = {171, 2015, 247.8, 64}, -- Sandgate
[1280042] = {172, -864.991, 88.84, 375.18}, -- Nophica's Wells https://www.youtube.com/watch?v=pk4POCDQ9QE
[1280043] = {172, -1653, 24.5, -469}, -- Footfalls
[1280044] = {172, -1220.38, 69.854, 194.365}, -- Scorpion Keep
[1280045] = {173, -635, 280, -1797}, -- Hidden Gorge
[1280046] = {173, 447, 259.1, -2158}, -- Sea of Spires
[1280047] = {173, -710, 280.4, -2212}, -- Cutters Pass
[1280048] = {174, 1797, 248, 1856}, -- Red Labyrinth
[1280049] = {174, 1185, 279.8, 1407}, -- Burnt Lizard Creek
[1280050] = {174, 2416, 248.3, 1535}, -- Zanr'ak
[1280052] = {176, 80.056, 167.929, -1267.94}, -- Nanawa Mines https://www.youtube.com/watch?v=9H-NveJx9EI
[1280054] = {178, -620.374, 110.429, -113.903}, -- Copperbell Mines
-- Black Shroud
[1280061] = {206, -120, 16, -1332}, -- CAP
[1280062] = {150, 288, 4, -543.928}, -- CAP
[1280063] = {151, 1702, 20, -862}, -- CAP
[1280064] = {152, -1052, 20, -1760}, -- CAP
[1280065] = {153, -1566.035, -11.89, -550.51}, -- CAP
[1280066] = {154, 734, -12, 1126}, -- CAP
[1280067] = {150, -94.07, 4, -543.16}, -- Humblehearth
[1280068] = {150, -285, -21.8, -46}, -- Sorrel Haven
[1280069] = {150, 636, 16.2, -324}, -- Five Hangs
[1280070] = {151, 1529.83, 26.991, -1140.15}, -- Verdant Drop
[1280071] = {151, 1296, 47.2, -1534}, -- Lynxpelt Patch
[1280072] = {151, 2297.02, 31.546, -697.828}, -- Larkscall http://www.gwcdn.com/albums/images/4f7ce3a389118b43470005b1.jpg
[1280073] = {152, -883.769, 34.688, -2187.45}, -- Treespeak
[1280074] = {152, -1567, 16.1, -2593}, -- Aldersprings
[1280075] = {152, -800.277, 32, -2785.4}, -- Lasthold
[1280076] = {153, -1908, 0.3, -1042}, -- Lichenweed
[1280077] = {153, -2158, -46.1, -166}, -- Murmur Rills
[1280078] = {153, -1333, -14.2, 324}, -- Turning Leaf
[1280079] = {154, 991, -11.8, 600}, -- Silent Arbor
[1280080] = {154, 1126, -0.1, 1440}, -- Longroot
[1280081] = {154, 189, 0.1, 1337}, -- Snakemolt
[1280082] = {157, -687.916, -15.308, -2063.94}, -- Mun-Tuy Cellars https://www.youtube.com/watch?v=ty6f9Gy0uws
[1280083] = {158, 314.801, -36.2, -167.843}, -- Tam-Tara Deepcroft https://www.youtube.com/watch?v=eLJPTUG-dE0
-- Coerthas
[1280092] = {143, 216, 302.1, -258}, -- Camp Dragonhead
[1280093] = {144, 1122.21, 270.004, -1149.29}, -- Camp Crooked Fork https://www.youtube.com/watch?v=Q7-0r6ELCAU
[1280094] = {145, 1500.78, 206.036, 767.546}, -- Camp Glory
[1280095] = {147, -159.828, 222.037, 1154.81}, -- Camp Ever Lakes https://youtu.be/3wKNidix0Ls?t=274
[1280096] = {148, -1760.36, 270.059, -194.713}, -- Camp Riversmeet https://www.youtube.com/watch?v=gt7Tc9gbTpk
[1280097] = {143, -517, 207.9, 543}, -- Boulder Downs
[1280098] = {143, 190, 367.4, -662}, -- Prominence Point
[1280099] = {143, 960, 287.4, -22}, -- Feathergorge
[1280100] = {144, 1737, 176.5, -1250}, -- Maiden Glen
[1280101] = {144, 1390, 222.6, -736}, -- Hushed Boughs
[1280102] = {144, 1788, 164.8, -829}, -- Scarwing Fall
[1280103] = {145, 1383, 231.8, 422}, -- Weeping Vale
[1280104] = {145, 2160, 142.7, 622}, -- Clearwater
[1280105] = {147, -1, 144.1, 1373}, -- Teriggans Stand
[1280106] = {147, -64, 185.1, 1924}, -- Shepherd Peak
[1280107] = {147, -908, 191.7, 2162}, -- Fellwood
[1280108] = {148, -1734.82, 285.069, -839.63}, -- Wyrmkings Perch
[1280109] = {148, -2366.07, 336.041, -1054.75}, -- The Lance
[1280110] = {148, -2821, 256.1, -290}, -- Twinpools
-- Mor Dhona
[1280121] = {190, 487.445, 18.531, 672.244}, -- Camp Brittlebark https://youtu.be/mkbYeaUqcr4 - I can barely make the ground out
[1280122] = {190, -215.76, 18.54, -668.703}, -- Camp Revenant's Toll
[1280123] = {190, -458, -40.9, -318}, -- Fogfens
[1280124] = {190, 580, 58.2, 206}, -- Singing Shards
[1280125] = {190, -365.724, -18.591, -25.448} -- Jagged Crest Cave
}

117
Data/scripts/ally.lua Normal file
View file

@ -0,0 +1,117 @@
require ("global")
require ("magic")
require ("weaponskill")
allyGlobal =
{
}
function allyGlobal.onSpawn(ally, target)
end
function allyGlobal.onEngage(ally, target)
end
function allyGlobal.onAttack(ally, target, damage)
end
function allyGlobal.onDamageTaken(ally, attacker, damage)
end
function allyGlobal.onCombatTick(ally, target, tick, contentGroupCharas)
allyGlobal.HelpPlayers(ally, contentGroupCharas)
end
function allyGlobal.onDeath(ally, player, lastAttacker)
end
function allyGlobal.onDespawn(ally)
end
function allyGlobal.HelpPlayers(ally, contentGroupCharas, pickRandomTarget)
print("helpPlayers");
if contentGroupCharas and not ally.IsEngaged() then
print("contentGroup exists");
for chara in contentGroupCharas do
print("looping");
if chara then
-- probably a player, or another ally
-- todo: queue support actions, heal, try pull hate off player etc
if chara.IsPlayer() then
print("chara is a player");
-- do stuff
if not ally.IsEngaged() then
if chara.IsEngaged() then
allyGlobal.EngageTarget(ally, chara.target, nil);
break;
end
end
elseif chara.IsMonster() and chara.IsEngaged() then
if not ally.IsEngaged() then
print("Engaging monster that is engaged");
allyGlobal.EngageTarget(ally, chara, nil);
break;
end
end
end
end
end
end
function allyGlobal.tryAggro(ally, contentGroupCharas)
local count = 0;
if contentGroupCharas and not ally.IsEngaged() then
for i = 0, #contentGroupCharas - 1 do
if contentGroupCharas[i] and ally then
if contentGroupCharas[i].IsPlayer() then
-- probably a player, or another ally
-- todo: queue support actions, heal, try pull hate off player etc
if contentGroupCharas[i].target then
if ally.aiContainer:GetTargetFind():CanTarget(contentGroupCharas[i].target) and contentGroupCharas[i].target.IsMonster() and contentGroupCharas[i].target.hateContainer:HasHateForTarget(contentGroupCharas[i]) then
-- do stuff
allyGlobal.EngageTarget(ally, contentGroupCharas[i].target, nil);
break;
end
end
elseif contentGroupCharas[i].IsMonster() and contentGroupCharas[i].IsEngaged() then
if not ally.IsEngaged() then
print("Engaging monster that is engaged");
allyGlobal.EngageTarget(ally, contentGroupCharas[i], nil);
break;
end
end
end
end
end
end
function allyGlobal.HealPlayer(ally, player)
end
function allyGlobal.SupportAction(ally, player)
end
function allyGlobal.EngageTarget(ally, target, contentGroupCharas)
if contentGroupCharas then
for chara in contentGroupCharas do
if chara.IsMonster() then
if chara.allegiance ~= ally.allegiance then
ally.Engage(chara)
break;
end
end
end
elseif target then
print("Engaging");
ally.Engage(target)
ally.hateContainer.AddBaseHate(target);
end
end

View file

@ -0,0 +1,3 @@
function init(npc)
return false, false, 0, 0, 0, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return false, false, 0, 0, 0, 0;
end

View file

@ -0,0 +1,3 @@
function init(npc)
return false, false, 0, 0, 303, 10405;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return true, true, 10, 0, 1, true, false, false, false, false, false, false, false, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return true, true, 10, 0, 1, true, false, false, false, false, false, false, false, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return true, true, 10, 0, 1, true, false, false, false, false, false, false, false, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return true, true, 10, 0, 1, true, false, false, false, false, true, true, false, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return true, true, 10, 3, 1, true, false, false, false, false, true, true, false, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return true, true, 10, 3, 1, false, false, false, false, false, true, true, false, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return true, true, 10, 0, 1, false, false, false, false, false, false, false, false, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return true, true, 10, 0, 1, true, false, false, false, false, false, false, false, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return true, true, 10, 0, 1, true, false, false, false, false, false, false, false, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return true, true, 10, 0, 1, true, false, false, false, false, false, false, false, 0;
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return false, false, 0, 0;
end

View file

@ -0,0 +1,10 @@
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
callClientFunction(player, "bookTalk");
player:EndEvent();
end

View file

@ -0,0 +1,5 @@
require ("global")
function init(npc)
return false, false, 0, 0;
end

View file

@ -0,0 +1,43 @@
--[[
GuildleveWarpPoint Script
Functions:
eventGuildleveReward(glId, completionTimeSec, completeReward, difficultyBonus, faction, gil???, factionBonus, RewardId1, RewardAmount1, RewardId2, RewardAmount2, difficulty) - Open Reward Dialog
eventTalkGuildleveWarp(returnAetheryteID1, returnAetheryte2) - Opens choice menu
--]]
require ("global")
require ("aetheryte")
require ("utils")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
local currentGLDirector = player:GetGuildleveDirector();
local glData = currentGLDirector.guildleveData;
callClientFunction(player, "eventGuildleveReward", currentGLDirector.guildleveId, currentGLDirector.completionTime, 24, 24, 0, 0, 0, 0, 0, 0, 0, currentGLDirector.selectedDifficulty);
local choice = callClientFunction(player, "eventTalkGuildleveWarp", glData.aetheryte, 0);
if (choice == 3) then
local destination = aetheryteTeleportPositions[glData.aetheryte];
if (destination ~= nil) then
randoPos = getRandomPointInBand(destination[2], destination[4], 3, 5);
rotation = getAngleFacing(randoPos.x, randoPos.y, destination[2], destination[4]);
GetWorldManager():DoZoneChange(player, destination[1], nil, 0, 2, randoPos.x, destination[3], randoPos.y, rotation);
currentGLDirector:EndDirector();
end
elseif (choice == 4) then
currentGLDirector:EndDirector();
end
player:EndEvent();
end
--50023: GL COMPLETE!
--50132: You earn faction credits from X

View file

@ -0,0 +1,23 @@
--[[
MarketEntrance Script
Functions:
eventPushChoiceAreaOrQuest(gcLeaderPlaceName[Fronds, etc], showMarketWards/Houses (must be 0xc1a), gcHQPlaceName, anotherPlaceName, showItemSearchCounter, stopSearchingItemId) -
eventPushStepPrvMarket(?, ?, ?) -
--]]
require ("global")
local MARKETWARD_ENTRANCE = {-201.0, 0.0, -160.0, 1.5};
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
callClientFunction(player, "eventPushChoiceAreaOrQuest", 0xc13, 0xc1a, 0xdba, 0, true, 1);
player:EndEvent();
end

View file

@ -0,0 +1,10 @@
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
callClientFunction(player, "materiabookTalk");
player:EndEvent();
end

View file

@ -0,0 +1,19 @@
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
harvestJudge = GetStaticActor("HarvestJudge");
--callClientFunction(player, "delegateEvent", player, harvestJudge, "loadTextData", dummy);
--callClientFunction(player, "delegateEvent", player, harvestJudge, "targetCancel", dummy);
--callClientFunction(player, "delegateEvent", player, harvestJudge, "turnToTarget", dummy, 0);
--callClientFunction(player, "delegateEvent", player, harvestJudge, "openInputWidget", 22002, 1);
--callClientFunction(player, "delegateEvent", player, harvestJudge, "textInputWidget", harvestJudge, 22002, npc, false);
--callClientFunction(player, "delegateEvent", player, harvestJudge, "askInputWidget", harvestJudge, 22002, 1);
player:EndEvent();
end

View file

@ -0,0 +1,21 @@
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
choice = callClientFunction(player, "askLogout", player);
if (choice == 2) then
player:QuitGame();
elseif (choice == 3) then
player:Logout();
elseif (choice == 4) then
player:SendMessage(33, "", "Heck the bed");
end
player:EndEvent();
end

View file

@ -0,0 +1,25 @@
--[[
ObjectEventDoor Script
Functions:
eventDoorMoveAsk() - Shows confirm to move into event
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
choice = callClientFunction(player, "eventDoorMoveAsk");
if (choice == 1) then
end
player:EndEvent();
end

View file

@ -0,0 +1,16 @@
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
defaultFst = GetStaticActor("DftFst");
choice = callClientFunction(player, "delegateEvent", player, defaultFst, "defaultTalkWithInn_ExitDoor", nil, nil, nil);
if (choice == 1) then
GetWorldManager():DoZoneChange(player, 1);
end
player:EndEvent();
end

View file

@ -0,0 +1,54 @@
--[[
ObjectItemStorage Script
Functions:
storageMenu() - Shows store/retrieve/help menu.
selectCategory() - Shows the category menu
selectStoreItem(nil, categoryId) - Shows store item menu
selectReceiveItem(nil, categoryId) - Shows retrieve item menu
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
::TOP_MENU::
storageChoice = callClientFunction(player, "storageMenu");
if (storageChoice == 1) then
categoryChoice = callClientFunction(player, "selectCategory");
if (categoryChoice == 5) then
goto TOP_MENU;
end
itemId = callClientFunction(player, "selectStoreItem", nil, categoryChoice);
if (itemId ~= nil) then
player:GetItemPackage(INVENTORY_NORMAL):RemoveItem(itemId, 1);
end
elseif (storageChoice == 2) then
categoryChoice = callClientFunction(player, "selectCategory");
if (categoryChoice == 5) then
goto TOP_MENU;
end
itemId = callClientFunction(player, "selectReceiveItem", nil, categoryChoice);
if (itemId ~= nil) then
player:GetItemPackage(INVENTORY_NORMAL):AddItem(itemId, 1);
end
end
player:EndEvent();
end

View file

@ -0,0 +1,6 @@
require ("global")
function init(npc)
return false, false, 0, 0;
end

View file

@ -0,0 +1,13 @@
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
if (triggerName == "caution") then
worldMaster = GetWorldMaster();
player:SendGameMessage(player, worldMaster, 34109, 0x20);
elseif (triggerName == "exit") then
GetWorldManager():DoPlayerMoveInZone(player, 5);
end
player:EndEvent();
end

View file

@ -0,0 +1,12 @@
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
if (triggerName == "caution") then
worldMaster = GetWorldMaster();
player:SendGameMessage(player, worldMaster, 34109, 0x20);
elseif (triggerName == "exit") then
end
player:EndEvent();
end

View file

@ -0,0 +1,19 @@
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
isActive = true;
if (isActive) then
choice = callClientFunction(player, "askYesNo");
else
callClientFunction(player, "eventTalkRead");
end
player:EndEvent();
end

View file

@ -0,0 +1,56 @@
--[[
RetainerFurniture Script
Functions:
eventPushStepOpenRetainerMenu() - Opens menu to choose retainer
eventRingBell() - Plays the bell ring animation
eventPushRetainerCallCaution() - Shows warning that a open bazaar will be closed if retainer chosen
eventTalkRetainerMenu(hasPossessions, showDispatchChoice) - Opens retainer menu.
eventTalkRetainerDismissal(hasPossessions) - Show dismiss confirmation.
eventTalkRetainerMannequin(0:Enable/1:Disable) - Shows dialog to enable/disable modeling.
eventTalkRetainerItemTrade(operationCode) - Operate RetainerTradeWidget. Codes: 1 - Open, 2 - Select Mode, 3 - Close.
eventTalkRetainerItemList(operationCode) - Operate Bazaar Widget. Codes: 1 - Open, 2 - Select Mode, 3 - Close.
eventReturnResult(resultCode, ?) - Redraws the RetainerTrade UI.
eventTalkSelectBazaarStreet(limitsWardChoices) - Shows the dialog to send a retainer to a street. Set to 20.
eventTalkFinish() - Finishs the talk with retainer
eventPlayerTurn(rotation) - Turns the player
--]]
require ("global")
require ("retainer")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
retainerNumber = callClientFunction(player, "eventPushStepOpenRetainerMenu");
if (retainerNumber == nil or retainerNumber == 0) then
player:EndEvent();
return;
end
callClientFunction(player, "eventRingBell");
retainer = player:SpawnMyRetainer(npc, retainerNumber);
while (true) do
choice = callClientFunction(player, "eventTalkRetainerMenu", false, true);
if (choice == 1) then
doItemTrade(player, retainer);
elseif (choice == 2) then
doBazaar(player, retainer);
elseif (choice == 7) then
callClientFunction(player, "eventTalkRetainerMannequin", 0);
elseif (choice == 8) then
callClientFunction(player, "eventTalkSelectBazaarStreet", 20);
else
break;
end
end
player:DespawnMyRetainer();
player:EndEvent();
end

View file

@ -0,0 +1,19 @@
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
questNOC = GetStaticActor("Noc000");
if (npc:GetActorClassId() == 1200193) then
callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardAskLimsa", nil, nil, nil);
elseif (npc:GetActorClassId() == 1200194) then
callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardAskUldah", nil, nil, nil);
else
callClientFunction(player, "delegateEvent", player, questNOC, "pETaskBoardAskGridania", nil, nil, nil);
end
player:EndEvent();
end

View file

@ -0,0 +1,119 @@
--[[
AetheryteChild Script
Functions:
eventAetheryteChildSelect(showTeleport, parentAetheryteID, animaAmount, animaCost(always 1)): Opens menu
eventAetheryteChildDesion(aetheryteId): "Your homepoint is now X"
eventGLSelect(?) - Open GL selector
eventGLSelectDetail(glid, ?, reward, rewardQuantity, subreward, subrewardQuantity, faction, ?, completed) - Show GL details
eventGLDifficulty() - Open difficulty selector
eventGLStart(glId, difficulty, evaluatingFaction, areaFactionStanding, factionReward, warningBoundByDuty, warningTooFar, warningYouCannotRecieve, warningChangingClass) - Confirmation dialog
eventGLBoost(currentFavor, minNeeded) - Ask player for Guardian Aspect
eventGLPlay(??) - Open Menu (GL active version)
eventGLReward (glId, clearTime, missionBonus, difficultyBonus, factionNumber, factionBonus, factionCredit, reward, rewardQuantity, subreward, subrewardQuantity, difficulty) - Open reward window
eventGLJoin () - Ask to join party leader's leve
--]]
require ("global")
require ("aetheryte")
require ("utils")
require ("guildleve")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, aetheryte, triggerName)
if (player:GetGuildleveDirector() ~= nil) then
doGuildleveMenu(player, aetheryte);
else
doNormalMenu(player, aetheryte);
end
player:EndEvent();
end
function doGuildleveMenu(player, aetheryte)
local currentGLDirector = player:GetGuildleveDirector();
local choice = callClientFunction(player, "eventGLPlay", currentGLDirector.guildleveId, true, 1, 500, 400, guardian, 8, currentGLDirector.selectedDifficulty, 2);
--Abandon
if (choice == 6) then
currentGLDirector:AbandonGuildleve();
end
end
function doNormalMenu(player, aetheryte)
local aetheryteId = aetheryte:GetActorClassId();
local parentNode = aetheryteChildLinks[aetheryteId];
local menuChoice = callClientFunction(player, "eventAetheryteChildSelect", true, parentNode, 100, 1);
--Teleport
if (menuChoice == 2) then
printf("%ud", parentNode);
destination = aetheryteTeleportPositions[parentNode];
if (destination ~= nil) then
randoPos = getRandomPointInBand(destination[2], destination[4], 3, 5);
rotation = getAngleFacing(randoPos.x, randoPos.y, destination[2], destination[4]);
GetWorldManager():DoZoneChange(player, destination[1], nil, 0, 2, randoPos.x, destination[3], randoPos.y, rotation);
end
--Init Levequest
elseif (menuChoice == -1) then
doLevequestInit(player, aetheryte);
--Set Homepoint
elseif (menuChoice == -2) then
player:SetHomePoint(aetheryteId);
callClientFunction(player, "eventAetheryteChildDesion", aetheryteId);
--View Faction Standing
elseif (menuChoice == -3) then
player:SendGameMessage(player, aetheryte, 27, 0x20);
player:SendGameMessage(player, aetheryte, 28, 0x20, 1, 15);
player:SendGameMessage(player, aetheryte, 29, 0x20, 2, 10);
player:SendGameMessage(player, aetheryte, 30, 0x20, 3, 5);
end
end
function doLevequestInit(player, aetheryte)
local worldMaster = GetWorldMaster();
::SELECT_LOOP::
unknown, glId = callClientFunction(player, "eventGLSelect", 0x0);
if (glId ~= 0) then
::SELECT_DETAIL::
guildleveData = GetGuildleveGamedata(glId);
if (guildleveData == nil) then
player:SendMessage(0x20, "", "An error has occured... aborting.");
return;
end
unknown, begin = callClientFunction(player, "eventGLSelectDetail", glId, 0xa, 0xf4241, 1000, 0, 0, 0, true, false);
if (begin) then
::SELECT_DIFFICULTY::
player:SendGameMessage(worldMaster, 50014, 0x20); --"Please select a difficulty level. This may be lowered later."
difficulty = callClientFunction(player, "eventGLDifficulty", glId);
if (difficulty == nil) then goto SELECT_DETAIL; end
confirmResult = callClientFunction(player, "eventGLStart", glId, difficulty, 1, 10, 20, 0, 0, 0, 0);
if (confirmResult == nil) then goto SELECT_DIFFICULTY; else
player:SendGameMessage(worldMaster, 50036, 0x20, glId, player);
player:PlayAnimation(getGLStartAnimationFromSheet(guildleveData.borderId, guildleveData.plateId, true));
director = player:GetZone():CreateGuildleveDirector(glId, difficulty, player);
player:AddDirector(director);
director:StartDirector(true, glId)
end
else
goto SELECT_LOOP;
end
end
end

View file

@ -0,0 +1,154 @@
--[[
AetheryteParent Script
Functions:
eventAetheryteParentSelect(showTeleportMenu, animaAmount, gate1, gate2, gate3, gate4, gate5) - Open Menu
eventAetheryteParentDesion(sheetId) - Show Homepoint Set Message
eventGLSelect(?) - Open GL selector
eventGLSelectDetail(glid, ?, reward, rewardQuantity, subreward, subrewardQuantity, faction, ?, completed) - Show GL details
eventGLDifficulty() - Open difficulty selector
eventGLStart(glId, difficulty, evaluatingFaction, areaFactionStanding, factionReward, warningBoundByDuty, warningTooFar, warningYouCannotRecieve, warningChangingClass) - Confirmation dialog
eventGLBoost(currentFavor, minNeeded) - Ask player for Guardian Aspect
eventGLPlay(glId, showLeveLink, leveLinkFaction, leveLinkFactionStanding, leveLinkReward, guardianFavorAmount, guardianFavorNeeded, currentDifficulty, jobNameForChange) - Open Menu (GL active version)
eventGLReward (glId, clearTime, missionBonus, difficultyBonus, factionNumber, factionBonus, factionCredit, reward, rewardQuantity, subreward, subrewardQuantity, difficulty) - Open reward window
eventGLJoin () - Ask to join party leader's leve
--callClientFunction(player, "eventGLBoost", 0xc8, 0xb);
--callClientFunction(player, "eventGLReward", 0x2a48, 120, 123, 125, 1, 111, 0, 0xf4241, 5, 0, 0, 3);
--]]
require ("global")
require ("aetheryte")
require ("utils")
require ("guildleve")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, aetheryte, triggerName)
if (player:GetGuildleveDirector() ~= nil) then
doGuildleveMenu(player, aetheryte);
else
doNormalMenu(player, aetheryte);
end
player:EndEvent();
end
function doGuildleveMenu(player, aetheryte)
local currentGLDirector = player:GetGuildleveDirector();
local choice = callClientFunction(player, "eventGLPlay", currentGLDirector.guildleveId, true, 1, 500, 400, guardian, 8, currentGLDirector.selectedDifficulty, 2);
--Abandon
if (choice == 6) then
currentGLDirector:AbandonGuildleve();
end
end
function doNormalMenu(player, aetheryte)
local aetheryteId = aetheryte:GetActorClassId();
local childNodes = aetheryteParentLinks[aetheryteId];
local listPosition = 1;
local activeChildNodes = {0, 0, 0, 0, 0};
if (childNodes ~= nil) then
if (player:HasAetheryteNodeUnlocked(childNodes[1])) then
activeChildNodes[listPosition] = childNodes[1];
listPosition = listPosition+1;
end
if (player:HasAetheryteNodeUnlocked(childNodes[2])) then
activeChildNodes[listPosition] = childNodes[2];
listPosition = listPosition+1;
end
if (player:HasAetheryteNodeUnlocked(childNodes[3])) then
activeChildNodes[listPosition] = childNodes[3];
listPosition = listPosition+1;
end
if (player:HasAetheryteNodeUnlocked(childNodes[4])) then
activeChildNodes[listPosition] = childNodes[4];
listPosition = listPosition+1;
end
if (player:HasAetheryteNodeUnlocked(childNodes[5])) then
activeChildNodes[listPosition] = childNodes[5];
listPosition = listPosition+1;
end
end
local showTeleportOptions = true;
if (listPosition == 1) then
showTeleportOptions = false;
end
local choice = callClientFunction(player, "eventAetheryteParentSelect", showTeleportOptions, 100, activeChildNodes[1], activeChildNodes[2], activeChildNodes[3], activeChildNodes[4], activeChildNodes[5]);
if (choice ~= nil) then
--Init Leavequest
if (choice == -1) then
doLevequestInit(player, aetheryte);
--Set Homepoint
elseif (choice == -2) then
player:SetHomePoint(aetheryteId);
callClientFunction(player, "eventAetheryteParentDesion", aetheryteId);
--View Faction Standings
elseif (choice == -3) then
player:SendGameMessage(player, aetheryte, 124, 0x20);
player:SendGameMessage(player, aetheryte, 125, 0x20, 1, 15);
player:SendGameMessage(player, aetheryte, 126, 0x20, 2, 10);
player:SendGameMessage(player, aetheryte, 127, 0x20, 3, 5);
--Teleport to Gate
elseif (choice > 0) then
destination = aetheryteTeleportPositions[activeChildNodes[choice]];
if (destination ~= nil) then
randoPos = getRandomPointInBand(destination[2], destination[4], 3, 5);
rotation = getAngleFacing(randoPos.x, randoPos.y, destination[2], destination[4]);
GetWorldManager():DoZoneChange(player, destination[1], nil, 0, 2, randoPos.x, destination[3], randoPos.y, rotation);
end
end
end
end
function doLevequestInit(player, aetheryte)
local worldMaster = GetWorldMaster();
::SELECT_LOOP::
unknown, glId = callClientFunction(player, "eventGLSelect", 0x0);
if (glId ~= 0) then
::SELECT_DETAIL::
guildleveData = GetGuildleveGamedata(glId);
if (guildleveData == nil) then
player:SendMessage(0x20, "", "An error has occured... aborting.");
return;
end
unknown, begin = callClientFunction(player, "eventGLSelectDetail", glId, 0xa, 0xf4241, 1000, 0, 0, 0, true, false);
if (begin) then
::SELECT_DIFFICULTY::
player:SendGameMessage(worldMaster, 50014, 0x20); --"Please select a difficulty level. This may be lowered later."
difficulty = callClientFunction(player, "eventGLDifficulty", glId);
if (difficulty == nil) then goto SELECT_DETAIL; end
confirmResult = callClientFunction(player, "eventGLStart", glId, difficulty, 1, guildleveData.favorCount, 20, 0, 0, 0, 0);
if (confirmResult == nil) then goto SELECT_DIFFICULTY; else
player:SendGameMessage(worldMaster, 50036, 0x20, glId, player);
player:PlayAnimation(getGLStartAnimationFromSheet(guildleveData.borderId, guildleveData.plateId, true));
director = player:GetZone():CreateGuildleveDirector(glId, difficulty, player);
player:AddDirector(director);
director:StartDirector(true, glId);
end
else
goto SELECT_LOOP;
end
end
end

View file

@ -0,0 +1,25 @@
--[[
PopulaceAchievement Script
Functions:
eventNoGC() -
eventUnlock(sheetId) -
eventReward(?, bool, ?, bool) -
defTalk() - Blurb
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
callClientFunction(player, "defTalk");
player:EndEvent();
end

View file

@ -0,0 +1,159 @@
--[[
PopulaceBlackMarketeer Script
Functions:
eventTalkWelcome(player) - Start Text
eventSellItemAsk(player, itemName, tradePrice) - Requires GC Affiliation. Trade menu for Commemorative Coin
eventAskMainMenu(player, index) - Shows menu prompt to purchase with gil or with GC seals
eventTalkBye(player) - Says bye text
eventTalkStepBreak() - Ends talk, NPC turns to face original position
eventSealShopMenuOpen() - Opens menu for purchasing with grand company seals
eventSealShopMenuAsk() - Returns two values, one that seems to always be true, and an index of purchased item
eventSealShopMenuClose() - Closes seal menu
eventGilShopMenuOpen() - Opens menu for purchasing with gil
eventGilShopMenuAsk() - Returns two values, one that seems to always be true, and an index of purchased item
eventGilShopMenuClose() - Closes gil menu
Class applies to only three NPCs
Actorclass Id - 1500293 : Momoroon, Limsa Lominsa
Actorclass Id - 1500294 : Gagaroon, Gridania
Actorclass Id - 1500295 : Lalaroon, Ul'dah
--]]
require ("global")
require ("shop")
shopInfo = { -- [ index ] = { itemId, gilPrice, sealPrice, city, itemCategory }
[1001] = {3020202, 100, 10000, 1, 1},
[1002] = {3020509, 400, 40000, 1, 1},
[1003] = {3020510, 400, 40000, 1, 1},
[1004] = {3020504, 1000, 100000, 1, 1},
[1005] = {3020505, 1000, 100000, 1, 1},
[1101] = {9040018, 1500, 150000, 1, 2},
[1102] = {9010025, 2000, 200000, 1, 2},
[1301] = {2001014, 4000, 400000, 1, 4},
[2001] = {3020203, 100, 10000, 2, 1},
[2002] = {3020509, 400, 40000, 2, 1},
[2003] = {3020510, 400, 40000, 2, 1},
[2004] = {3020504, 1000, 100000, 2, 1},
[2005] = {3020505, 1000, 100000, 2, 1},
[2101] = {9040018, 1500, 150000, 2, 2},
[2102] = {9010025, 2000, 200000, 2, 2},
[2301] = {2001015, 4000, 400000, 2, 4},
[3001] = {3020204, 100, 10000, 3, 1},
[3002] = {3020509, 400, 40000, 3, 1},
[3003] = {3020510, 400, 40000, 3, 1},
[3004] = {3020504, 1000, 100000, 3, 1},
[3005] = {3020505, 1000, 100000, 3, 1},
[3101] = {9040018, 1500, 150000, 3, 2},
[3102] = {9010025, 2000, 200000, 3, 2},
[3301] = {2001016, 4000, 400000, 3, 4},
}
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
commemorativeCoin = 10011251;
commemorativeCoinValue = 25000;
gilCurrency = 1000001;
playerGC = player.gcCurrent
playerGCSeal = 1000200 + playerGC;
callClientFunction(player, "eventTalkWelcome", player);
if player:GetItemPackage(INVENTORY_NORMAL):HasItem(commemorativeCoin) and playerGC > 0 then
-- Checks for player having a commemorative coin, show window trade option if so.
coinChoice = callClientFunction(player, "eventSellItemAsk", player, commemorativeCoin, commemorativeCoinValue);
if coinChoice == 1 then
currencyType = callClientFunction(player, "eventAskMainMenu", player);
elseif coinChoice == 2 then
-- You trade <itemQuantity1> <itemName1> <itemQuality1> for <itemQuantity2> <itemName2> <itemQuality2>.
player:SendGameMessage(player, GetWorldMaster(), 25071, MESSAGE_TYPE_SYSTEM, commemorativeCoin, 1, playerGCSeal, 1, 1, commemorativeCoinValue);
player:GetItemPackage(INVENTORY_NORMAL):RemoveItem(commemorativeCoin, 1);
player:GetItemPackage(INVENTORY_CURRENCY):addItem(playerGCSeal, 25000, 1)
-- TODO: Add handling for checking GC seals limit and not going over it
end
else
-- If no grand company alignment, go straight to the shop that uses gil, otherwise show gc seal option.
if playerGC == 0 then
processGilShop(player);
else
currencyType = callClientFunction(player, "eventAskMainMenu", player);
if currencyType == 1 then
processGilShop(player);
elseif currencyType == 2 then
processSealShop(player);
end
end
end
callClientFunction(player, "eventTalkBye", player);
callClientFunction(player, "eventTalkStepBreak", player);
player:EndEvent();
end
function processGilShop(player)
callClientFunction(player, "eventGilShopMenuOpen", player);
while (true) do
unk1, buyResult = callClientFunction(player, "eventGilShopMenuAsk", player);
printf(unk1);
if (buyResult == 0 or buyResult == -1) then
callClientFunction(player, "eventGilShopMenuClose", player);
break;
else
if shopInfo[buyResult] == nil then
-- Prevent server crash from someone trying to buy a non-existent item via packet injection.
break;
else
-- TODO: Add handling to check you're on the right NPC to prevent packet injecting a purchase from anything in the list
if shopInfo[buyResult][5] == 4 then
location = INVENTORY_KEYITEMS;
else
location = INVENTORY_NORMAL;
end
purchaseItem(player, location, shopInfo[buyResult][1], 1, 1, shopInfo[buyResult][3], gilCurrency);
end
end
end
end
function processSealShop(player)
callClientFunction(player, "eventSealShopMenuOpen", player);
while (true) do
unk1, buyResult = callClientFunction(player, "eventSealShopMenuAsk", player);
if (buyResult == 0 or buyResult == -1) then
callClientFunction(player, "eventSealShopMenuClose", player);
break;
else
if shopInfo[buyResult] == nil then
-- Prevent server crash from someone trying to buy a non-existent item via packet injection.
break;
else
-- TODO: Add handling to check you're on the right NPC to prevent packet injecting a purchase from anything in the list
if shopInfo[buyResult][5] == 4 then
location = INVENTORY_KEYITEMS;
else
location = INVENTORY_NORMAL;
end
purchaseItem(player, location, shopInfo[buyResult][1], 1, 1, shopInfo[buyResult][2], playerGCSeal);
end
end
end
end

View file

@ -0,0 +1,26 @@
--[[
PopulaceBountyPresenter Script
Functions:
eventLowerLevel(player) -
eventAlreadyPresent(player) -
eventBeforePresent(player) -
eventAfterPresent(player) -
eventJail(player, bool) -
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
callClientFunction(player, "eventLowerLevel", player);
player:EndEvent();
end

View file

@ -0,0 +1,26 @@
--[[
PopulaceBranchVendor Script
Functions:
eventTalkWelcome(player) - Starts talk turn and
eventSearchItemAsk(nil, stopSearchingItemId) -
eventTalkStepBreak() - Finishes the talk turn.
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
callClientFunction(player, "eventTalkWelcome", player);
callClientFunction(player, "eventSearchItemAsk", nil, 0);
callClientFunction(player, "eventTalkStepBreak", player);
player:EndEvent();
end

View file

@ -0,0 +1,26 @@
--[[
PopulaceCampMaster Script
Functions:
defTalk(player, favAetheryte1, favAetheryte2, favAetheryte3, playerLevel, ?) - The main and only function for this npc. If favAetheryte1 == 0, will not ask to remove others.
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
favLocation = callClientFunction(player, "defTalk", player, 0, 1280004, 1280005);
--if (hasThree) then
--Remove chosen
--end
player:EndEvent();
end

View file

@ -0,0 +1,31 @@
--[[
PopulaceCampSubMaster Script
Functions:
talkWelcome(player, level, ?) - Main npc function.
confirmUseFacility(player, gilAmount) - Confirm dialog if player uses facility.
finishTalkTurn() - Call to stop the npc staring at player.
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
choice = callClientFunction(player, "talkWelcome", player, 1, false);
if (choice == 1) then
confirmed = callClientFunction(player, "confirmUseFacility", player, 1);
end
callClientFunction(player, "finishTalkTurn");
player:EndEvent();
end

View file

@ -0,0 +1,41 @@
--[[
PopulaceCaravanAdviser Script
Functions:
adviserDeffault() - Not a typo. NPC dialog talking about a chocobo. Resets their sight on you, perhaps used on closing dialog?
adviserAsk() - Brings up a menu for caravan info, or purchasing gysahl greens
adviserAdvise() - NPC dialog discussing feeding chocobos
adviserSales(price) - Gysahl purchase dialog and prompt
adviserBuy() - Dialog to play after purchasing gysahl greens
adviserBuyNG() - NPC plays /shrug animation.
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
local gysahlPrice = 20;
local choice = callClientFunction(player, "adviserAsk");
if choice == 1 then
callClientFunction(player, "adviserAdvise");
elseif choice == 2 then
local purchaseChoice = callClientFunction(player, "adviserSales", gysahlPrice);
if purchaseChoice == 1 then
callClientFunction(player, "adviserBuy");
elseif purchaseChoice == 2 then
callClientFunction(player, "adviserBuyNG");
end
elseif choice == 3 then
callClientFunction(player, "adviserDeffault")
end
player:EndEvent();
end

View file

@ -0,0 +1,68 @@
--[[
PopulaceCaravanGuide Script
This script handles the caravan guide class, which is for the actor who escorts the chocobos behind them during Caravan Security events.
Functions:
caravanGuardCancel() - Menu prompt to abandon the caravan
caravanGuardReward(cargo, nil, areaName, playerGC, killCount, areaName2)
- Reward dialog for completing the caravan
- cargo = 0 (none) through 9 (all) for varying degrees of success dialog
- If playerGC doesn't match the GC of the areaName region, NPC mentions you don't need their seals.
- killCount shows an extra dialog if 40-49 enemies were slain, and a different one at 50+
caravanGuardNotReward() - Dialog stating you didn't contribute to the event at all
caravanGuardFailReward(areaName, areaName2) - Failure dialog, NPC offers free gysahl green, then offers free teleport back to aetheryte
caravanGuardThanks(name1, name2, name3) - Dialog for joining the caravan. NPC names the three chocobos. Name IDs from xtx_displayName
caravanGuardOffer(areaName, areaName2, playerGC) - Dialog for who to talk to for joining the caravan.
caravanGuardAmple(areaName, areaName2) - Dialog for NPC taking a break?
caravanGuardSuccess() - Dialog when you reached destination?
caravanGuardFailure(areaName, areaName2) - Failure dialog for mentioned area.
caravanGuardIgnore() - Resets NPC state for player? Or used for players not flagged for the event.
caravanGuardBonusReward(nil, isBonus?) - NPC says variation on a piece of dialog from the boolean passed
caravanGuardNotBonusReward() - Inventory full flavour dialog
Notes:
Functions employing areaName/areaName2 add their value together in the client's script to get the area name. Said area values are...
1 = Wineport, 2 = Quarrymill, 3 = Silver Bazaar, 4 = Aleport, 5 = Hyrstmill, 6 = Golden Bazaar
areaName will always be 1-3 for caravanGuardReward to function as expected for GC-related dialog
areaName2 will always be either 0 or 3. 0 for the lower level caravan area name, 3 for the higher level.
populaceCaravanGuide sheet:
ID Dialog Comment
6 It is time. Come, let us ride. - Caravan begins.
12 We've arrived at last! Come and speak to me when you're ready to claim your reward. - Caravan completed.
23 We're under attack! The chocobos! Protect the chocobos! - Caravan aggros monsters
27 Gods, have we already come this far? At this pace, we stand to make good time. - Says between 50% & 90% of the way to desgination? Can be said more than once per run
28 Well fought, friend. I thank the gods you're with us. Come, onward! - Cleared monsters that caravan aggro'd
TO-DO:
Document actors involved. Should be six of them.
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
local areaName = 1;
local areaName2 = 3;
local playerGC = 1;
local cargo = 9;
local killCount = 50;
callClientFunction(player, "caravanGuardOffer", areaName, areaName2, playerGC);
--callClientFunction(player, "caravanGuardReward", cargo, nil, areaName, playerGC, killCount, areaName2);
--player:SendGameMessageDisplayIDSender(npc, 6, MESSAGE_TYPE_SAY, npc.displayNameId);
player:EndEvent();
end

View file

@ -0,0 +1,49 @@
--[[
PopulaceCaravanManager Script
Functions:
caravanGuardEntry(areaGC, hasRoomForGCSeals, areaName, difficulty, playerGC, playerCountRequired, levelRequired)
- Dialog for signing up for caravan. areaGC(1-3) & areaName(0 or 3) added together to get location name.
- If difficulty => 40 on areaGC 1-3 & areaName 0, NPC mentions it's be a tougher trip
caravanGuardQuestion(areaName1, areaName2, escortMax, isSameGC?, playerGC?) - Ask about the caravan escort
caravanGuardJoinOK(areaName1, areaName2, playerGC) - Dialog for successfully joining the caravan
caravanGuardJoinNG(nil, maxEscorts, playerGC) - Dialog dictating how many escorts total filled the run.
caravanGuardAmple(nil, playerGC, playerGC) - Dialog for caravan escort being full.
caravanGuardOther(npcGC) - Dialog where NPC mentions you're not part of the given Grand Company parameter
caravanGuardSigh() - NPC does a shrug animation
caravanGuardHuh() - NPC does /huh
caravanGuardCancel(nil, playerGC) - Dialog for canceling caravan escort.
Notes:
Some NPC dialog address you differently if your GC rank is Chief Sergeant (id 27) or higher, but only in non-English languages.
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
local GC = 3;
local playerGC = 1;
local areaName = 0;
local level = 25;
local playerCount = 8;
local difficulty = 41;
local hasRoomForGCSeals = false;
local isSameGC = true;
local escortMax = 8;
areaName1 = 1;
areaName2 = 3;
-- callClientFunction(player, "caravanGuardCancel", nil, 3);
callClientFunction(player, "caravanGuardEntry", GC, hasRoomForGCSeals, areaName, difficulty, playerGC, playerCount, level);
player:EndEvent();
end

View file

@ -0,0 +1,114 @@
--[[
PopulaceChocoboLender Script
Functions:
eventTalkWelcome(player) - Start Text
eventAskMainMenu(player, curLevel, hasFundsForRent, isPresentChocoboIssuance, isSummonMyChocobo, isChangeBarding, currentChocoboWare) - Shows the main menu
eventTalkMyChocobo(player) - Starts the cutscene for getting a chocobo
eventSetChocoboName(true) - Opens the set name dialog
eventAfterChocoboName(player) - Called if player done naming chocobo, shows cutscene, returns state and waits to teleport outside city.
eventCancelChocoboName(player) - Called if player cancels naming chocobo, returns state.
eventTalkStepBreak(player) - Finishes talkTurn and says a goodbye
--]]
require ("global")
local gcIssuances = {
[1500006] = 2001004,
[1500061] = 2001005,
[1000840] = 2001006
};
local startAppearances = {
[1500006] = CHOCOBO_LIMSA1,
[1500061] = CHOCOBO_GRIDANIA1,
[1000840] = CHOCOBO_ULDAH1
};
local cityExits = {
[1500006] = 15,
[1500061] = 14,
[1000840] = 16
};
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
--callClientFunction(player, "eventTalkWelcome", player);
--callClientFunction(player, "eventAskMainMenu", player, 20, true, true, true, true, 4);
--callClientFunction(player, "eventTalkMyChocobo", player);
--callClientFunction(player, "eventSetChocoboName", false);
--callClientFunction(player, "eventAfterChocoboName", player);
local curLevel = 20; -- TODO: pull from character
local hasIssuance = player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(gcIssuances[npc:GetActorClassId()]);
local hasChocobo = player.hasChocobo;
if (player.isGM and hasChocobo == false) then -- Let GMs auto have the issuance for debugging
hasIssuance = true;
end
local rentPrice = 800;
local hasFunds = (player:GetCurrentGil() >= rentPrice);
callClientFunction(player, "eventTalkWelcome", player);
local menuChoice = callClientFunction(player, "eventAskMainMenu", player, curLevel, hasFunds, hasIssuance, true, true, player.chocoboAppearance);
if (menuChoice == 1) then -- Issuance option
callClientFunction(player, "eventTalkMyChocobo", player);
local nameResponse = callClientFunction(player, "eventSetChocoboName", true);
if (nameResponse == "") then -- Cancel Chocobo naming
callClientFunction(player, "eventCancelChocoboName", player);
callClientFunction(player, "eventTalkStepBreak", player);
player:EndEvent();
return;
else
local appearance = startAppearances[npc:GetActorClassId()];
player:IssueChocobo(appearance, nameResponse);
callClientFunction(player, "eventAfterChocoboName", player);
mountChocobo(player);
GetWorldManager():DoZoneChange(player, cityExits[npc:GetActorClassId()]);
player:SendGameMessage(player, GetWorldMaster(), 25248, 0x20, 2001007);
player:SendDataPacket("attention", GetWorldMaster(), "", 25248, 2001007);
if (player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(2001007) == false) then
player:GetItemPackage(INVENTORY_KEYITEMS):AddItem(2001007);
end
player:GetItemPackage(INVENTORY_KEYITEMS):RemoveItem(gcIssuances[npc:GetActorClassId()], 1);
player:EndEvent();
return;
end
elseif(menuChoice == 2) then -- Summon Bird
mountChocobo(player);
GetWorldManager():DoZoneChange(player, cityExits[npc:GetActorClassId()]);
elseif(menuChoice == 3) then -- Change Barding
callClientFunction(player, "eventTalkStepBreak", player);
elseif(menuChoice == 5) then -- Rent Bird
issueRentalChocobo(player);
else
callClientFunction(player, "eventTalkStepBreak", player);
end
player:EndEvent();
end
function mountChocobo(player)
player:SendChocoboAppearance();
player:SetMountState(1);
player:ChangeSpeed(0.0, 5.0, 10.0);
player:ChangeState(15);
end
function issueRentalChocobo(player)
--TODO: Write issue rental chocobo code
end

View file

@ -0,0 +1,43 @@
--[[
PopulaceCompanyBuffer Script
Functions:
eventTalkWelcome(player, boolean) - Welcome dialog. Boolean seems to be related to rank?
eventTalkBufEffect() - Dialog for applying Sanction
eventTalkBufEffectAfter(player) - Dialog after applying Sanction
eventTalkStepBreak() - Returns to NPC's neutral state
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
local gcRep = {
[1500388] = 1, -- Maelstrom Representative
[1500389] = 2, -- Adder Representative
[1500390] = 3, -- Flame Representative
}
function onEventStarted(player, npc, triggerName)
local playerGC = player.gcCurrent;
local playerGCRanks = {player.gcRankLimsa, player.gcRankGridania, player.gcRankUldah};
local choice = callClientFunction(player, "eventTalkWelcome", player, true);
if (choice == 1 and playerGCRanks[playerGC] > 10 and playerGCRanks[playerGC] < 112) then
callClientFunction(player, "eventTalkBufEffect");
callClientFunction(player, "eventTalkBufEffectAfter", player);
-- TODO: Add Sanction buff
else
player:SendMessage(0x20, "", "Quit hex editing your memory.");
end
callClientFunction(player, "eventTalkStepBreak");
player:endEvent();
end

View file

@ -0,0 +1,66 @@
--[[
PopulaceCompanyGLPublisher Script
xtx_gcRank for GC Rank values
Functions:
talkOutsider() - Dialog for no affiliated with GC. Seems to always read Maelstrom?
talkOfferWelcome(unk1) - Errors
askCompanyLeve() - Errors
askLeveDetail(unk1, unk2, unk3, unk4, unk5, unk6, unk7, unk8) - Errors
eventGLDifficulty() - Difficulty window, returns player choice
eventGLStart(leveName, difficulty, unk1) - leveName from xtx_guildleve
talkAfterOffer()
talkOfferLimit()
finishTalkTurn() - Resets NPC target/facing
eventGLPlay(leveName, guardianFavor, favorCost, difficulty) - Menu for active levequest
eventGLShinpu(guardianFavor, favorCost) - Menu to accept favor buff. evenGLPlay() calls it
eventGLThanks() - Errors
eventGLReward( -- Leve reward screen
guildleveId,
clearTime,
missionBonus,
difficultyBonus,
factionNumber,
factionBonus,
factionCredit,
glRewardItem,
glRewardNumber,
glRewardSubItem,
glRewardSubNumber,
difficulty
)
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
gcOfficer = {
[1500222] = 1, -- Storm Sergeant Hammil
[1500223] = 1, -- Storm Sergeant Sternn
[1500224] = 2, -- Serpent Sergeant Cordwyk
[1500225] = 2, -- Serpent Sergeant Lodall
[1500226] = 3, -- Flame Sergeant Byrne
[1500227] = 3, -- Flame Sergeant Dalvag
}
function onEventStarted(player, npc, triggerName)
callClientFunction(player, "talkOutsider");
callClientFunction(player, "finishTalkTurn");
player:endEvent();
end

View file

@ -0,0 +1,45 @@
--[[
PopulaceCompanyGuide Script
Functions:
eventTalkWelcome() - Dialog for new recruits
eventTalkProvisional() - Message for when rank isn't high enough?
eventTalkExclusive() - Message for wrong GC.
eventTalkComMember(nil, npc, isFoundationDay) - Information menus for various GC related activities
eventTalkStepBreak() - Returns to NPC's neutral state
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
local gcRep = {
[1001737] = 1, -- Maelstrom Representative
[1001738] = 2, -- Adder Representative
[1001739] = 3, -- Flame Representative
}
function onEventStarted(player, npc, triggerName)
local playerGC = player.gcCurrent;
local playerGCRanks = {player.gcRankLimsa, player.gcRankGridania, player.gcRankUldah};
local npcGC = gcRep[npc:GetActorClassId()];
if (playerGC ~= npcGC and playerGCRanks[playerGC] == 127) then
callClientFunction(player, "eventTalkWelcome");
elseif (playerGC == npcGC and playerGCRanks[playerGC] == 127) then
callClientFunction(player, "eventTalkProvisional");
elseif (playerGC ~= npcGC and playerGCRanks[playerGC] ~= 127) then
callClientFunction(player, "eventTalkExclusive");
elseif (playerGC == npcGC and playerGCRanks[playerGC] > 10 and playerGCRanks[playerGC] < 112) then
callClientFunction(player, "eventTalkComMember", nil, npc, true);
end
callClientFunction(player, "eventTalkStepBreak");
player:endEvent();
end

View file

@ -0,0 +1,77 @@
--[[
PopulaceCompanyOfficer Script
xtx_gcRank for GC Rank values
Functions:
eventTalkWelcome() - Welcome dialog
eventTalkWelcomeQuest() - Same as Welcome dialog?
eventTalkPreJoin() - Dialog for starting GC rank?
eventTalkExclusive() - Dialog to play when you're not of that GC?
eventTalkJoinedOnly() - Reads like chat-end dialog for your GC.
eventTalkJoined(gcRank, gcRank, isCanAfford, isShowPromotion) - Menu to ask about/for promotion
eventDoRankUp(gcRank, gcRank) - Plays rank-up animation and opens GC window.
eventRankUpDone(???, ???) - Has your character do the GC salute? Values seem to do nothing?
eventRankCategoryUpBefore(gcRank) - 11/21/31 - Mentions which GC quest you need to clear to continue promotion
eventRankCategoryUpAfter() - Follow-up dialog after ranking up
eventTalkQuestUncomplete() - Quest prerequisite dialog for ranking up to Second Lieutenant (1.23b rank cap)
eventTalkFestival() - Foundation Day 2011 event dialog. Server needs to reward 1000 GC seals after.
eventTalkFestival2() - Foundation Day 2011 event dialog. Seems to reward more seals, unsure how many.
eventTalkFestival2012(value) - Foundation Day 2012 event dialog. Rewards amount of seals dictated by value, retail used 5000.
eventTalkStepBreak() - Resets NPC target/facing
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
gcOfficer = {
[1500199] = 1, -- Limsa Officer
[1500200] = 2, -- Grid Officer
[1500198] = 3, -- Flame Officer
}
function onEventStarted(player, npc, triggerName)
playerGC = player.gcCurrent;
playerGCSeal = 1000200 + playerGC;
playerCurrentRank = 13;
playerRankUpCost = 1500;
playerNextRank = 15;
currentRankCap = 31; -- Second Lieutenant
npcId = npc:GetActorClassId();
if playerGC == gcOfficer[npcId] then
callClientFunction(player, "eventTalkWelcome");
if playerCurrentRank < currentRankCap then
if player:GetItemPackage(INVENTORY_CURRENCY):HasItem(playerGCSeal, playerRankUpCost) then
-- Show Promotion window, allow paying
local choice = callClientFunction(player, "eventTalkJoined", playerCurrentRank, playerNextRank, true, true);
-- If promotion accepted
if choice == 1 then
callClientFunction(player, "eventDoRankUp", playerNextRank, playerNextRank);
-- TODO: Table GC info or get it in source/sql. Handle actual upgrade of GC rank/seal cap/cost/etc.
end
else
-- Show Promotion window, show dialog you can't afford promotion
callClientFunction(player, "eventTalkJoined", playerCurrentRank, playerNextRank, false, true);
end
else
callClientFunction(player, "eventTalkJoined", playerCurrentRank, playerNextRank);
end
callClientFunction(player, "eventTalkJoinedOnly");
else
callClientFunction(player, "eventTalkExclusive");
end
callClientFunction(player, "eventTalkStepBreak");
player:endEvent();
end

View file

@ -0,0 +1,510 @@
--[[
PopulaceCompanyShop Script
Functions:
eventTalkStepCantUse() -- When player tries to buy from another GC's shop
eventTalkPreJoin() -- Dialog for the shop
eventTalkPreJoinQuest() -- Tutorial dialog for the shop?
eventTalkJoined(???) -- Dialog for the shop, they salute. Orphaned parameter?
eventTalkFestival() -- Festival Day Event Dialog
eventTalkFestival2() -- Festival Day Event Follow-up Dialog
eventTalkMainMenu(???, ???) -- Shop menu for picking GC items
eventShopMenuOpen() -- Sets up shop menu. Calls getSpecialEventWork, value 8 shows GC firework & 11 a Patriot's Choker
eventShopMenuAsk() -- Opens up the shop menu.
eventShopMenuClose()
eventGuideChocoboWhistle(???) -- Tutorial dialog after purchasing Chocobo issuance slip. Orphaned parameter?
eventGuideTownTransport(index) -- Tutorial dialog after purchasing an aetherpass. Index is item ID.
eventAskChocoboCustomize(index, price) -- Chocobo Barding purchase dialog. Index is item ID.
eventChocoboCustomize() -- Follow-up dialog if you purchase Chocobo Barding.
getGrandCompanyNumber() -- Returns GC value of the NPC
getShopItemStartIndex(index) -- Gets starting index value based on GC shop
getShopItemEndIndex(index) -- Gets ending index value based on GC shop
getShopSellingItemMax(???) --
getShopSellingItemDetail(player, ???, ???)
eventTalkStepBreak() -- Returns NPC to their starting direction
--]]
require ("global")
require ("shop")
function init(npc)
return false, false, 0, 0;
end
gcOfficer = {
[1500202] = 1, -- Limsa Shop
[1500203] = 2, -- Grid Shop
[1500201] = 3, -- Flame Shop
}
shopInfo = { -- [index] = { itemID, itemQuality, itemQuantity, itemCost, gcRank, city, special, itemCategory }
[100001] = {3010403, 1, 10, 20, 0, 1, 0, 1},
[100002] = {3010402, 1, 10, 30, 0, 1, 0, 1},
[100003] = {3020202, 1, 1, 50, 0, 1, 0, 1},
[100004] = {3020406, 1, 20, 10, 0, 1, 0, 1},
[100005] = {3020403, 1, 10, 15, 0, 1, 0, 1},
[100006] = {3020402, 1, 5, 60, 0, 1, 0, 1},
[100007] = {3020404, 1, 5, 100, 0, 1, 0, 1},
[100008] = {3020528, 1, 5, 50, 0, 1, 0, 1},
[100009] = {3020516, 1, 5, 50, 0, 1, 0, 1},
[100010] = {3020411, 1, 1, 15, 0, 1, 0, 1},
[100011] = {3020412, 1, 1, 200, 0, 1, 0, 1},
[100012] = {3020509, 1, 1, 200, 0, 1, 0, 1},
[100013] = {3020510, 1, 1, 200, 0, 1, 0, 1},
[100014] = {10013001, 1, 20, 5, 0, 1, 0, 1},
[100015] = {10013002, 1, 20, 25, 0, 1, 0, 1},
[100016] = {10013003, 1, 20, 45, 0, 1, 0, 1},
[100017] = {10013004, 1, 20, 100, 0, 1, 0, 1},
[100018] = {10013005, 1, 20, 150, 0, 1, 0, 1},
[100019] = {3910402, 1, 99, 85, 0, 1, 0, 1},
[100020] = {3910103, 1, 99, 120, 0, 1, 0, 1},
[100021] = {3910203, 1, 99, 120, 0, 1, 0, 1},
[100022] = {3910305, 1, 99, 85, 0, 1, 0, 1},
[100023] = {3920004, 1, 999, 50, 0, 1, 0, 1},
[100024] = {3920006, 1, 999, 70, 0, 1, 0, 1},
[100025] = {3920003, 1, 999, 115, 0, 1, 0, 1},
[100026] = {3910005, 1, 99, 75, 0, 1, 0, 1},
[100027] = {3910006, 1, 99, 90, 0, 1, 0, 1},
[100028] = {3940011, 1, 20, 20, 0, 1, 0, 1},
[100029] = {3940010, 1, 20, 30, 0, 1, 0, 1},
[100030] = {3020504, 1, 1, 400, 15, 1, 0, 1},
[100031] = {3020505, 1, 1, 400, 15, 1, 0, 1},
[100032] = {3020506, 1, 1, 300, 31, 1, 0, 1},
[101001] = {4040010, 1, 1, 500, 0, 1, 0, 2},
[101002] = {4040110, 1, 1, 1000, 0, 1, 0, 2},
[101003] = {4040205, 1, 1, 1400, 0, 1, 0, 2},
[101004] = {4040305, 1, 1, 3000, 0, 1, 0, 2},
[101005] = {4040204, 1, 1, 4000, 0, 1, 0, 2},
[101006] = {4080304, 1, 1, 950, 0, 1, 0, 2},
[101007] = {4080211, 1, 1, 1000, 0, 1, 0, 2},
[101008] = {4080106, 1, 1, 2000, 0, 1, 0, 2},
[101009] = {4080303, 1, 1, 4000, 0, 1, 0, 2},
[101010] = {5020010, 1, 1, 900, 0, 1, 0, 2},
[101011] = {5020209, 1, 1, 1000, 0, 1, 0, 2},
[101012] = {5020213, 1, 1, 1600, 0, 1, 0, 2},
[101013] = {5020305, 1, 1, 4000, 0, 1, 0, 2},
[101014] = {8030350, 1, 1, 750, 0, 1, 0, 2},
[101015] = {8030447, 1, 1, 750, 0, 1, 0, 2},
[101016] = {8031223, 1, 1, 750, 0, 1, 0, 2},
[101017] = {8032008, 1, 1, 750, 0, 1, 0, 2},
[101018] = {9050029, 1, 1, 900, 0, 1, 0, 2},
[101019] = {9050044, 1, 1, 1900, 0, 1, 0, 2},
[101020] = {9040032, 1, 1, 950, 0, 1, 0, 2},
[101021] = {9040025, 1, 1, 1500, 0, 1, 0, 2},
[101022] = {8013201, 1, 1, 1000, 11, 1, 0, 2},
[101023] = {8032601, 1, 1, 1000, 11, 1, 0, 2},
[101024] = {8071301, 1, 1, 1000, 11, 1, 0, 2},
[101025] = {8081701, 1, 1, 1000, 11, 1, 0, 2},
[101026] = {8050620, 1, 1, 1200, 11, 1, 0, 2},
[101027] = {8050243, 1, 1, 1200, 11, 1, 0, 2},
[101028] = {8050344, 1, 1, 1200, 11, 1, 0, 2},
[101029] = {8050028, 1, 1, 1200, 11, 1, 0, 2},
[101030] = {8090706, 1, 1, 1200, 11, 1, 0, 2},
[101031] = {4030205, 1, 1, 2500, 13, 1, 0, 2},
[101032] = {4020306, 1, 1, 2500, 13, 1, 0, 2},
[101033] = {4040014, 1, 1, 2500, 13, 1, 0, 2},
[101034] = {4080408, 1, 1, 2500, 13, 1, 0, 2},
[101035] = {4070310, 1, 1, 2500, 13, 1, 0, 2},
[101036] = {5030307, 1, 1, 2500, 13, 1, 0, 2},
[101037] = {5020112, 1, 1, 2500, 13, 1, 0, 2},
[101038] = {4100205, 1, 1, 2000, 13, 1, 0, 2},
[101039] = {8011609, 1, 1, 3000, 15, 1, 0, 2},
[101040] = {8032311, 1, 1, 3000, 15, 1, 0, 2},
[101041] = {8071017, 1, 1, 3000, 15, 1, 0, 2},
[101042] = {8050132, 1, 1, 3000, 15, 1, 0, 2},
[101043] = {8081123, 1, 1, 3000, 15, 1, 0, 2},
[101044] = {4030117, 1, 1, 4500, 17, 1, 0, 2},
[101045] = {4020210, 1, 1, 4500, 17, 1, 0, 2},
[101046] = {4040406, 1, 1, 4500, 17, 1, 0, 2},
[101047] = {4080107, 1, 1, 4500, 17, 1, 0, 2},
[101048] = {4070108, 1, 1, 4500, 17, 1, 0, 2},
[101049] = {5030111, 1, 1, 4500, 17, 1, 0, 2},
[101050] = {5020013, 1, 1, 4500, 17, 1, 0, 2},
[101051] = {4100405, 1, 1, 4000, 17, 1, 0, 2},
[101052] = {8011610, 1, 1, 5000, 21, 1, 0, 2},
[101053] = {8032312, 1, 1, 5000, 21, 1, 0, 2},
[101054] = {8071018, 1, 1, 5000, 21, 1, 0, 2},
[101055] = {8050133, 1, 1, 5000, 21, 1, 0, 2},
[101056] = {8050769, 1, 1, 5000, 21, 1, 0, 2},
[101057] = {8081124, 1, 1, 5000, 21, 1, 0, 2},
[101058] = {8080565, 1, 1, 5000, 21, 1, 0, 2},
[101059] = {8090609, 1, 1, 5000, 21, 1, 0, 2},
[101060] = {9050021, 1, 1, 1000, 21, 1, 0, 2},
[101061] = {9050022, 1, 1, 1000, 21, 1, 0, 2},
[101062] = {9010025, 1, 1, 1000, 21, 1, 0, 2},
[101063] = {4100804, 1, 1, 5500, 23, 1, 0, 2},
[101064] = {8013614, 1, 1, 5500, 23, 1, 0, 2},
[101065] = {8032820, 1, 1, 5500, 23, 1, 0, 2},
[101066] = {8051516, 1, 1, 5500, 23, 1, 0, 2},
[101067] = {8071520, 1, 1, 5500, 23, 1, 0, 2},
[101068] = {9030060, 1, 1, 5500, 23, 1, 0, 2},
[101069] = {9050067, 1, 1, 5500, 23, 1, 0, 2},
[101070] = {8013615, 1, 1, 6000, 25, 1, 0, 2},
[101071] = {8013616, 1, 1, 6000, 25, 1, 0, 2},
[101072] = {8032821, 1, 1, 6000, 25, 1, 0, 2},
[101073] = {8071521, 1, 1, 6000, 25, 1, 0, 2},
[101074] = {8081914, 1, 1, 6000, 25, 1, 0, 2},
[101075] = {9040065, 1, 1, 6000, 25, 1, 0, 2},
[101076] = {9010061, 1, 1, 6000, 25, 1, 0, 2},
[101077] = {4100805, 1, 1, 6500, 27, 1, 0, 2},
[101078] = {4020408, 1, 1, 6500, 27, 1, 0, 2},
[101079] = {4040508, 1, 1, 6500, 27, 1, 0, 2},
[101080] = {4080508, 1, 1, 6500, 27, 1, 0, 2},
[101081] = {4070408, 1, 1, 6500, 27, 1, 0, 2},
[101082] = {5030408, 1, 1, 6500, 27, 1, 0, 2},
[101083] = {5020408, 1, 1, 6500, 27, 1, 0, 2},
[101084] = {4030604, 1, 1, 25000, 31, 1, 0, 2},
[101085] = {4020404, 1, 1, 25000, 31, 1, 0, 2},
[101086] = {4040504, 1, 1, 25000, 31, 1, 0, 2},
[101087] = {4080504, 1, 1, 25000, 31, 1, 0, 2},
[101088] = {4070404, 1, 1, 25000, 31, 1, 0, 2},
[101089] = {5030404, 1, 1, 25000, 31, 1, 0, 2},
[101090] = {5020404, 1, 1, 25000, 31, 1, 0, 2},
[101091] = {8013204, 1, 1, 6000, 31, 1, 0, 2},
[101092] = {8032604, 1, 1, 6000, 31, 1, 0, 2},
[101093] = {8071304, 1, 1, 6000, 31, 1, 0, 2},
[101094] = {8081704, 1, 1, 6000, 31, 1, 0, 2},
[102001] = {3020601, 1, 20, 5, 0, 1, 8, 3},
[102002] = {9040018, 1, 1, 1000, 11, 1, 11, 3},
[103001] = {2001004, 1, 1, 3000, 11, 1, 0, 4},
[103002] = {2001014, 1, 1, 3000, 15, 1, 0, 4},
[103003] = {2001017, 1, 1, 2000, 21, 1, 0, 4},
[103004] = {2001018, 1, 1, 3000, 21, 1, 0, 4},
[103005] = {2001019, 1, 1, 4000, 21, 1, 0, 4},
[103006] = {2001026, 1, 1, 25000, 27, 1, 0, 4},
[200001] = {3010403, 1, 10, 20, 0, 2, 0, 1},
[200002] = {3010402, 1, 10, 30, 0, 2, 0, 1},
[200003] = {3020203, 1, 1, 50, 0, 2, 0, 1},
[200004] = {3020406, 1, 20, 10, 0, 2, 0, 1},
[200005] = {3020403, 1, 10, 15, 0, 2, 0, 1},
[200006] = {3020402, 1, 5, 60, 0, 2, 0, 1},
[200007] = {3020404, 1, 5, 100, 0, 2, 0, 1},
[200008] = {3020528, 1, 5, 50, 0, 2, 0, 1},
[200009] = {3020516, 1, 5, 50, 0, 2, 0, 1},
[200010] = {3020411, 1, 1, 15, 0, 2, 0, 1},
[200011] = {3020412, 1, 1, 200, 0, 2, 0, 1},
[200012] = {3020509, 1, 1, 200, 0, 2, 0, 1},
[200013] = {3020510, 1, 1, 200, 0, 2, 0, 1},
[200014] = {10013001, 1, 20, 5, 0, 2, 0, 1},
[200015] = {10013002, 1, 20, 25, 0, 2, 0, 1},
[200016] = {10013003, 1, 20, 45, 0, 2, 0, 1},
[200017] = {10013004, 1, 20, 100, 0, 2, 0, 1},
[200018] = {10013005, 1, 20, 150, 0, 2, 0, 1},
[200019] = {3910402, 1, 99, 85, 0, 2, 0, 1},
[200020] = {3910103, 1, 99, 120, 0, 2, 0, 1},
[200021] = {3910203, 1, 99, 120, 0, 2, 0, 1},
[200022] = {3910305, 1, 99, 85, 0, 2, 0, 1},
[200023] = {3920004, 1, 999, 50, 0, 2, 0, 1},
[200024] = {3920006, 1, 999, 70, 0, 2, 0, 1},
[200025] = {3920003, 1, 999, 115, 0, 2, 0, 1},
[200026] = {3910005, 1, 99, 75, 0, 2, 0, 1},
[200027] = {3910006, 1, 99, 90, 0, 2, 0, 1},
[200028] = {3940011, 1, 20, 20, 0, 2, 0, 1},
[200029] = {3940010, 1, 20, 30, 0, 2, 0, 1},
[200030] = {3020504, 1, 1, 400, 15, 2, 0, 1},
[200031] = {3020505, 1, 1, 400, 15, 2, 0, 1},
[200032] = {3020506, 1, 1, 300, 31, 2, 0, 1},
[201001] = {5030107, 1, 1, 350, 0, 2, 0, 2},
[201002] = {5030207, 1, 1, 750, 0, 2, 0, 2},
[201003] = {5030206, 1, 1, 1000, 0, 2, 0, 2},
[201004] = {5030029, 1, 1, 1500, 0, 2, 0, 2},
[201005] = {5030031, 1, 1, 2400, 0, 2, 0, 2},
[201006] = {5030209, 1, 1, 3000, 0, 2, 0, 2},
[201007] = {5030028, 1, 1, 4000, 0, 2, 0, 2},
[201008] = {4020109, 1, 1, 800, 0, 2, 0, 2},
[201009] = {4020106, 1, 1, 1000, 0, 2, 0, 2},
[201010] = {4020008, 1, 1, 2200, 0, 2, 0, 2},
[201011] = {4020305, 1, 1, 4000, 0, 2, 0, 2},
[201012] = {4100005, 1, 1, 1000, 0, 2, 0, 2},
[201013] = {4100109, 1, 1, 4000, 0, 2, 0, 2},
[201014] = {8030035, 1, 1, 750, 0, 2, 0, 2},
[201015] = {8030919, 1, 1, 750, 0, 2, 0, 2},
[201016] = {8031821, 1, 1, 750, 0, 2, 0, 2},
[201017] = {8032220, 1, 1, 750, 0, 2, 0, 2},
[201018] = {9050029, 1, 1, 900, 0, 2, 0, 2},
[201019] = {9050044, 1, 1, 1900, 0, 2, 0, 2},
[201020] = {9040035, 1, 1, 950, 0, 2, 0, 2},
[201021] = {9040025, 1, 1, 1500, 0, 2, 0, 2},
[201022] = {8013202, 1, 1, 1000, 11, 2, 0, 2},
[201023] = {8032602, 1, 1, 1000, 11, 2, 0, 2},
[201024] = {8071302, 1, 1, 1000, 11, 2, 0, 2},
[201025] = {8081702, 1, 1, 1000, 11, 2, 0, 2},
[201026] = {8050148, 1, 1, 1200, 11, 2, 0, 2},
[201027] = {8050244, 1, 1, 1200, 11, 2, 0, 2},
[201028] = {8051222, 1, 1, 1200, 11, 2, 0, 2},
[201029] = {8050029, 1, 1, 1200, 11, 2, 0, 2},
[201030] = {8090707, 1, 1, 1200, 11, 2, 0, 2},
[201031] = {4030710, 1, 1, 2500, 13, 2, 0, 2},
[201032] = {4020211, 1, 1, 2500, 13, 2, 0, 2},
[201033] = {4040407, 1, 1, 2500, 13, 2, 0, 2},
[201034] = {4080213, 1, 1, 2500, 13, 2, 0, 2},
[201035] = {4070215, 1, 1, 2500, 13, 2, 0, 2},
[201036] = {5030113, 1, 1, 2500, 13, 2, 0, 2},
[201037] = {5020014, 1, 1, 2500, 13, 2, 0, 2},
[201038] = {4100608, 1, 1, 2000, 13, 2, 0, 2},
[201039] = {8010566, 1, 1, 3000, 15, 2, 0, 2},
[201040] = {8030625, 1, 1, 3000, 15, 2, 0, 2},
[201041] = {8070724, 1, 1, 3000, 15, 2, 0, 2},
[201042] = {8050618, 1, 1, 3000, 15, 2, 0, 2},
[201043] = {8080715, 1, 1, 3000, 15, 2, 0, 2},
[201044] = {4030016, 1, 1, 4500, 17, 2, 0, 2},
[201045] = {4020012, 1, 1, 4500, 17, 2, 0, 2},
[201046] = {4040111, 1, 1, 4500, 17, 2, 0, 2},
[201047] = {4080010, 1, 1, 4500, 17, 2, 0, 2},
[201048] = {4070013, 1, 1, 4500, 17, 2, 0, 2},
[201049] = {5030308, 1, 1, 4500, 17, 2, 0, 2},
[201050] = {5020113, 1, 1, 4500, 17, 2, 0, 2},
[201051] = {4100507, 1, 1, 4000, 17, 2, 0, 2},
[201052] = {8010567, 1, 1, 5000, 21, 2, 0, 2},
[201053] = {8030626, 1, 1, 5000, 21, 2, 0, 2},
[201054] = {8070725, 1, 1, 5000, 21, 2, 0, 2},
[201055] = {8050619, 1, 1, 5000, 21, 2, 0, 2},
[201056] = {8050768, 1, 1, 5000, 21, 2, 0, 2},
[201057] = {8080716, 1, 1, 5000, 21, 2, 0, 2},
[201058] = {8080564, 1, 1, 5000, 21, 2, 0, 2},
[201059] = {8090506, 1, 1, 5000, 21, 2, 0, 2},
[201060] = {9050025, 1, 1, 1000, 21, 2, 0, 2},
[201061] = {9050026, 1, 1, 1000, 21, 2, 0, 2},
[201062] = {9010025, 1, 1, 1000, 21, 2, 0, 2},
[201063] = {4100806, 1, 1, 5500, 23, 2, 0, 2},
[201064] = {8013617, 1, 1, 5500, 23, 2, 0, 2},
[201065] = {8032822, 1, 1, 5500, 23, 2, 0, 2},
[201066] = {8051517, 1, 1, 5500, 23, 2, 0, 2},
[201067] = {8071522, 1, 1, 5500, 23, 2, 0, 2},
[201068] = {9030061, 1, 1, 5500, 23, 2, 0, 2},
[201069] = {9050068, 1, 1, 5500, 23, 2, 0, 2},
[201070] = {8013618, 1, 1, 6000, 25, 2, 0, 2},
[201071] = {8013619, 1, 1, 6000, 25, 2, 0, 2},
[201072] = {8032823, 1, 1, 6000, 25, 2, 0, 2},
[201073] = {8071523, 1, 1, 6000, 25, 2, 0, 2},
[201074] = {8081915, 1, 1, 6000, 25, 2, 0, 2},
[201075] = {9040066, 1, 1, 6000, 25, 2, 0, 2},
[201076] = {9010062, 1, 1, 6000, 25, 2, 0, 2},
[201077] = {4100807, 1, 1, 6500, 27, 2, 0, 2},
[201078] = {4020409, 1, 1, 6500, 27, 2, 0, 2},
[201079] = {4040509, 1, 1, 6500, 27, 2, 0, 2},
[201080] = {4080509, 1, 1, 6500, 27, 2, 0, 2},
[201081] = {4070409, 1, 1, 6500, 27, 2, 0, 2},
[201082] = {5030409, 1, 1, 6500, 27, 2, 0, 2},
[201083] = {5020409, 1, 1, 6500, 27, 2, 0, 2},
[201084] = {4030605, 1, 1, 25000, 31, 2, 0, 2},
[201085] = {4020405, 1, 1, 25000, 31, 2, 0, 2},
[201086] = {4040505, 1, 1, 25000, 31, 2, 0, 2},
[201087] = {4080505, 1, 1, 25000, 31, 2, 0, 2},
[201088] = {4070405, 1, 1, 25000, 31, 2, 0, 2},
[201089] = {5030405, 1, 1, 25000, 31, 2, 0, 2},
[201090] = {5020405, 1, 1, 25000, 31, 2, 0, 2},
[201091] = {8013205, 1, 1, 6000, 31, 2, 0, 2},
[201092] = {8032605, 1, 1, 6000, 31, 2, 0, 2},
[201093] = {8071305, 1, 1, 6000, 31, 2, 0, 2},
[201094] = {8081705, 1, 1, 6000, 31, 2, 0, 2},
[202001] = {3020603, 1, 20, 5, 0, 2, 8, 3},
[202002] = {9040018, 1, 1, 1000, 11, 2, 11, 3},
[203001] = {2001005, 1, 1, 3000, 11, 2, 0, 4},
[203002] = {2001015, 1, 1, 3000, 15, 2, 0, 4},
[203003] = {2001020, 1, 1, 2000, 21, 2, 0, 4},
[203004] = {2001021, 1, 1, 3000, 21, 2, 0, 4},
[203005] = {2001022, 1, 1, 4000, 21, 2, 0, 4},
[203006] = {2001026, 1, 1, 25000, 27, 2, 0, 4},
[300001] = {3010403, 1, 10, 20, 0, 3, 0, 1},
[300002] = {3010402, 1, 10, 30, 0, 3, 0, 1},
[300003] = {3020204, 1, 1, 50, 0, 3, 0, 1},
[300004] = {3020406, 1, 20, 10, 0, 3, 0, 1},
[300005] = {3020403, 1, 10, 15, 0, 3, 0, 1},
[300006] = {3020402, 1, 5, 60, 0, 3, 0, 1},
[300007] = {3020404, 1, 5, 100, 0, 3, 0, 1},
[300008] = {3020528, 1, 5, 50, 0, 3, 0, 1},
[300009] = {3020516, 1, 5, 50, 0, 3, 0, 1},
[300010] = {3020411, 1, 1, 15, 0, 3, 0, 1},
[300011] = {3020412, 1, 1, 200, 0, 3, 0, 1},
[300012] = {3020509, 1, 1, 200, 0, 3, 0, 1},
[300013] = {3020510, 1, 1, 200, 0, 3, 0, 1},
[300014] = {10013001, 1, 20, 5, 0, 3, 0, 1},
[300015] = {10013002, 1, 20, 25, 0, 3, 0, 1},
[300016] = {10013003, 1, 20, 45, 0, 3, 0, 1},
[300017] = {10013004, 1, 20, 100, 0, 3, 0, 1},
[300018] = {10013005, 1, 20, 150, 0, 3, 0, 1},
[300019] = {3910402, 1, 99, 85, 0, 3, 0, 1},
[300020] = {3910103, 1, 99, 120, 0, 3, 0, 1},
[300021] = {3910203, 1, 99, 120, 0, 3, 0, 1},
[300022] = {3910305, 1, 99, 85, 0, 3, 0, 1},
[300023] = {3920004, 1, 999, 50, 0, 3, 0, 1},
[300024] = {3920006, 1, 999, 70, 0, 3, 0, 1},
[300025] = {3920003, 1, 999, 115, 0, 3, 0, 1},
[300026] = {3910005, 1, 99, 75, 0, 3, 0, 1},
[300027] = {3910006, 1, 99, 90, 0, 3, 0, 1},
[300028] = {3940011, 1, 20, 20, 0, 3, 0, 1},
[300029] = {3940010, 1, 20, 30, 0, 3, 0, 1},
[300030] = {3020504, 1, 1, 400, 15, 3, 0, 1},
[300031] = {3020505, 1, 1, 400, 15, 3, 0, 1},
[300032] = {3020506, 1, 1, 300, 31, 3, 0, 1},
[301001] = {4030006, 1, 1, 400, 0, 3, 0, 2},
[301002] = {4030015, 1, 1, 1000, 0, 3, 0, 2},
[301003] = {4030405, 1, 1, 1600, 0, 3, 0, 2},
[301004] = {4030506, 1, 1, 3200, 0, 3, 0, 2},
[301005] = {4030505, 1, 1, 4000, 0, 3, 0, 2},
[301006] = {4070011, 1, 1, 550, 0, 3, 0, 2},
[301007] = {4070105, 1, 1, 1000, 0, 3, 0, 2},
[301008] = {4070212, 1, 1, 1500, 0, 3, 0, 2},
[301009] = {4070211, 1, 1, 4000, 0, 3, 0, 2},
[301010] = {4100710, 1, 1, 450, 0, 3, 0, 2},
[301011] = {4100403, 1, 1, 1000, 0, 3, 0, 2},
[301012] = {4100404, 1, 1, 1900, 0, 3, 0, 2},
[301013] = {4100306, 1, 1, 4000, 0, 3, 0, 2},
[301014] = {8030248, 1, 1, 750, 0, 3, 0, 2},
[301015] = {8030548, 1, 1, 750, 0, 3, 0, 2},
[301016] = {8031021, 1, 1, 750, 0, 3, 0, 2},
[301017] = {8031513, 1, 1, 750, 0, 3, 0, 2},
[301018] = {9050029, 1, 1, 900, 0, 3, 0, 2},
[301019] = {9050044, 1, 1, 1900, 0, 3, 0, 2},
[301020] = {9040036, 1, 1, 950, 0, 3, 0, 2},
[301021] = {9040025, 1, 1, 1500, 0, 3, 0, 2},
[301022] = {8013203, 1, 1, 1000, 11, 3, 0, 2},
[301023] = {8032603, 1, 1, 1000, 11, 3, 0, 2},
[301024] = {8071303, 1, 1, 1000, 11, 3, 0, 2},
[301025] = {8081703, 1, 1, 1000, 11, 3, 0, 2},
[301026] = {8050520, 1, 1, 1200, 11, 3, 0, 2},
[301027] = {8051024, 1, 1, 1200, 11, 3, 0, 2},
[301028] = {8050345, 1, 1, 1200, 11, 3, 0, 2},
[301029] = {8050449, 1, 1, 1200, 11, 3, 0, 2},
[301030] = {8090708, 1, 1, 1200, 11, 3, 0, 2},
[301031] = {4030305, 1, 1, 2500, 13, 3, 0, 2},
[301032] = {4020011, 1, 1, 2500, 13, 3, 0, 2},
[301033] = {4040208, 1, 1, 2500, 13, 3, 0, 2},
[301034] = {4080306, 1, 1, 2500, 13, 3, 0, 2},
[301035] = {4070012, 1, 1, 2500, 13, 3, 0, 2},
[301036] = {5030037, 1, 1, 2500, 13, 3, 0, 2},
[301037] = {5020217, 1, 1, 2500, 13, 3, 0, 2},
[301038] = {4100112, 1, 1, 2000, 13, 3, 0, 2},
[301039] = {8011522, 1, 1, 3000, 15, 3, 0, 2},
[301040] = {8030744, 1, 1, 3000, 15, 3, 0, 2},
[301041] = {8070361, 1, 1, 3000, 15, 3, 0, 2},
[301042] = {8050766, 1, 1, 3000, 15, 3, 0, 2},
[301043] = {8080562, 1, 1, 3000, 15, 3, 0, 2},
[301044] = {4030408, 1, 1, 4500, 17, 3, 0, 2},
[301045] = {4020113, 1, 1, 4500, 17, 3, 0, 2},
[301046] = {4040306, 1, 1, 4500, 17, 3, 0, 2},
[301047] = {4080409, 1, 1, 4500, 17, 3, 0, 2},
[301048] = {4070311, 1, 1, 4500, 17, 3, 0, 2},
[301049] = {5030210, 1, 1, 4500, 17, 3, 0, 2},
[301050] = {5020307, 1, 1, 4500, 17, 3, 0, 2},
[301051] = {4100712, 1, 1, 4000, 17, 3, 0, 2},
[301052] = {8011523, 1, 1, 5000, 21, 3, 0, 2},
[301053] = {8030745, 1, 1, 5000, 21, 3, 0, 2},
[301054] = {8070362, 1, 1, 5000, 21, 3, 0, 2},
[301055] = {8050811, 1, 1, 5000, 21, 3, 0, 2},
[301056] = {8050767, 1, 1, 5000, 21, 3, 0, 2},
[301057] = {8080015, 1, 1, 5000, 21, 3, 0, 2},
[301058] = {8080563, 1, 1, 5000, 21, 3, 0, 2},
[301059] = {8090709, 1, 1, 5000, 21, 3, 0, 2},
[301060] = {9050023, 1, 1, 1000, 21, 3, 0, 2},
[301061] = {9050024, 1, 1, 1000, 21, 3, 0, 2},
[301062] = {9010025, 1, 1, 1000, 21, 3, 0, 2},
[301063] = {4100808, 1, 1, 5500, 23, 3, 0, 2},
[301064] = {8013620, 1, 1, 5500, 23, 3, 0, 2},
[301065] = {8032824, 1, 1, 5500, 23, 3, 0, 2},
[301066] = {8051518, 1, 1, 5500, 23, 3, 0, 2},
[301067] = {8071524, 1, 1, 5500, 23, 3, 0, 2},
[301068] = {9030062, 1, 1, 5500, 23, 3, 0, 2},
[301069] = {9050069, 1, 1, 5500, 23, 3, 0, 2},
[301070] = {8013621, 1, 1, 6000, 25, 3, 0, 2},
[301071] = {8013622, 1, 1, 6000, 25, 3, 0, 2},
[301072] = {8032825, 1, 1, 6000, 25, 3, 0, 2},
[301073] = {8071525, 1, 1, 6000, 25, 3, 0, 2},
[301074] = {8081916, 1, 1, 6000, 25, 3, 0, 2},
[301075] = {9040067, 1, 1, 6000, 25, 3, 0, 2},
[301076] = {9010063, 1, 1, 6000, 25, 3, 0, 2},
[301077] = {4100809, 1, 1, 6500, 27, 3, 0, 2},
[301078] = {4020410, 1, 1, 6500, 27, 3, 0, 2},
[301079] = {4040510, 1, 1, 6500, 27, 3, 0, 2},
[301080] = {4080510, 1, 1, 6500, 27, 3, 0, 2},
[301081] = {4070410, 1, 1, 6500, 27, 3, 0, 2},
[301082] = {5030410, 1, 1, 6500, 27, 3, 0, 2},
[301083] = {5020410, 1, 1, 6500, 27, 3, 0, 2},
[301084] = {4030606, 1, 1, 25000, 31, 3, 0, 2},
[301085] = {4020406, 1, 1, 25000, 31, 3, 0, 2},
[301086] = {4040506, 1, 1, 25000, 31, 3, 0, 2},
[301087] = {4080506, 1, 1, 25000, 31, 3, 0, 2},
[301088] = {4070406, 1, 1, 25000, 31, 3, 0, 2},
[301089] = {5030406, 1, 1, 25000, 31, 3, 0, 2},
[301090] = {5020406, 1, 1, 25000, 31, 3, 0, 2},
[301091] = {8013206, 1, 1, 6000, 31, 3, 0, 2},
[301092] = {8032606, 1, 1, 6000, 31, 3, 0, 2},
[301093] = {8071306, 1, 1, 6000, 31, 3, 0, 2},
[301094] = {8081706, 1, 1, 6000, 31, 3, 0, 2},
[302001] = {3020602, 1, 20, 5, 0, 3, 8, 3},
[302002] = {9040018, 1, 1, 1000, 11, 3, 11, 3},
[303001] = {2001006, 1, 1, 3000, 11, 3, 0, 4},
[303002] = {2001016, 1, 1, 3000, 15, 3, 0, 4},
[303003] = {2001023, 1, 1, 2000, 21, 3, 0, 4},
[303004] = {2001024, 1, 1, 3000, 21, 3, 0, 4},
[303005] = {2001025, 1, 1, 4000, 21, 3, 0, 4},
[303006] = {2001026, 1, 1, 25000, 27, 3, 0, 4},
}
function onEventStarted(player, npc, triggerName)
skipGCcheck = 0; -- 0 No, 1 Yes
playerGC = player.gcCurrent;
playerGCSeal = 1000200 + playerGC;
playerCurrentRank = 13;
npcId = npc:GetActorClassId();
if (playerGC == gcOfficer[npcId] or skipGCcheck == 1) then
callClientFunction(player, "eventTalkPreJoin");
--player:SendMessage(0x20, "", "[Info]: Client takes awhile to load GC shops");
while (true) do
eventTalkChoice = callClientFunction(player, "eventTalkMainMenu", 8, 11);
--player:SendMessage(0x20, "", "eventTalkMainMenu: " .. tostring(eventTalkChoice));
if (eventTalkChoice == 1) then
t1, t2, t3 = callClientFunction(player, "eventShopMenuOpen");
--player:SendMessage(0x20, "", "eventShopMenuOpen: " .. tostring(t1) .. ", ".. tostring(t2) .. ", ".. tostring(t3));
while (true) do
-- TODO: ADD RANK CHECK, CITY CHECK, AND ITEM-RANGE CHECK
buyResult, buyIndex = callClientFunction(player, "eventShopMenuAsk");
if (buyIndex == -1) then
callClientFunction(player, "eventShopMenuClose");
break;
else
-- [index] = { itemID, itemQuality, itemQuantity, itemCost gcRank, city, special, itemCategory }
if (shopInfo[buyIndex][8] == 4) then
location = INVENTORY_KEYITEMS;
else
location = INVENTORY_NORMAL;
end
end
purchaseItem(player, location, shopInfo[buyIndex][1], shopInfo[buyIndex][3], shopInfo[buyIndex][2], shopInfo[buyIndex][4], playerGCSeal);
end
--player:SendMessage(0x20, "", "Player picked an item at gcSealShopIndex " .. tostring(buyResult) .. ", ".. tostring(buyIndex));
elseif (eventTalkChoice == -1) then
break;
end
end
else
callClientFunction(player, "eventTalkStepCantUse");
end
callClientFunction(player, "eventTalkStepBreak");
player:endEvent();
end

View file

@ -0,0 +1,464 @@
--[[
PopulaceCompanySupply Script
This class handles the menus for player's delivering specific items in exchange for grand company seals.
The supply/provision schedule runs on a weekly rotation, which resets Monday at 12AM JST, with eight rotations total to cycle through.
Each desired item has a server-wide max that it can be turned in, and when that is fulfilled, it moves to the next item in that week's list to work on.
NPCs involved in the script use the Noc001 script for dialog and menu interactions.
Functions:
eventTalkPreJoin() - Dialog when you're not affiliated
eventTalkExclusive() - Dialog when you're part of a GC but not the one of the actor?
eventTalkJoined() - Salutes then softlocks the client due to removed dialog strings. Obsolete function.
eventQuestItemMenuOpen(itemId, itemPrice, itemPriceHq, supplyType) - supplyType: 1 = Supply, 2 = Provisioning, 3 = Totorak, 4 = Dzmael, 5 = Primal, 6 = NM drops
eventQuestItemMenuSelect(quantity, quality, unk) - Brings up the shop-style menu for viewing item detail and confirming item delivery. Args appear to do nothing on client?
eventQuestItemMenuClose() - Closes menu
eventQuestSupplyItemActor(unk1) -- Client calls this automatically for setting up Expeditionary window in some manner
eventQuestSupplyItemID(unk1, unk2) -- eventQuestSupplyItemActor() calls this to sets item ranges based on category
getEventQuestSupplyMode() - Returns current supply mode set by eventQuestItemMenuOpen()
eventTalkStepBreak() - Resets actor engage state
Noc001 Functions:
pENPCAskSupplyWelcome(npcGC) -- Welcome dialog
pENPCAskSupply(npcGC) -- Brings up the delivery selection menu
eventQuestAskExWelcome(npcGC) -- Dialog when you pick Expeditionary
eventQuestAskExArea(npcGC) -- Brings up the Expeditionary selection menu
pENPCAskNowTalk(npcGC) -- Dialog for picking Delivery Status from pENPCAskSupply()
nowSup(itemId1, current1, max1, itemId2, current2, max2, itemId3, current3, max3) -- Says current 3 items and current amount delivered vs. max it'll take
nowSupAddItem(itemId, current, max) -- Lists bonus item
pItem(itemId1, unk1, itemId2, unk2, itemId3, unk3, itemId4, unk4) -- Lists which item(s) you want to delivery. Fourth item is the bonus, set 0 for hidden.
showSupplyLimit(minutes, seconds, current, required) -- Shows time remaining to finish delivery, shows current/required amount
eventShowPrizeMessage(npcGC) -- Reward dialog for handing something in?
pELimitErr() -- Error msg for GC no longer accepting items.
pETradeErr() -- Transaction error. Inventory error?
pETradeErrLimit(minutes, seconds, current, required) -- Transaction error. Shows time remaining and current/required amount
pESuppylMaxErrKeyWait(isShowLimit, minutes, seconds, current, required) -- Error msg for delivery quota already filled. Optional timer/amount display
pESuppylSealMaxErr() -- Error msg for capped on GC seals, transaction incomplete
eventQuestCantEx(npcGC) -- Dialog explaining you need to be Private Second Class to do Expeditionary missions
--]]
require ("global")
require ("shop")
function init(npc)
return false, false, 0, 0;
end
local gcRep = {
[1500210] = 1, -- Maelstrom Representative
[1500211] = 2, -- Adder Representative
[1500212] = 3, -- Flame Representative
}
local gcItems = { -- Debug purposes. Static item list with seal value and max turn-in.
[111] = {id = 10002015, seals = 8, cap = 1900},
[112] = {id = 8031419, seals = 68, cap = 300},
[113] = {id = 3010011, seals = 3, cap = 5000},
[114] = {id = 8011108, seals = 89, cap = 400},
[115] = {id = 10004001, seals = 5, cap = 3000},
[116] = {id = 10008109, seals = 3, cap = 5000},
[117] = {id = 12000180, seals = 5, cap = 3000},
[118] = {id = 10004026, seals = 9, cap = 3400},
[121] = {id = 10008211, seals = 5, cap = 3000},
[122] = {id = 3020407, seals = 5, cap = 2500},
[123] = {id = 8030220, seals = 92, cap = 200},
[124] = {id = 8030922, seals = 99, cap = 400},
[125] = {id = 10001014, seals = 3, cap = 5000},
[126] = {id = 10008007, seals = 5, cap = 3000},
[127] = {id = 3011217, seals = 3, cap = 5000},
[128] = {id = 3011207, seals = 3, cap = 6000},
[131] = {id = 4030204, seals = 69, cap = 300},
[132] = {id = 10004103, seals = 9, cap = 1700},
[133] = {id = 10009208, seals = 6, cap = 3000},
[134] = {id = 1, seals = 1, cap = 1}, -- Unknown
[135] = {id = 10004008, seals = 9, cap = 1700},
[136] = {id = 10008007, seals = 5, cap = 3000},
[137] = {id = 3011201, seals = 5, cap = 3000},
[138] = {id = 10009401, seals = 6, cap = 6000},
[211] = {id = 10002012, seals = 5, cap = 3000},
[212] = {id = 4100007, seals = 51, cap = 300},
[213] = {id = 3010108, seals = 2, cap = 3000},
[214] = {id = 8080825, seals = 42, cap = 800},
[215] = {id = 10004003, seals = 5, cap = 3000},
[216] = {id = 10002012, seals = 3, cap = 5000},
[217] = {id = 3011104, seals = 2, cap = 3000},
[218] = {id = 3011107, seals = 3, cap = 6000},
}
local gcWeek = { -- Debug purposes. Static weekly item lists. [week] = { [city] = {[category] = { info } } }
[1] = {
[1] = { -- Limsa
[1] = { -- Supply
gcItems[111],
gcItems[112],
gcItems[113],
gcItems[114],
},
[2] = { -- Provision
gcItems[115],
gcItems[116],
gcItems[117],
gcItems[118],
}
},
[2] = { -- Gridania
[1] = { -- Supply
gcItems[121],
gcItems[122],
gcItems[123],
gcItems[124],
},
[2] = { -- Provision
gcItems[125],
gcItems[126],
gcItems[127],
gcItems[128],
}
},
[3] = { -- Ul'dah
[1] = { -- Supply
gcItems[131],
gcItems[132],
gcItems[133],
gcItems[134],
},
[2] = { -- Provision
gcItems[135],
gcItems[136],
gcItems[137],
gcItems[138],
}
}
},
[2] = {
[1] = { -- Limsa
[1] = { -- Supply
gcItems[211],
gcItems[212],
gcItems[213],
gcItems[214],
},
[2] = { -- Provision
gcItems[215],
gcItems[216],
gcItems[217],
gcItems[218],
}
}
}
}
local gcDelivery = { -- Debug purposes. Holds values for current turned in amount and 4th item bonus status.
week = 1,
currentCount = {
{
{49, 81, 5000, 5}, {2402, 4779, 589, 2} -- Limsa Supply/Provision
},
{
{1, 2, 3, 4}, {5, 6, 7, 8} -- Gridania Supply/Provision
},
{
{10, 32, 9, 18}, {23, 49, 9, 300} -- Ul'dah Supply/Provision
}
},
bonus = { {1, 1}, {0,1}, {0,1} }; -- City -> {Supply, Provision}
timeRemainingMinutes = 99,
timeRemainingSeconds = 59,
}
local supplyQuest = GetStaticActor("Noc001");
local skipGCcheck = false; -- Debug
local skipRankCheck = false; -- Debug
local gcCheckProceed = false; -- Debug
function onEventStarted(player, npc, triggerName)
local playerGC = player.gcCurrent;
local limsaRank = player.gcRankLimsa;
local gridaniaRank = player.gcRankGridania;
local uldahRank = player.gcRankUldah;
local playerGCSeal = 1000200 + playerGC;
local npcId = npc:GetActorClassId();
local npcGC = gcRep[npcId];
if (skipGCcheck == true) then
gcCheckProceed = true;
end
if ((playerGC ~= npcGC) and skipGCcheck == false) then
if (playerGC == 0) then
callClientFunction(player, "eventTalkPreJoin");
else
callClientFunction(player, "eventTalkExclusive");
end
else
gcCheckProceed = true;
end
if gcCheckProceed then
callClientFunction(player, "delegateEvent", player, supplyQuest, "pENPCAskSupplyWelcome", gcRep[npcId]);
while (true) do
local choice = callClientFunction(player, "delegateEvent", player, supplyQuest, "pENPCAskSupply", gcRep[npcId]);
if (choice == 2) then -- Supply
deliveryMenuInfo(player, npcGC, 1);
elseif (choice == 3) then -- Provision
deliveryMenuInfo(player, npcGC, 2);
elseif (choice == 4) then -- Expeditionary
local proceed = false;
if (skipRankCheck == true) then
proceed = true;
else
if (playerGC == 1 and limsaRank >= 13 and limsaRank <= 111)
or (playerGC == 2 and gridaniaRank >= 13 and gridaniaRank <= 111)
or (playerGC == 3 and uldahRank >= 13 and uldahRank <= 111) then
proceed = true
end
end
if proceed == true then
callClientFunction(player, "delegateEvent", player, supplyQuest, "eventQuestAskExWelcome", gcRep[npcId]);
while (true) do
local exChoice = callClientFunction(player, "delegateEvent", player, supplyQuest, "eventQuestAskExArea", gcRep[npcId]);
if (exChoice >= 3) then
deliveryMenuOpen(player, npc, 0,0,0, exChoice);
else
break;
end
end
else
callClientFunction(player, "delegateEvent", player, supplyQuest, "eventQuestCantEx",gcRep[npcId]);
end
elseif (choice == 5) then -- Requested item
deliveryStatus(player, npcGC);
else
break;
end
wait(1);
end
end
callClientFunction(player, "eventTalkStepBreak");
player:endEvent()
end
function deliveryMenuInfo(player, city, category)
local gcContents = getWeeklyItems(city, category);
local gcCurrent = getCurrentCount(city, category);
local supplyChoice = 0;
while (true) do
if gcDelivery.bonus[city][category] == 1 then -- Show fourth item if condition is met, otherwise show three.
supplyChoice = callClientFunction
(
player,
"delegateEvent",
player,
supplyQuest,
"pItem",
gcContents[1].id,
1,
gcContents[2].id,
1,
gcContents[3].id,
1,
gcContents[4].id,
1
);
else
supplyChoice = callClientFunction
(
player,
"delegateEvent",
player,
supplyQuest,
"pItem",
gcContents[1].id,
1,
gcContents[2].id,
1,
gcContents[3].id,
1,
0,
0
);
end
if supplyChoice >= 2 then
if gcCurrent[supplyChoice-1] < gcContents[supplyChoice-1].cap then
local hqPrice = math.ceil(gcContents[supplyChoice-1].seals * 1.5);
deliveryMenuOpen
(
player,
npc,
gcContents[supplyChoice-1].id,
gcContents[supplyChoice-1].seals,
hqPrice,
category
);
else
callClientFunction(player, "delegateEvent", player, supplyQuest, "pESuppylMaxErrKeyWait");
end
elseif supplyChoice == 1 then
break;
end
wait(1);
end
end
function deliveryMenuOpen(player, npc, itemId, price, hqPrice, supplyType)
callClientFunction(player, "eventQuestItemMenuOpen", itemId, price, hqPrice, supplyType);
while (true) do
local choice, quantity, quality, itemSlot, Type7Param = callClientFunction(player, "eventQuestItemMenuSelect");
if choice == false then
callClientFunction(player, "eventQuestItemMenuClose");
break;
end
--[[
player:SendMessage(0x20, "", "Choice: " .. tostring(choice));
player:SendMessage(0x20, "", "Quantity: " .. tostring(quantity));
player:SendMessage(0x20, "", "Quality: " .. tostring(quality));
player:SendMessage(0x20, "", "Slot: " .. tostring(itemSlot)); -- Broke at some point, always return 0, investigate sometime
player:SendMessage(0x20, "", "Type7Param: " .. tostring(Type7Param.slot));
--]]
pickedItem = GetItemGamedata(player:GetItemPackage(INVENTORY_NORMAL):GetItemAtSlot(Type7Param.slot).itemId).name;
player:SendMessage(0x20, "", "Player tried to deliver " .. quantity .. " " .. pickedItem);
-- TODO: Add error handling for capped seals, no-long-available-to-deliver, etc
wait(1);
end
end
function deliveryStatus(player, city)
local gcContents = getWeeklyItems(city, 1);
local gcCurrent = getCurrentCount(city, 1);
callClientFunction(player, "delegateEvent", player, supplyQuest, "pENPCAskNowTalk", gcRep[npcId]);
callClientFunction
(
player,
"delegateEvent",
player,
supplyQuest,
"nowSup",
gcContents[1].id,
gcCurrent[1],
gcContents[1].cap,
gcContents[2].id,
gcCurrent[2],
gcContents[2].cap,
gcContents[3].id,
gcCurrent[3],
gcContents[3].cap
);
if gcDelivery.bonus[city][1] == 1 then
callClientFunction
(
player,
"delegateEvent",
player,
supplyQuest,
"nowSupAddItem",
gcContents[4].id,
gcCurrent[4],
gcContents[4].cap
);
end;
gcContents = getWeeklyItems(city, 2);
gcCurrent = getCurrentCount(city, 2);
callClientFunction
(
player,
"delegateEvent",
player,
supplyQuest,
"nowSup",
gcContents[1].id,
gcCurrent[1],
gcContents[1].cap,
gcContents[2].id,
gcCurrent[2],
gcContents[2].cap,
gcContents[3].id,
gcCurrent[3],
gcContents[3].cap
);
if gcDelivery.bonus[city][2] == 1 then
callClientFunction
(
player,
"delegateEvent",
player,
supplyQuest,
"nowSupAddItem",
gcContents[4].id,
gcCurrent[4],
gcContents[4].cap
);
end;
callClientFunction(player, "delegateEvent", player, supplyQuest, "showSupplyLimit", gcDelivery.timeRemainingMinutes, gcDelivery.timeRemainingSeconds, 2, 8);
end
function getWeeklyItems(city, category)
return gcWeek[gcDelivery.week][city][category]
end
function getCurrentCount(city, category)
return gcDelivery.currentCount[city][category];
end

View file

@ -0,0 +1,120 @@
--[[
PopulaceCompanyWarp Script
Functions:
eventTalkWelcome(player) - Start Text
eventAskMainMenu(player, index) - Shows teleport menu, hides the teleport location at index value to prevent warping to the spot you're at
eventAfterWarpOtherZone(player) - Fades out for warp
eventTalkStepBreak() - Ends talk
--]]
require ("global")
warpNpc =
{ --[actorId] = {warpIndex, cityId} -- ()s around name indicate missing NPC + Aethernet
[1500321] = {1, 1}, -- (Storm Private Gardner)
[1500331] = {2, 1}, -- (Storm Private Rich)
[1500323] = {3, 1}, -- (Storm Private Potter)
[1500330] = {4, 1}, -- (Storm Private Hunt)
[1500322] = {5, 1}, -- (Storm Private Abel)
[1500332] = {6, 1}, -- (Storm Private Stone)
[1500339] = {7, 1}, -- (Storm Private Holt)
[1500324] = {1, 2}, -- serpent_private_white
[1500334] = {2, 2}, -- serpent_private_hill
[1500326] = {3, 2}, -- serpent_private_carver
[1500333] = {4, 2}, -- serpent_private_stone
[1500325] = {5, 2}, -- serpent_private_holmes
[1500335] = {6, 2}, -- serpent_private_kirk
[1500327] = {1, 3}, -- flame_private_newton
[1500337] = {2, 3}, -- (Flame Private Tanner)
[1500329] = {3, 3}, -- (Flame Private Morning)
[1500336] = {4, 3}, -- (Flame Private Covey)
[1500328] = {5, 3}, -- flame_private_allen
[1500338] = {6, 3}, -- (Flame Private Yar)
}
aethernet =
{
{ -- 1: Limsa
{zone = 230, x = -424.140, y = 42.000, z = 371.988, r = -2.472}, -- 1 - Aetheryte Plaza
{zone = 133, x = -439.744, y = 40.000, z = 234.376, r = 0.287}, -- 2 - Drowning Wench
{zone = 230, x = -498.131, y = 43.622, z = 60.818, r = 0.254}, -- 3 - The Bismarck
{zone = 230, x = -759.331, y = 12.000, z = 239.413, r = -0.869}, -- 4 - Ferry Docks
{zone = 230, x = -623.582, y = 4.000, z = 369.318, r = 1.736}, -- 5 - Fisherman's Bottom
{zone = 230, x = -525.536, y = 18.000, z = 173.735, r = 3.082}, -- 6 - The Octant
{zone = 133, x = -231.711, y = 12.000, z = 193.573, r = -0.786}, -- 7 - Procession of Terns
{zone = 128, x = -20.783, y = 42.214, z = 146.946, r = 2.046}, -- 8 - Zephyr Gate
},
{ -- 2: Gridania
{zone = 206, x = -107.878, y = 17.524, z = -1343.871, r = 0.657}, -- 1 - Aetheryte Plaza
{zone = 155, x = 96.868, y = 3.480, z = -1211.040, r = 2.582}, -- 2 - Carline Canopy
{zone = 206, x = 86.942, y = 19.789, z = -1420.891, r = 2.965}, -- 3 - Atelier Fen-Yil
{zone = 206, x = -84.621, y = 19.061, z = -1502.665, r = 0.756}, -- 4 - Whistling Miller
{zone = 206, x = 205.101, y = 9.526, z = -1245.405, r = -1.749}, -- 5 - Quiver's Hold
{zone = 206, x = 160.578, y = 25.061, z = -1556.662, r = 1.896}, -- 6 - Wailing Barracks
{zone = 150, x = 318.838, y = 4.036, z = -992.071, r = -0.307}, -- 7 - Mistalle Bridges
{zone = 206, x = -192.167, y = 4.466, z = -1061.777, r = -0.026}, -- 8 - Berlends Bridges
},
{ -- 3: Ul'dah
{zone = 175, x = -190.574, y = 190.000, z = 18.086, r = 2.190}, -- 1 - Aetheryte Plaza
{zone = 175, x = -36.513, y = 192.000, z = 37.130, r = -0.490}, -- 2 - Quicksand
{zone = 209, x = -192.971, y = 230.000, z = 209.348, r = 2.860}, -- 3 - Frondale's Phrontistery
{zone = 209, x = -60.243, y = 200.000, z = 257.718, r = -1.276}, -- 4 - Onyx Lane
{zone = 209, x = -147.633, y = 198.000, z = 160.064, r = -1.600}, -- 5 - Gold Court
{zone = 209, x = -263.776, y = 202.000, z = 206.699, r = -3.135}, -- 6 - Arrzaneth Ossuary
{zone = 170, x = -29.721, y = 182.635, z = -76.313, r = 2.625}, -- 7 - Gate of Nald
{zone = 170, x = 129.957, y = 183.862, z = 220.719, r = 1.515}, -- 8 - Gate of Thal
}
}
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
local passLimsa = 2001014;
local passGrid = 2001015;
local passUldah = 2001016;
passCheck = 1; -- 0 = Check player for Aetherpass keyitem. 1 = Ignore it.
npcId = npc:GetActorClassId();
city = warpNpc[npcId][2];
if city == 1 then
if player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(passLimsa) then
passCheck = 1;
else
if passCheck == 0 then callClientFunction(player, "eventTalkWelcome", player); end
end;
elseif city == 2 then
if player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(passGrid) then
passCheck = 1;
else
if passCheck == 0 then callClientFunction(player, "eventTalkWelcome", player); end
end;
elseif city == 3 then
if player:GetItemPackage(INVENTORY_KEYITEMS):HasItem(passUldah) then
passCheck = 1;
else
if passCheck == 0 then callClientFunction(player, "eventTalkWelcome", player); end
end
end
if passCheck == 1 then
choice = callClientFunction(player, "eventAskMainMenu", player, warpNpc[npcId][1]);
if choice == 0 then
--callClientFunction(player, "playereventTalkStepBreak");
player:EndEvent();
else
-- callClientFunction(player, "eventAfterWarpOtherZone", player); -- Commented out for now to prevent double fade-to-black for warp
player:EndEvent();
GetWorldManager():DoZoneChange(player, aethernet[city][choice].zone, nil, 0, 15, aethernet[city][choice].x, aethernet[city][choice].y, aethernet[city][choice].z, aethernet[city][choice].r);
end
end
player:EndEvent();
end

View file

@ -0,0 +1,3 @@
function init(npc)
return false, false, 0, 0;
end

View file

@ -0,0 +1,24 @@
--[[
PopulaceFlyingShip Script
Functions:
eventIn(player, hasTicket, nil?, travelPrice) - If hasTicket == nil, say no money text.
eventOut(isAborting) - Set isAborting to 30010 if player didn't "use" the airship. Shows no refund warning.
eventNG(player) - Message said when player is talking to the wrong npc.
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
callClientFunction(player, "eventIn", player, false, nil, 5);
player:EndEvent();
end

View file

@ -0,0 +1,95 @@
--[[
PopulaceGuildlevePublisher Script
Functions:
eventTalkType(level (changes factionLeves), sayIntro, brokenBladePoints, shieldsPoints, hornhandPoints, showTutorialLeves, doOmen (!=0), menuId (to Jump), leveAllowances, ?, ?, ?)
eventTalkPack(startGuildlevePack, endGuildlevePack)
eventTalkCard(card1,card2,card3,card4,card5,card6,card7,card8)
eventTalkDetail(guildLeveId, factionEvaluating, rewardType1, rewardQuantity1, rewardType2, rewardQuantity2, boostPoint, previouslyCompleted, completionBonus)
eventTalkAfterOffer()
eventHistoryleveExist(guildLeveId)
eventHistoryleveCannot()
eventGLChangeDetail(?, guildLeveId, boostPoint, rewardType1, rewardQuantity1, rewardType2, rewardQuantity2, factionEvaluating, previouslyCompleted)
eventTalkChangeOne(skipQuestion)
talkOfferMaxOver()
askRetryRegionalleve(guildLeveId, leveAllowances);
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc)
::MENU_LOOP::
menuChoice = callClientFunction(player, "eventTalkType", 0x30, true, 0x02CE, 0x356, 0x367, true, 0, nil, 0x29, 0,0,0);
--Battlecraft
if (menuChoice == 1) then
resultGLPack = callClientFunction(player, "eventTalkPack", 201, 207);
if (resultGLPack == nil) then
goto MENU_LOOP;
else
::CARDS_LOOP::
cards = {0x30C3, 0x30C4, 0x30C1, 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9};
chosenGLCard = callClientFunction(player, "eventTalkCard", cards[1], cards[2], cards[3], cards[4], cards[5], cards[6], cards[7], cards[8]);
if (chosenGLCard == -1) then
goto MENU_LOOP;
else
wasAccepted = callClientFunction(player, "eventTalkDetail", cards[chosenGLCard], 0, 0xF4242, 0xD, 0xF4242, 0, 0, true, 0);
if (wasAccepted == true) then
end
goto CARDS_LOOP;
end
end
--FieldCraft Miner
elseif (menuChoice == 0x15) then
--FieldCraft Botanist
elseif (menuChoice == 0x16) then
--FieldCraft Fisher
elseif (menuChoice == 0x17) then
--FieldCraft Quit
elseif (menuChoice == 0x18) then
--Faction Broken Blade
elseif (menuChoice == 0x29) then
--Faction Shields
elseif (menuChoice == 0x2A) then
--Faction Horn and Hand
elseif (menuChoice == 0x2B) then
--Leve Evaluation
elseif (menuChoice == 5) then
--Tutorial
elseif (menuChoice == 6) then
--End of Info
elseif (menuChoice == 7) then
--Quit
elseif (menuChoice == 8) then
end
--
--
--
player:EndEvent();
end
function onEventUpdate(player, npc, step, menuOptionSelected)
--player:RunEventFunction("eventTalkType", 0x32, true, 0x02CE, 0x356, 0x367, false, 2, nil, 0x29, 0,0,0);
player:RunEventFunction("eventTalkPack", 201, 207);
--player:RunEventFunction("eventTalkCard", 0x30C3, 0x30C4, 0x30C1, 0x30C5, 0x30C6, 0x30C7, 0x30C8, 0x30C9);
--
--player:RunEventFunction("eventGLChangeDetail", 0xDEAD, 0x30C4, 0xFF, 0xF4242, 0xD, 0xF4242, 0, 2, true);
end

View file

@ -0,0 +1,51 @@
--[[
PopulaceItemRepairer Script
Functions:
talkWelcome(player, sayWelcomeText, currentLevel?, changes 1500243 from "welcome" to "well met") - Opens the main menu
selectItem(nil, pageNumber, ?, condition1, condition2, condition3, condition4, condition5) - Select item slot.
confirmRepairItem(player, price, itemId, hq grade) - Shows the confirm box for item repair.
confirmUseFacility(player, price) - Shows confirm box for using facility. Default price is 11k?
finishTalkTurn() - Call at end to stop npc from staring at the player (eeeek)
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
result = callClientFunction(player, "talkWelcome", player, true, 20, false);
if (result == 1) then
local currentPage = 1;
local slotToRepair = nil;
while (true) do
slot, page, listIndx = callClientFunction(player, "selectItem", nil, currentPage, 4, 2, 55, 55, 55, 55);
if (slot == nil and page ~= nil) then
currentPage = page;
else
slotToRepair = slot;
break;
end
end
if (slotToRepair ~= nil) then
callClientFunction(player, "confirmRepairItem", player, 100, 8032827, 0);
end
elseif (result == 2) then
callClientFunction(player, "confirmUseFacility", player);
end
callClientFunction(player, "finishTalkTurn");
player:EndEvent();
end

View file

@ -0,0 +1,72 @@
--[[
PopulaceLinkshellManager Script
Functions:
eventTalkStep1(noLinkshellActive) - Says intro. If noLinkshellActive = true, say newbie stuff.
eventTalkStep2(noLinkshellActive) - Shows menu, if noLinkshellActive = true, only give ability to make linkshell.
eventTalkStepMakeupDone() - Confirm when creating LS
eventTalkStepModifyDone() - Confirm when modding LS
eventTalkStepBreakDone() - Confirm when deleting LS
Text IDs:
25121 - That [@SWITCH($E8(1),linkshell,company)] name is already being used.
25122 - That [@SWITCH($E8(1),linkshell,company)] name cannot be used.
25123 - The [@SWITCH($E8(1),linkshell,company)] [@STRING($EA(2))] has been [@SWITCH($E8(1),created,founded)].
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function createLinkshell(player, name, crest)
GetWorldManager():RequestWorldLinkshellCreate(player, name, crest);
return waitForSignal("ls_result");
end
function modifyLinkshell(player, name, crest)
end
function disbandLinkshell(player, name, crest)
end
function onEventStarted(player, npc, triggerName)
local hasNoActiveLS = false;
callClientFunction(player, "eventTalkStep1", hasNoActiveLS);
local command, lsName, crestId = callClientFunction(player, "eventTalkStep2", hasNoActiveLS);
--Create
if (command == 3) then
local result = createLinkshell(player, lsName, crestId);
if (result == 0) then
callClientFunction(player, "eventTalkStepMakeupDone");
elseif (result == 1) then
player:SendGameMessage(player, GetWorldMaster(), 25121, 0x20); --LS already exists
callClientFunction(player, "eventTalkStepBreakDone");
elseif (result == 2) then
player:SendGameMessage(player, GetWorldMaster(), 25122, 0x20); --Cannot use this name (reserved/banned)
callClientFunction(player, "eventTalkStepBreakDone");
elseif (result == 3) then
end
--Modify
elseif (command == 4) then
modifyLinkshell(player, lsName, crestId);
callClientFunction(player, "eventTalkStepModifyDone");
--Disband
elseif (command == 5) then
disbandLinkshell(player, lsName, crestId);
callClientFunction(player, "eventTalkStepBreakDone");
end
player:endEvent();
end

View file

@ -0,0 +1,24 @@
--[[
PopulaceNMReward Script
Functions:
eventTalkStep0(player, ?, ?) - Opens the main menu
eventTalkStep0_1(player) - "Ain't running a charity here", message said when you have insufficent funds
eventTalkStep0_2(player, hasItems) - Relic Quest dialog.
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
callClientFunction(player, "eventTalkStep0", player, 0);
player:EndEvent();
end

View file

@ -0,0 +1,38 @@
--[[
PopulacePassiveGLPublisher Script
Functions:
askOfferPack() - Show Classes
askOfferRank() - Show Ranks
askOfferQuest(player)
confirmOffer(nil, questId)
confirmMaxOffer()
talkOfferWelcome(actor, leveAllowances)
talkOfferDecide()
talkOfferMaxOver()
selectDiscardGuildleve(player)
confirmJournal()
askDiscardGuildleve()
confirmDiscardGuildleve(nil, questId)
askRetryRegionalleve(questId, leveAllowances)
finishTalkTurn()
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc)
callClientFunction(player, "talkOfferWelcome", player, 1);
player:EndEvent();
end
function onEventUpdate(player, npc, step, menuOptionSelected, lsName, lsCrest)
--callClientFunction(player, "askOfferQuest", player, 1000);
end

View file

@ -0,0 +1,28 @@
--[[
PopulaceItemRepairer Script
Functions:
INIT: speechType, townType
talkWelcome(player, bool, number, bool) - Opens the main menu
selectItem(nil, pageNumber, ?, condition1, condition2, condition3, condition4, condition5) - "Ain't running a charity here", message said when you have insufficent funds
confirmRepairItem(player, price, itemId, hq grade) - Shows the confirm box for item repair.
confirmUseFacility(player, price) - Shows confirm box for using facility. Default price is 11k?
finishTalkTurn() - Call at end to stop npc from staring at the player (eeeek)
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
result = callClientFunction(player, "eventTalkStep14");
player:EndEvent();
end

View file

@ -0,0 +1,145 @@
--[[
PopulaceRetainerManager Script
Functions:
eventTalkStep1(true) - Intro tutorial if no retainer
newEventTalkStep1(sayIntro) - Seems to be a post-Tanaka version of the intro????
eventTalkStep2() - Choose retainer yourself (go to race select) or let npc do it
eventTaklSelectCutSeane(cutsceneName, actorClassId1, actorClassId2, actorClassId3, actorClassId4, actorClassId5) - Starts the advance cutscene to choose a retainer. 5 retainer actorClassId's are given.
eventTalkStep4(actorClassId) - Opens up the retainer naming dialog
eventTalkStepFinalAnswer(actorClassId) - Confirm Dialog
eventTalkStepError(errorCode) - Error dialog, 1: No Extra Retainers, 2: Server Busy.
eventTalkStepFinish()
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
local npcActorClass = npc:GetActorClassId()
local retainerIndex = 3001100;
local cutscene = "rtn0l010" -- Defaulting to Limsa for now for testing
if npcActorClass == 1000166 then
cutscene = "rtn0l010";
retainerIndex = 3001101;
elseif npcActorClass == 1000865 then
cutscene = "rtn0u010";
retainerIndex = 3002101;
elseif npcActorClass == 1001184 then
cutscene = "rtn0g010";
retainerIndex = 3003101;
else
return;
end
introChoice = callClientFunction(player, "newEventTalkStep1", false);
if (introChoice == 1) then
-- Choose Retainer or Random
raceChoice = callClientFunction(player, "eventTalkStep2");
while (true) do
if (retainerChoice == 0) then
raceChoice = callClientFunction(player, "eventTalkStep22");
end
if (raceChoice == 0) then
--Choose random actorId from a valid set for the city
math.randomseed(os.time());
local randomRetainer = math.random(retainerIndex, (retainerIndex+74));
retainerName = callClientFunction(player, "eventTalkStep4", randomRetainer);
if (retainerName ~= "") then
confirmChoice = callClientFunction(player, "eventTalkStepFinalAnswer", randomRetainer);
if (confirmChoice == 1) then
callClientFunction(player, "eventTalkStepFinish");
player:EndEvent();
return;
elseif (confirmChoice == 3) then
raceChoice = 0;
else
player:EndEvent();
return;
end
else
callClientFunction(player, "eventTalkStepBreak");
raceChoice = -1;
end
elseif (raceChoice > 0) and (raceChoice < 16) then
--Choose 5 random but correct actor ids for the city and race/tribe
local retainerRace = ((retainerIndex) + (5*(raceChoice-1)));
local retainerRaceChoices = {retainerRace, retainerRace+1, retainerRace+2, retainerRace+3, retainerRace+4};
-- Randomize the appearance order of the available five
shuffle(retainerRaceChoices);
retainerChoice = callClientFunction(player, "eventTaklSelectCutSeane", cutscene, retainerRaceChoices[1], retainerRaceChoices[2], retainerRaceChoices[3], retainerRaceChoices[4], retainerRaceChoices[5]);
if (retainerChoice == -1) then
player:EndEvent();
return;
elseif (retainerChoice > 0) then
--Retainer chosen, choose name
retainerName = callClientFunction(player, "eventTalkStep4", retainerRaceChoices[retainerChoice]);
if (retainerName ~= "") then
confirmChoice = callClientFunction(player, "eventTalkStepFinalAnswer", retainerRaceChoices[retainerChoice]);
if (confirmChoice == 1) then
callClientFunction(player, "eventTalkStepFinish");
player:EndEvent();
return;
elseif (confirmChoice == 3) then
retainerChoice = 0;
else
player:EndEvent();
return;
end
else
callClientFunction(player, "eventTalkStepBreak");
raceChoice = -1;
end
end
else
break;
end
end
end
player:EndEvent();
end
function shuffle(tbl)
for i = #tbl, 2, -1 do
local j = math.random(i)
tbl[i], tbl[j] = tbl[j], tbl[i]
end
return tbl
end

View file

@ -0,0 +1,84 @@
--[[
PopulaceSpecialEventCryer Script
Actor Class script to handle the 6 NPCs (technically 3, the actors were duped) involved in the Foundation Day 2011 & 2012 events.
In 2011 they appear to be used for recruitment information for their respective Grand Company.
In 2012, they were used for exchanging Over-aspected Crystals/Clusters for GC seals as part of the ongoing Atomos event.
Functions:
For 2011.
eventTalkStep0(joined) - NPC dialog about joining their cause to fight back Imperials. joined = 0 or 1. Function has hardcoded actor IDs, won't work with 2012 versions
eventTalkNotGCmenber(npcGC) - NPC dialog when you're not part of their grand company.
For 2012.
eventTalkCrystalExchange(player, npcGC, hasCrystal) - NPC dialog explaining they want over-aspected crystals. Brings up crystal exchange prompt if hasCrystal = 1.
eventTalkCsOverflow(player, npcGC) - Error message that you can't hold the seals being offered.
eventTalkCrystalExchange2(player, npcGC) - NPC dialog for accepting exchange of crystals for seals
--]]
require ("global")
function init(npc)
return false, false, 0, 0;
end
local gcRep = {
[1001619] = 1, -- Maelstrom Representative 2011
[1002105] = 1, -- Maelstrom Representative 2012
[1001623] = 2, -- Adder Representative 2011
[1002109] = 2, -- Adder Representative 2012
[1001627] = 3, -- Flame Representative 2011
[1002113] = 3, -- Flame Representative 2012
}
function onEventStarted(player, npc, triggerName)
local playerGC = player.gcCurrent;
local npcId = npc:GetActorClassId();
local npcGC = gcRep[npcId];
local npcGCSeal = 1000200 + npcGC;
local hasCrystal = 1;
local crystal = 3020537;
local cluster = 3020413;
local eventMode = 2012;
if eventMode == 2011 then
if playerGC == 0 then
callClientFunction(player, "eventTalkStep0", 0);
elseif playerGC == npcGC then
callClientFunction(player, "eventTalkStep0", 1);
else
callClientFunction(player, "eventTalkNotGCmenber", npcGC);
end
elseif eventMode == 2012 then
choice = callClientFunction(player, "eventTalkCrystalExchange", player, npcGC, hasCrystal);
if choice == 1 then
--callClientFunction(player, "eventTalkCsOverflow", player, npcGC);
player:SendMessage(0x20, "", "You pretend to hand over four over-aspected crystals.");
callClientFunction(player, "eventTalkCrystalExchange2", player, npcGC);
local invCheck = player:GetItemPackage(INVENTORY_CURRENCY):AddItem(npcGCSeal, 1000, 1);
if invCheck == INV_ERROR_SUCCESS then
player:SendGameMessage(player, GetWorldMaster(), 25071, MESSAGE_TYPE_SYSTEM, crystal, 1, npcGCSeal, 1, 4, 1000);
end
elseif choice == 2 then
player:SendMessage(0x20, "", "You pretend to hand over an over-aspected cluster.");
--callClientFunction(player, "eventTalkCsOverflow", player, npcGC);
callClientFunction(player, "eventTalkCrystalExchange2", player, npcGC);
local invCheck = player:GetItemPackage(INVENTORY_CURRENCY):AddItem(npcGCSeal, 3000, 1);
if invCheck == INV_ERROR_SUCCESS then
player:SendGameMessage(player, GetWorldMaster(), 25071, MESSAGE_TYPE_SYSTEM, cluster, 1, npcGCSeal, 1, 1, 3000);
end
end
end
player:EndEvent();
end

View file

@ -0,0 +1,13 @@
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc)
player:SendMessage(0x20, "", "This PopulaceStandard actor has no event set. Actor Class Id: " .. tostring(npc:GetActorClassId()));
player:EndEvent();
end
function onEventUpdate(player, npc, blah, menuSelect)
player:EndEvent();
end

View file

@ -0,0 +1,107 @@
--[[
PopulaceGuildShop Script
In 1.20, the devs removed Guild Marks as acquirable. In 1.21, this class was set up to allow exchanging them for
a variety of materia/crystals/gil, as well as refunding traits purchased with marks. Traits used to be purchased
to slot in, where-as with late-XIV they are just automatically unlocked once the appropriate level is met.
Functions:
cashbackTalkCommand(arg1 through arg10) -- Dialog for refunding purchased skills prior to Job update. Args are xtx_command values for command names.
cashbackTalk(nil, refundAmount, arg3 through arg10) -- Dialog for refunding treaties to guild marks. Arg3 through 10 use xtx_itemName values.
selectMode(nil, npcId, isShowExchange, guildCurrency, unk) -- Menus for exchanging leftover marks, undoing class points, and learning about guild. Unk seems related to point resetting
maskShopListIndex(shopPack?, isSomething) -- Presumably hides an item in the shop list. Needs to be called after openShopBuy or errors client.
guildExplain(npcId, player) -- Guild Mark tutorial dialog. selectMode calls this on its own
--]]
require ("global")
require ("shop")
function init(npc)
return false, false, 0, 0;
end
guildShopInfo = { -- [actor id] = { saySheetId, guildmarkCurrency }
[1000157] = {9, 1000103}, -- Marauder, S'raemha
[1000158] = {24, 1000120}, -- Culinarian, Noline
[1000162] = {18, 1000114}, -- Blacksmith, Qhas Chalahko
[1000164] = {16, 1000123}, -- Fishermen, Faucillien
[1000459] = {21, 1000117}, -- Leatherworker, Gallia
[1000460] = {13, 1000111}, -- Conjurer, Hetzkin
[1000461] = {15, 1000122}, -- Botanist, Kipopo
[1000462] = {11, 1000107}, -- Lancer, Clarembald
[1000464] = {10, 1000106}, -- Archer, Cassandra
[1000466] = {17, 1000113}, -- Carpenter, Frances
[1000631] = {8, 1000102}, -- Gladiator, Coynach
[1000632] = {7, 1000101}, -- Pugilist, Moruith
[1000633] = {12, 1000110}, -- Thaumaturge, Nyunoeya
[1000634] = {23, 1000119}, -- Alchemist, Kylene
[1000635] = {20, 1000116}, -- Goldsmith, Hnaufrid
[1000636] = {22, 1000118}, -- Weaver, Lafla Morfla
[1000637] = {14, 1000121}, -- Miner, Shilgen
[1001461] = {19, 1000115}, -- Armorer, Notrelchamps
}
function onEventStarted(player, npc)
local npcId = npc:GetActorClassId();
local saySheetId = guildShopInfo[npcId][1];
local shopCurrency = guildShopInfo[npcId][2];
local gilCurrency = 1000001;
local keepersHymn = 3020410;
local shopPack = 0;
callClientFunction(player, "welcomeTalk", nil, saySheetId, player);
while (true) do
local choice = callClientFunction(player, "selectMode", nil, npcId, true, shopCurrency, 100);
if (choice == 3) then -- Undo Point Allotment
-- TODO: Add point reset handling
elseif (choice == 4) then -- Leave menu selected
player:EndEvent();
break;
elseif (choice == nil) then -- Escape key hit to leave menu
player:EndEvent();
break
elseif (choice >= 102 and choice <= 120) then -- Exchange marks for Materia
shopPack = choice + 18; -- Index offset
if (choice == 119) then
shopPack = shopPack + 1;
elseif (choice == 120) then -- Exchange marks for Crystals
shopPack = 144;
end;
processGuildShop(player, shopPack, shopCurrency);
elseif (choice == 121) then -- Exchange marks for Gil. 1 mark = 4 gil
local markAmount = player:GetItemPackage(INVENTORY_CURRENCY):GetItemQuantity(shopCurrency);
purchaseItem(player, INVENTORY_CURRENCY, gilCurrency, markAmount*4, 1, markAmount, shopCurrency);
end
end
player:EndEvent()
end
function processGuildShop(player, choice, currency)
callClientFunction(player, "openShopBuy", player, choice, currency);
--callClientFunction(player, "maskShopListIndex", 137, true);
while (true) do
buyResult, quantity = callClientFunction(player, "selectShopBuy", player);
if (buyResult == 0) then
callClientFunction(player, "closeShopBuy", player);
break;
else
player:SendMessage(0x20, "", string.format("Player purchased %s item(s) at index %s in shopPack %s.", quantity, buyResult, choice));
end
end
end

View file

@ -0,0 +1,290 @@
--[[
PopulaceShopSalesman Script
Functions:
welcomeTalk(sheetId, player) - Start Message
selectMode(askMode) - Shows buy/sell modes. If askmode > 0 show guild tutorial. If askmode == -7/-8/-9 show nothing. Else show affinity/condition tutorials.
selectModeOfClassVendor() - Opens categories for class weapons and gear
selectModeOfMultiWeaponVendor(consumptionTutorialId) - Opens categories for weapons/tools (war/magic/land/hand). Arg consumptionTutorialId appends location of item repair person. -1: Ul'dah, -2: Gridania, -3: Limsa
selectModeOfMultiArmorVendor(consumptionTutorialId) - Opens categories for armor in different slots. Arg consumptionTutorialId appends location of item repair person. -1: Ul'dah, -2: Gridania, -3: Limsa
openShopBuy(player, shopPack, currancyItemId) - ShopPack: Items to appear in window. CurrancyItemId: What is being used to buy these items.
selectShopBuy(player) - Call after openShopBuy() to open widget
closeShopBuy(player) - Closes the buy window
openShopSell(player) - Call this to open sell window
selectShopSell(player) - Call after openShopSell()
closeShopSell(player) - Closes the sell window
confirmSellingItem(itemId, quality, quantity, gil) - Simple Sell confirmation window
selectFacility(?, sheetId, 3) - Opens the facility chooser.
confirmUseFacility(player, cost) - Facility cost confirm
informSellPrice(1, chosenItem, price) - Shows sell confirm window. ChosenItem must be correct.
startTutorial(nil, tutorialId) - Opens up a tutorial menu for each guild type based on tutorialId
finishTalkTurn() - Done at the end.
--]]
require ("global")
require ("shop")
shopInfo = { -- [actorclass id] = { welcomeText, shopMode, shopPack{s} }
[1000159] = {34, 0, 1016},
[1000163] = {49, 0, 1017},
[1000165] = {74, 0, 1019},
[1001458] = {44, 0, 1018},
[1500405] = {320, 0, 1013},
[1500407] = {321, 0, 1012},
[1500411] = {322, 0, 2017},
[1500414] = {324, 0, 1012},
[1500419] = {327, 0, 1012},
[1500422] = {332, 0, 1013},
[1500423] = {331, 0, 2017},
[1500429] = {328, 0, 2017},
[1500430] = {281, 0, 5121},
[1600001] = {6, 0, 1006},
[1600002] = {7, 0, 1007},
[1600003] = {8, 0, 1008},
[1600004] = {9, 0, 1009},
[1600005] = {10, 0, 1010},
[1600006] = {11, 0, 1011},
[1600007] = {12, 0, 1012},
[1600008] = {13, 0, 1013},
[1600009] = {14, 0, 1014},
[1600010] = {15, 0, 1015},
[1600011] = {1, 0, 1001},
[1600012] = {2, 0, 1002},
[1600013] = {3, 0, 1003},
[1600014] = {4, 0, 1004},
[1600016] = {5, 0, 1005},
[1600017] = {39, 0, 2020},
[1600018] = {59, 0, 2021},
[1600019] = {75, 0, 2022},
[1600020] = {77, 0, 2010},
[1600021] = {78, 0, 2011},
[1600022] = {79, 0, 2012},
[1600023] = {80, 0, 2013},
[1600024] = {81, 0, 2014},
[1600025] = {82, 0, 2015},
[1600026] = {83, 0, 2016},
[1600027] = {84, 0, 2017},
[1600028] = {85, 0, 2018},
[1600029] = {86, 0, 2019},
[1600030] = {87, 0, 2001},
[1600031] = {88, 0, 2003},
[1600032] = {89, 0, 2002},
[1600033] = {90, 0, 2004},
[1600034] = {91, 0, 2005},
[1600035] = {92, 0, 2006},
[1600036] = {93, 0, 2007},
[1600037] = {94, 0, 2008},
[1600039] = {69, 0, 3020},
[1600040] = {54, 0, 3019},
[1600041] = {64, 0, 3021},
[1600042] = {76, 0, 3022},
[1600043] = {96, 0, 3009},
[1600044] = {97, 0, 3010},
[1600045] = {98, 0, 3011},
[1600046] = {99, 0, 3012},
[1600047] = {100, 0, 3013},
[1600048] = {101, 0, 3014},
[1600049] = {102, 0, 3016},
[1600050] = {103, 0, 3015},
[1600051] = {104, 0, 3017},
[1600052] = {105, 0, 3004},
[1600053] = {106, 0, 3007},
[1600054] = {107, 0, 3018},
[1600055] = {108, 0, 3006},
[1600056] = {109, 0, 3005},
[1600057] = {110, 0, 3002},
[1600058] = {111, 0, 3003},
[1600059] = {112, 0, 3001},
[1600064] = {235, 0, 2023},
[1600066] = {237, 0, 3023},
[1600075] = {245, 1, {5021,5022,5023,5024,5025,5026} },
[1600076] = {247, 1, {5027,5028,5029,5030,5031,5032} },
[1600077] = {248, 1, {5033,5034,5035,5036,5037,5038} },
[1600080] = {251, 1, {5051,5052,5053,5054,5055,5056} },
[1600081] = {255, 1, {5075,5076,5077,5078,5079,5080} },
[1600089] = {260, 1, {5105,5106,5107,5108,5109,5110} },
[1600092] = {263, 0, 2024},
[1600094] = {265, 0, 3024},
[1600100] = {281, 2, {5001, 5002, 5007, 5008} },
}
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, npc, triggerName)
-- require("/unique/".. npc.zone.zoneName .."/PopulaceShopSalesman/" .. npc:GetUniqueId())
npcId = npc:GetActorClassId();
if shopInfo[npcId] == nil then
errorMsg = string.format("This PopulaceShopSalesman actor has no shop set. Actor Class Id: %s", npcId);
player:SendMessage(MESSAGE_TYPE_SYSTEM_ERROR, "", errorMsg );
player:EndEvent();
return;
end;
shopCurrancy = 1000001;
callClientFunction(player, "welcomeTalk", shopInfo[npcId][1], player);
if npcId == 1000159 then -- DoH Guild NPCs with Facility menu
tutorialId = 36;
elseif npcId == 1000163 then
tutorialId = 31;
elseif npcId == 1001458 then
tutorialId = 30;
elseif npcId == 1600017 then
tutorialId = 29;
elseif npcId == 1600018 then
tutorialId = 33;
elseif npcId == 1600039 then
tutorialId = 35;
elseif npcId == 1600040 then
tutorialId = 32;
elseif npcId == 1600041 then
tutorialId = 34;
else
tutorialId = -8;
end
while (true) do
if (shopInfo[npcId][2] == 0) then
choice = callClientFunction(player, "selectMode", tutorialId);
elseif (shopInfo[npcId][2] == 1) then
choice = callClientFunction(player, "selectModeOfClassVendor");
elseif (shopInfo[npcId][2] == 2) then
choice = callClientFunction(player, "selectModeOfMultiWeaponVendor", tutorialId);
elseif (shopInfo[npcId][2] == 3) then
choice = callClientFunction(player, "selectModeOfMultiArmorVendor", tutorialId);
end
if (choice == nil or choice == -3) then
break;
end
if (shopInfo[npcId][2] == 0) then
processNormalShop(player, choice);
elseif (shopInfo[npcId][2] == 1) then
processMultiShop(player, choice);
elseif (shopInfo[npcId][2] == 2) then
processMultiShop(player, choice);
elseif (shopInfo[npcId][2] == 3) then
processMultiShop(player, choice);
end
end
callClientFunction(player, "finishTalkTurn", player);
player:EndEvent();
end
function processNormalShop(player, choice)
if (choice == 1) then
callClientFunction(player, "openShopBuy", player, shopInfo[npcId][3], shopCurrancy);
while (true) do
buyResult, quantity = callClientFunction(player, "selectShopBuy", player);
if (buyResult == 0) then
callClientFunction(player, "closeShopBuy", player);
break;
else
-- purchaseItem(player, shopInfo.shopContents[buyResult].id, quantity, shopInfo.shopContents[buyResult].hq, shopInfo.shopContents[buyResult].gil, shopInfo.shopCurrancy);
end
end
elseif (choice == 2) then
openSellMenu(player);
elseif (choice == 3) then
local classFacility = (shopInfo[npcId][1] + 1) or 35;
facilityChoice = callClientFunction(player, "selectFacility", nil, classFacility, 3);
if facilityChoice == 1 then
callClientFunction(player, "confirmUseFacility", player, 200);
elseif facilityChoice == 2 then
callClientFunction(player, "confirmUseFacility", player, 400);
elseif facilityChoice == 3 then
callClientFunction(player, "confirmUseFacility", player, 1000);
end
elseif (choice == 4) then
callClientFunction(player, "startTutorial", nil, tutorialId);
end
end
function processMultiShop(player, choice, sellType)
if (choice >= 1 and choice <= 6) then
callClientFunction(player, "openShopBuy", player, shopInfo[npcId][3][choice], shopCurrancy);
while (true) do
buyResult, quantity = callClientFunction(player, "selectShopBuy", player);
if (buyResult == 0) then
callClientFunction(player, "closeShopBuy", player);
break;
else
-- purchaseItem(player, shopInfo.shopContents[choice][buyResult].id, quantity, shopInfo.shopContents[choice][buyResult].hq, shopInfo.shopContents[choice][buyResult].gil, shopInfo.shopCurrancy);
end
end
elseif (choice == 0) then
openSellMenu(player);
elseif (choice == 6) then
callClientFunction(player, "selectFacility", 2, 35, 3);
callClientFunction(player, "confirmUseFacility", player, 35);
elseif (choice == 7) then
callClientFunction(player, "startTutorial", nil, tutorialId);
end
end
function openSellMenu(player)
callClientFunction(player, "openShopSell", player);
while (true) do
sellResult, sellQuantity, sellState, unknown, sellItemSlot = callClientFunction(player, "selectShopSell", player);
if (sellResult == nil) then
callClientFunction(player, "closeShopSell", player);
break;
else
if sellState == 1 then
itemToSell = player:GetItemPackage(INVENTORY_NORMAL):GetItemAtSlot(sellItemSlot-1);
gItemSellId = itemToSell.itemId;
gItemQuality = itemToSell.quality;
gItemPrice = GetItemGamedata(gItemSellId);
gItemPrice = gItemPrice.sellPrice;
if gItemQuality == 2 then -- +1
gItemPrice = (math.floor(gItemPrice * 1.10));
elseif gItemQuality == 3 then -- +2
gItemPrice = (math.floor(gItemPrice * 1.25));
elseif gItemQuality == 4 then -- +3
gItemPrice = (math.floor(gItemPrice * 1.50));
end
callClientFunction(player, "informSellPrice", 1, sellItemSlot, gItemPrice);
elseif sellState == nil then
sellItem(player, gItemSellId, sellQuantity, gItemQuality, gItemPrice, sellItemSlot-1, shopCurrancy);
end
end
end
end

View file

@ -0,0 +1,46 @@
--[[
OrdinaryRetainer Script
Functions:
eventTalkRetainerOther() -
eventTalkRetainerMenu(mode, hasPossessions) - Opens the main menu. If mode == 2, hide dismiss option.
eventTalkRetainerDismissal(hasPossessions) - Show dismiss confirmation.
eventTalkRetainerMannequin(0:enable/1:disable confirm) - Show bazaar modeling confirmation.
eventTalkRetainerItemTrade(operationCode) - Operate RetainerTradeWidget. Codes: 1 - Open, 2 - Select Mode, 3 - Close.
eventTalkRetainerItemList(operationCode) - Operate Bazaar Widget. Codes: 1 - Open, 2 - Select Mode, 3 - Close.
eventReturnResult(resultCode, ?) - Redraws the RetainerTrade UI.
sayToPlayer(actorClassId, messageType, argument) - Makes the retainer say a phrase to the player.
eventTalkFinish() - Stops npc from looking at player.
eventPlayerTurn(angle) - Turns player to angle.
--]]
require ("global")
require ("retainer")
function init(npc)
return false, false, 0, 0;
end
function onEventStarted(player, retainer, triggerName)
while (true) do
choice = callClientFunction(player, "eventTalkRetainerMenu", 1);
if (choice == 1) then
doItemTrade(player, retainer);
elseif (choice == 2) then
doBazaar(player, retainer);
elseif (choice == 7) then
callClientFunction(player, "eventTalkRetainerMannequin", 0);
elseif (choice == 5) then
player:DespawnMyRetainer();
else
break;
end
end
player:EndEvent();
end

175
Data/scripts/battlenpc.lua Normal file
View file

@ -0,0 +1,175 @@
local initClassItems, initRaceItems;
function onBeginLogin(player)
--New character, set the initial quest
if (player:GetPlayTime(false) == 0) then
initialTown = player:GetInitialTown();
if (initialTown == 1 and player:HasQuest(110001) == false) then
player:AddQuest(110001);
player:SetHomePoint(1280001);
elseif (initialTown == 2 and player:HasQuest(110005) == false) then
player:AddQuest(110005);
player:SetHomePoint(1280061);
elseif (initialTown == 3 and player:HasQuest(110009) == false) then
player:AddQuest(110009);
player:SetHomePoint(1280031);
end
end
--For Opening. Set Director and reset position incase d/c
if (player:HasQuest(110001) == true and player:GetZoneID() == 193) then
director = player:GetZone():CreateDirector("OpeningDirector", false);
player:AddDirector(director);
director:StartDirector(true);
player:SetLoginDirector(director);
player:KickEvent(director, "noticeEvent", true);
player.positionX = 0.016;
player.positionY = 10.35;
player.positionZ = -36.91;
player.rotation = 0.025;
player:GetQuest(110001):ClearQuestData();
player:GetQuest(110001):ClearQuestFlags();
elseif (player:HasQuest(110005) == true and player:GetZoneID() == 166) then
director = player:GetZone():CreateDirector("OpeningDirector", false);
player:AddDirector(director);
director:StartDirector(false);
player:SetLoginDirector(director);
player:KickEvent(director, "noticeEvent", true);
player.positionX = 369.5434;
player.positionY = 4.21;
player.positionZ = -706.1074;
player.rotation = -1.26721;
player:GetQuest(110005):ClearQuestData();
player:GetQuest(110005):ClearQuestFlags();
elseif (player:HasQuest(110009) == true and player:GetZoneID() == 184) then
--director = player:GetZone():CreateDirector("OpeningDirector", false);
--player:AddDirector(director);
--director:StartDirector(false);
--player:SetLoginDirector(director);
--player:KickEvent(director, "noticeEvent", true);
--
player.positionX = 5.364327;
player.positionY = 196.0;
player.positionZ = 133.6561;
player.rotation = -2.849384;
player:GetQuest(110009):ClearQuestData();
player:GetQuest(110009):ClearQuestFlags();
end
end
function onLogin(player)
if (player:GetPlayTime(false) == 0) then
player:SendMessage(0x1D,"",">PlayTime == 0, new player!");
initClassItems(player);
initRaceItems(player);
player:SavePlayTime();
end
end
function initClassItems(player)
local slotTable;
local invSlotTable;
--DoW
if (player.charaWork.parameterSave.state_mainSkill[0] == 2) then --PUG
player:GetItemPackage(0):AddItem({4020001, 8030701, 8050728, 8080601, 8090307});
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 3) then --GLA
player:GetItemPackage(0):AddItem({4030010, 8031120, 8050245, 8080601, 8090307});
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 4) then --MRD
player:GetItemPackage(0):AddItem({4040001, 8011001, 8050621, 8070346, 8090307});
player:GetEquipment():SetEquipment({0, 8, 12, 13, 15},{0, 1, 2, 3, 4});
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 7) then --ARC
player:GetItemPackage(0):AddItem({4070001, 8030601, 8050622, 8080601, 8090307});
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 8) then --LNC
player:GetItemPackage(0):AddItem({4080201, 8030801, 8051015, 8080501, 8090307});
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
--DoM
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 22) then --THM
player:GetItemPackage(0):AddItem({5020001, 8030245, 8050346, 8080346, 8090208});
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 23) then --CNJ
player:GetItemPackage(0):AddItem({5030101, 8030445, 8050031, 8080246, 8090208});
player:GetEquipment():SetEquipment({0, 10, 12, 14, 15},{0, 1, 2, 3, 4});
--DoH
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 29) then --
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 30) then --
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 31) then --
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 32) then --
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 33) then --
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 34) then --
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 35) then --
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 36) then --
--DoL
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 39) then --MIN
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 40) then --BTN
elseif (player.charaWork.parameterSave.state_mainSkill[0] == 41) then --FSH
end
end
function initRaceItems(player)
if (player.playerWork.tribe == 1) then --Hyur Midlander Male
player:GetItemPackage(0):AddItem(8040001);
player:GetItemPackage(0):AddItem(8060001);
elseif (player.playerWork.tribe == 2) then --Hyur Midlander Female
player:GetItemPackage(0):AddItem(8040002);
player:GetItemPackage(0):AddItem(8060002);
elseif (player.playerWork.tribe == 3) then --Hyur Highlander Male
player:GetItemPackage(0):AddItem(8040003);
player:GetItemPackage(0):AddItem(8060003);
elseif (player.playerWork.tribe == 4) then --Elezen Wildwood Male
player:GetItemPackage(0):AddItem(8040004);
player:GetItemPackage(0):AddItem(8060004);
elseif (player.playerWork.tribe == 5) then --Elezen Wildwood Female
player:GetItemPackage(0):AddItem(8040006);
player:GetItemPackage(0):AddItem(8060006);
elseif (player.playerWork.tribe == 6) then --Elezen Duskwight Male
player:GetItemPackage(0):AddItem(8040005);
player:GetItemPackage(0):AddItem(8060005);
elseif (player.playerWork.tribe == 7) then --Elezen Duskwight Female
player:GetItemPackage(0):AddItem(8040007);
player:GetItemPackage(0):AddItem(8060007);
elseif (player.playerWork.tribe == 8) then --Lalafell Plainsfolk Male
player:GetItemPackage(0):AddItem(8040008);
player:GetItemPackage(0):AddItem(8060008);
elseif (player.playerWork.tribe == 9) then --Lalafell Plainsfolk Female
player:GetItemPackage(0):AddItem(8040010);
player:GetItemPackage(0):AddItem(8060010);
elseif (player.playerWork.tribe == 10) then --Lalafell Dunesfolk Male
player:GetItemPackage(0):AddItem(8040009);
player:GetItemPackage(0):AddItem(8060009);
elseif (player.playerWork.tribe == 11) then --Lalafell Dunesfolk Female
player:GetItemPackage(0):AddItem(8040011);
player:GetItemPackage(0):AddItem(8060011);
elseif (player.playerWork.tribe == 12) then --Miqo'te Seekers of the Sun
player:GetItemPackage(0):AddItem(8040012);
player:GetItemPackage(0):AddItem(8060012);
elseif (player.playerWork.tribe == 13) then --Miqo'te Seekers of the Moon
player:GetItemPackage(0):AddItem(8040013);
player:GetItemPackage(0):AddItem(8060013);
elseif (player.playerWork.tribe == 14) then --Roegadyn Sea Wolf
player:GetItemPackage(0):AddItem(8040014);
player:GetItemPackage(0):AddItem(8060014);
elseif (player.playerWork.tribe == 15) then --Roegadyn Hellsguard
player:GetItemPackage(0):AddItem(8040015);
player:GetItemPackage(0):AddItem(8060015);
end
player:GetEquipment():SetEquipment({9, 11},{5,6});
end

View file

@ -0,0 +1,107 @@
CommandType =
{
None = 0,
AutoAttack = 1,
Weaponskill = 2,
Ability = 3,
Spell = 4
}
ActionType =
{
None = 0,
Physical = 1,
Magic = 2,
Heal = 3,
Status = 4
}
ActionProperty =
{
None = 0,
Physical = 1,
Magic = 2,
Heal = 4,
Status = 8,
Ranged = 16
}
DamageTakenType =
{
None,
Attack,
Magic,
Weaponskill,
Ability
}
HitDirection =
{
None = 0,
Front = 1,
Right = 2,
Rear = 4,
Left = 8
}
HitType =
{
Miss = 0,
Evade = 1,
Parry = 2,
Block = 3,
Resist = 4,
Hit = 5,
Crit = 6
}
TargetFindAOEType =
{
None = 0,
Circle = 1,
Cone = 2,
Box = 3
}
StatusEffectFlags =
{
None = 0,
--Loss flags - Do we need loseonattacking/caststart? Could just be done with activate flags
LoseOnDeath = bit32.lshift(1, 0), -- effects removed on death
LoseOnZoning = bit32.lshift(1, 1), -- effects removed on zoning
LoseOnEsuna = bit32.lshift(1, 2), -- effects which can be removed with esuna (debuffs)
LoseOnDispel = bit32.lshift(1, 3), -- some buffs which player might be able to dispel from mob
LoseOnLogout = bit32.lshift(1, 4), -- effects removed on logging out
LoseOnAttacking = bit32.lshift(1, 5), -- effects removed when owner attacks another entity
LoseOnCastStart = bit32.lshift(1, 6), -- effects removed when owner starts casting
LoseOnAggro = bit32.lshift(1, 7), -- effects removed when owner gains enmity (swiftsong)
LoseOnClassChange = bit32.lshift(1, 8), --Effect falls off whhen changing class
--Activate flags
ActivateOnCastStart = bit32.lshift(1, 9), --Activates when a cast starts.
ActivateOnCommandStart = bit32.lshift(1, 10), --Activates when a command is used, before iterating over targets. Used for things like power surge, excruciate.
ActivateOnCommandFinish = bit32.lshift(1, 11), --Activates when the command is finished, after all targets have been iterated over. Used for things like Excruciate and Resonance falling off.
ActivateOnPreactionTarget = bit32.lshift(1, 12), --Activates after initial rates are calculated for an action against owner
ActivateOnPreactionCaster = bit32.lshift(1, 13), --Activates after initial rates are calculated for an action by owner
ActivateOnDamageTaken = bit32.lshift(1, 14),
ActivateOnHealed = bit32.lshift(1, 15),
--Should these be rolled into DamageTaken?
ActivateOnMiss = bit32.lshift(1, 16), --Activates when owner misses
ActivateOnEvade = bit32.lshift(1, 17), --Activates when owner evades
ActivateOnParry = bit32.lshift(1, 18), --Activates when owner parries
ActivateOnBlock = bit32.lshift(1, 19), --Activates when owner evades
ActivateOnHit = bit32.lshift(1, 20), --Activates when owner hits
ActivateOnCrit = bit32.lshift(1, 21), --Activates when owner crits
--Prevent flags. Sleep/stun/petrify/etc combine these
PreventSpell = bit32.lshift(1, 22), -- effects which prevent using spells, such as silence
PreventWeaponSkill = bit32.lshift(1, 23), -- effects which prevent using weaponskills, such as pacification
PreventAbility = bit32.lshift(1, 24), -- effects which prevent using abilities, such as amnesia
PreventAttack = bit32.lshift(1, 25), -- effects which prevent basic attacks
PreventMovement = bit32.lshift(1, 26), -- effects which prevent movement such as bind, still allows turning in place
PreventTurn = bit32.lshift(1, 27), -- effects which prevent turning, such as stun
PreventUntarget = bit32.lshift(1, 28), -- effects which prevent changing targets, such as fixation
Stance = bit32.lshift(1, 29) -- effects that do not have a timer
}

View file

@ -0,0 +1,19 @@
require ("global")
require ("utils")
--[[
AttackWeaponSkill Script
Finds the correct weaponskill subscript to fire when a weaponskill actor is activated.
--]]
local attackMagicHandlers = {
}
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
player.Ability(command.actorId, targetActor);
player:endEvent();
end

View file

@ -0,0 +1,5 @@
require("global")
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
end

View file

@ -0,0 +1,20 @@
require ("global")
--[[
ActivateCommand Script
Switches between active and passive mode states
--]]
function onEventStarted(player, command, triggerName)
if (player.currentMainState == 0x0000) then
player.Engage(0, 0x0002);
elseif (player.currentMainState == 0x0002) then
player.Disengage(0x0000);
end
player:endEvent();
sendSignal("playerActive");
end;

View file

@ -0,0 +1,20 @@
require ("global")
require ("utils")
--[[
AttackWeaponSkill Script
Finds the correct weaponskill subscript to fire when a weaponskill actor is activated.
--]]
local attackMagicHandlers = {
}
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
player.Ability(command.actorId, targetActor);
player:endEvent();
end

View file

@ -0,0 +1,19 @@
require ("global")
require ("utils")
--[[
AttackWeaponSkill Script
Finds the correct weaponskill subscript to fire when a weaponskill actor is activated.
--]]
local attackMagicHandlers = {
}
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
player.Cast(command.actorId, targetActor);
player:endEvent();
end;

View file

@ -0,0 +1,26 @@
require ("global")
require ("utils")
--[[
AttackWeaponSkill Script
Finds the correct weaponskill subscript to fire when a weaponskill actor is activated.
--]]
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
--Are they in active mode?
if (player:GetState() != 2) then
player:SendGameMessage(GetWorldMaster(), 32503, 0x20);
player:endEvent();
return;
end
if not player.aiContainer.IsEngaged() then
player.Engage(targetActor);
end;
player.WeaponSkill(command.actorId, targetActor);
player:endEvent();
end;

View file

@ -0,0 +1,30 @@
--[[
BazaarCheckCommand Script
Handles what happens when you examine a player's bazaar
--]]
require ("global")
function onEventStarted(player, actor, triggerName, name, arg1, arg2, arg3, bazaarActorId)
local bazaarActor = nil;
if (name ~= nil) then
bazaarActor = player:GetZone():FindPCInZone(name);
elseif (bazaarActorId ~= nil) then
bazaarActor = player:GetZone():FindActorInArea(bazaarActorId);
end
if (bazaarActor ~= nil) then
player:SendMessage(MESSAGE_TYPE_SYSTEM_ERROR, "", "Currently disabled due to freezing characters.");
--callClientFunction(player, "delegateCommand", GetStaticActor("BazaarCheckCommand"), "processChackBazaar");
else
--Show error
end
player:EndEvent();
end

View file

@ -0,0 +1,58 @@
--[[
BazaarDealCommand Script
Handles various bazaar transfer options
All bazaar args have a Reward (The item the person who fufills the request gets) and a Seek (The item the player wants, either gil or an item).
Args:
rewardItem: Item reference to what will be given to the buyer. If it's gil the itemID will be given instead. If offering an item to seek; reward/seek are combined and put here.
seekItem: Item reference to what the buyer will give us. If it's gil the itemID will be given instead,
bazaarMode: The tag value to set in the bazaar item's data.
arg1: Always nil
bazaarActor: The actor who owns this bazaar
rewardAmount: The amount of rewardItem the buyer will get.
seekAmount: The amount of seekItem we want.
--]]
require ("global")
function onEventStarted(player, actor, triggerName, rewardItem, seekItem, bazaarMode, arg1, bazaarActor, rewardAmount, seekAmount, arg2, arg3, type9ItemIds)
local rewarding = nil;
local seeking = nil;
--Handle special case for offering an item.
if (seekItem == nil) then
rewarding = player:GetItemPackage(rewardItem.offerPackageId):GetItemAtSlot(rewardItem.offerSlot);
seeking = player:GetItemPackage(rewardItem.seekPackageId):GetItemAtSlot(rewardItem.seekSlot);
end
--Handle Reward
if (rewarding == nil) then
if (type(rewardItem) == "number") then
rewarding = player:GetItemPackage(INVENTORY_CURRENCY):GetItemByCatelogId(rewardItem);
else
rewarding = player:GetItem(rewardItem);
end
end
--Handle Seek
if (seeking == nil) then
if (type(seekItem) == "number") then
seeking = player:GetItemPackage(INVENTORY_CURRENCY):GetItemByCatelogId(seekItem);
else
seeking = player:GetItem(seekItem);
end
end
result = GetWorldManager():AddToBazaar(player, rewarding, seeking, rewardAmount, seekAmount, bazaarMode);
player:EndEvent();
end

View file

@ -0,0 +1,55 @@
--[[
BazaarTradeCommand Script
Handles bazaar trade
All bazaar args have a Reward (The item the person who fufills the request gets) and a Seek (The item the player wants, either gil or an item).
--]]
--TODO REFACTOR
function onEventStarted(player, actor, triggerName, rewardItem, seekItemOrCost, seekAmount, arg1, bazaarActorId, rewardAmount, rewardItemId, nameIndex, arg2, type9ItemIds)
local originalReward = nil;
local originalSeek = nil;
local bazaarActor = nil;
--Get the bazaar actor
if (bazaarActorId ~= nil) then
bazaarActor = player:GetZone():FindActorInArea(bazaarActorId);
end
--Abort if no actor
if (bazaarActor == nil) then
player:SendGameMessage(player, worldMaster, 25111, 0x20);
player:EndEvent();
return;
end
--If seekItem is a number, we are buying an item (ExecuteBazaarBuy)
if (type(seekItemOrCost) == "number") then
if (player:GetCurrentGil() >= seekItemOrCost) then
if (GetWorldManager():BazaarBuyOperation(bazaarActor, player, bazaarActor:GetItem(rewardItem), rewardAmount, seekItemOrCost)) then
else
player:SendGameMessage(player, worldMaster, 25111, 0x20);
end
else
player:SendGameMessage(player, worldMaster, 40252, 0x20);
end
else --Else we are fufilling a sought out item (ExecuteBazaarSell)
local rewardItem = bazaarActor:GetItem(rewardItem);
local seekItem = player:GetItem(seekItemOrCost);
if (rewardItem ~= nil and seekItem ~= nil) then
if (GetWorldManager():BazaarSellOperation(bazaarActor, player, rewardItem, rewardAmount, seekItem, seekAmount)) then
else
player:SendGameMessage(player, worldMaster, 25111, 0x20);
end
else
end
end
player:EndEvent();
end

View file

@ -0,0 +1,22 @@
--[[
BazaarUndealCommand Script
Handles canceling bazaar items
25107 - Your bazaar is either full or already contains that unique item.
25111 - Unable to complete transaction.
25112 - You are unable to remove the item from your bazaar. You cannot hold any more items.
25113 - Offered and sought items cannot be identical.
25114 - Items in less than mint condition cannot be offered.
25115 - Items in less than mint condition cannot be placed in your bazaar.
--]]
function onEventStarted(player, actor, triggerName, rewardItem, seekItem, bazaarType, narg, bazaarActor, rewardAmount, seekAmount, narg, narg, type9ItemIds)
GetWorldManager():RemoveFromBazaar(player, player:GetItem(rewardItem));
player:EndEvent();
end

View file

@ -0,0 +1,23 @@
--[[
BonusPointCommand Script
Functions:
operateUI(pointsAvailable, pointsLimit, str, vit, dex, int, min, pie)
--]]
require ("global")
function onEventStarted(player, actor, triggerName)
--local points = player:GetAttributePoints();
--player:RunEventFunction("delegateCommand", actor, "operateUI", points.available, points.limit, points.inSTR, points.inVIT, points.inDEX, points.inINT, points.inMIN, points.inPIT);
result = callClientFunction(player, "delegateCommand", actor, "operateUI", 100, 100, 10, 10, 10, 10, 10, 10);
--Do Save
if (result == true) then
end
player:endEvent();
end

View file

@ -0,0 +1,6 @@
function onEventStarted(player, caller, commandRequest, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8)
player:SetCurrentJob(17);
player:EndEvent();
end

View file

@ -0,0 +1,19 @@
--[[
CheckCommand Script
Handles player examining someone
--]]
function onEventStarted(player, commandactor, triggerName, arg1, arg2, arg3, arg4, checkedActorId)
actor = player:GetActorInInstance(checkedActorId);
if (actor ~= nil) then
player:examinePlayer(actor);
end
player:EndEvent();
end

View file

@ -0,0 +1,45 @@
--[[
ChocoboRideCommand Script
Handles mounting and dismounting the Chocobo and Goobbue
--]]
function onEventStarted(player, actor, triggerName, isGoobbue)
if (player:GetState() == 0) then
worldMaster = GetWorldMaster();
if (isGoobbue ~= true) then
player:ChangeMusic(83);
player:SendGameMessage(player, worldMaster, 26001, 0x20);
player:SetMountState(1);
else
player:ChangeMusic(98);
player:SendGameMessage(player, worldMaster, 26019, 0x20);
player:SetMountState(2);
end
player:ChangeSpeed(0.0, 5.0, 10.0, 10.0);
player:ChangeState(15);
else
player:ChangeMusic(player:GetZone().bgmDay);
worldMaster = GetWorldMaster();
if (player:GetMountState() == 1) then
player:SendGameMessage(player, worldMaster, 26003, 0x20);
else
player:SendGameMessage(player, worldMaster, 26021, 0x20);
end
player:SetMountState(0);
player:ChangeSpeed(0.0, 2.0, 5.0, 5.0)
player:ChangeState(0);
end
player:EndEvent();
end

View file

@ -0,0 +1,144 @@
require ("global")
--[[
CmnAttackWeaponSkill Script
Finds the correct weaponskill subscript to fire when a weaponskill actor is activated.
--]]
local function handleTEST(player)
end
local weaponskillHandlers = {
[0xA0F067F4] = nil,
[0xA0F067F5] = nil,
[0xA0F067F7] = nil,
[0xA0F067F8] = nil,
[0xA0F067FA] = nil,
[0xA0F067FB] = nil,
[0xA0F067FD] = nil,
[0xA0F067FE] = nil,
[0xA0F06800] = nil,
[0xA0F06801] = nil,
[0xA0F06802] = nil,
[0xA0F06804] = nil,
[0xA0F06805] = nil,
[0xA0F06806] = nil,
[0xA0F06808] = nil,
[0xA0F0680A] = nil,
[0xA0F0680B] = nil,
[0xA0F0680D] = nil,
[0xA0F0680E] = nil,
[0xA0F06810] = nil,
[0xA0F06812] = nil,
[0xA0F06814] = nil,
[0xA0F068A8] = nil,
[0xA0F068A9] = nil,
[0xA0F068AB] = nil,
[0xA0F068AC] = nil,
[0xA0F068AE] = nil,
[0xA0F068AF] = nil,
[0xA0F068B2] = nil,
[0xA0F068B3] = nil,
[0xA0F068B5] = nil,
[0xA0F068B7] = nil,
[0xA0F068B8] = nil,
[0xA0F068B9] = nil,
[0xA0F068BB] = nil,
[0xA0F068BC] = nil,
[0xA0F068BE] = nil,
[0xA0F068BF] = nil,
[0xA0F068C1] = nil,
[0xA0F068C3] = nil,
[0xA0F068C5] = nil,
[0xA0F0695C] = nil,
[0xA0F0695D] = nil,
[0xA0F0695E] = nil,
[0xA0F06960] = nil,
[0xA0F06961] = nil,
[0xA0F06963] = nil,
[0xA0F06964] = nil,
[0xA0F06966] = nil,
[0xA0F06967] = nil,
[0xA0F06968] = nil,
[0xA0F0696A] = nil,
[0xA0F0696B] = nil,
[0xA0F0696D] = nil,
[0xA0F0696E] = nil,
[0xA0F06970] = nil,
[0xA0F06971] = nil,
[0xA0F06973] = nil,
[0xA0F06974] = nil,
[0xA0F06976] = nil,
[0xA0F06978] = nil,
[0xA0F06B78] = nil,
[0xA0F06B79] = nil,
[0xA0F06B7B] = nil,
[0xA0F06B7C] = nil,
[0xA0F06B7E] = nil,
[0xA0F06B7F] = nil,
[0xA0F06B81] = nil,
[0xA0F06B82] = nil,
[0xA0F06B84] = nil,
[0xA0F06B85] = nil,
[0xA0F06B8A] = nil,
[0xA0F06B8C] = nil,
[0xA0F06B8E] = nil,
[0xA0F06B90] = nil,
[0xA0F06B91] = nil,
[0xA0F06B93] = nil,
[0xA0F06B95] = nil,
[0xA0F06B97] = nil,
[0xA0F06C2C] = nil,
[0xA0F06C2D] = nil,
[0xA0F06C2F] = nil,
[0xA0F06C31] = nil,
[0xA0F06C32] = nil,
[0xA0F06C34] = nil,
[0xA0F06C35] = nil,
[0xA0F06C36] = nil,
[0xA0F06C38] = nil,
[0xA0F06C39] = nil,
[0xA0F06C3B] = nil,
[0xA0F06C3C] = nil,
[0xA0F06C3E] = nil,
[0xA0F06C3F] = nil,
[0xA0F06C41] = nil,
[0xA0F06C43] = nil,
[0xA0F06C45] = nil,
[0xA0F06C47] = nil,
[0xA0F06C49] = nil,
[0xA0F06C4B] = nil,
[0xA0F06D94] = nil,
[0xA0F06D95] = nil,
[0xA0F06D96] = nil,
[0xA0F06F92] = nil,
[0xA0F06F93] = nil,
[0xA0F06F95] = nil,
[0xA0F06F96] = nil,
[0xA0F070E6] = nil,
[0xA0F070E7] = nil,
[0xA0F070E9] = nil,
[0xA0F070EA] = nil
}
function onEventStarted(player, command, triggerName)
--Are they in active mode?
if (player:GetState() != 2) then
player:SendGameMessage(GetWorldMaster(), 32503, 0x20);
player:endEvent();
return;
end
if (weaponskillHandlers[command.actorId] ~= nil) then
weaponskillHandlers[command.actorId](player);
else
player:SendMessage(0x20, "", "That weaponskill is not implemented yet.");
end
player:endEvent();
end

View file

@ -0,0 +1,18 @@
--[[
ConfirmGroupCommand Script
Handles what happens when you resolve an invite to a group
--]]
function onEventStarted(player, actor, triggerName, groupType, result)
--Accept/Refuse happened, else just close the window
if (result == 1 or result == 2) then
GetWorldManager():GroupInviteResult(player, groupType, result);
end
player:EndEvent();
end

View file

@ -0,0 +1,20 @@
--[[
ConfirmTradeCommand Script
Handles what happens when you accept/refuse a trade
--]]
function onEventStarted(player, actor, triggerName, groupType, result)
--Accept
if (result == 1) then
GetWorldManager():AcceptTrade(player);
--Refuse
elseif (result == 2) then
GetWorldManager():RefuseTrade(player);
end
player:EndEvent();
end

View file

@ -0,0 +1,5 @@
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
player.Cast(command.actorId, targetActor);
player:endEvent();
end

View file

@ -0,0 +1,5 @@
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
player.Cast(command.actorId, targetActor);
player:endEvent();
end

View file

@ -0,0 +1,26 @@
require ("global")
require ("utils")
--[[
AttackWeaponSkill Script
Finds the correct weaponskill subscript to fire when a weaponskill actor is activated.
--]]
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
--Are they in active mode?
if (player:GetState() != 2) then
player:SendGameMessage(GetWorldMaster(), 32503, 0x20);
player:endEvent();
return;
end
if not player.aiContainer.IsEngaged() then
player.Engage(targetActor);
end;
player.WeaponSkill(command.actorId, targetActor);
player:endEvent();
end;

View file

@ -0,0 +1,23 @@
--[[
DiceCommand Script
--]]
function onEventStarted(player, actor, triggerName, maxNumber)
if (maxNumber == nil or maxNumber > 1000 or maxNumber < 1) then
maxNumber = 100;
end
result = math.random(0, maxNumber);
worldMaster = GetWorldMaster();
player:SendGameMessage(player, worldMaster, 25342, 0x20, result, maxNumber);
player:EndEvent();
end
function onEventUpdate(player, npc)
end

View file

@ -0,0 +1,56 @@
--[[
HarvestJudge
Operates the harvesting system for mining, logging, and fishing.
Functions:
loadTextData(commandActor): Loads all gamesheets needed and instantiates a HarvestJudge.
targetCancel(commandActor): Cancels the player's target.
turnToTarget(commandActor, harvestType, direction): Turns to a direction (name's a lie, angle must be computed lol)
openInputWidget(commandActor, harvestType, nodeGrade): Inits the widget system (call first).
orderInputWidget(commandActor, nodeHP [max 100], ?, harvestType): Updates the node HP.
textInputWidget(commandActor, harvestType, ?, textId, ?, ?, ?): Sets the result text after a minigame is performed.
askInputWidget(commandActor, harvestType, inputPageNumber, showTutorial, showFishWait, showFishWaitAndJig, updateFishHP, showRareCatalystEffect): Gets user input after opening a ask widget.
closeInputWidget(commandActor, harvestType): Closes the widget system (call last).
rangeInputWidget(harvestType, inputPageNumber, goodMin, goodMax, bool): Unknown, currently crashing...
Notes:
HarvestType Ids:
20002: Mine
20003: Log
20004: Fish
--]]
require ("global")
function onEventStarted(player, commandactor, triggerName, arg1, arg2, arg3, arg4, checkedActorId)
harvestJudge = GetStaticActor("HarvestJudge");
callClientFunction(player, "delegateCommand", harvestJudge, "loadTextData", commandactor);
callClientFunction(player, "delegateCommand", harvestJudge, "targetCancel", commandactor);
callClientFunction(player, "delegateCommand", harvestJudge, "turnToTarget", commandactor, 0x55F2, 2);
player:ChangeState(50);
callClientFunction(player, "delegateCommand", harvestJudge, "openInputWidget", commandactor, 0x55F2, 2);
callClientFunction(player, "delegateCommand", harvestJudge, "orderInputWidget", commandactor, 3, false, 0x55f2);
callClientFunction(player, "delegateCommand", harvestJudge, "textInputWidget", commandactor, 0x55f2, harvestJudge, nil, nil, nil, nil, 0);
callClientFunction(player, "delegateCommand", harvestJudge, "askInputWidget", commandactor, 0x55f2, 1, 0, false, false, nil, false);
callClientFunction(player, "delegateCommand", harvestJudge, "textInputWidget", commandactor, 0x55f2, harvestJudge, 60, nil, nil, nil, 0);
callClientFunction(player, "delegateCommand", harvestJudge, "askInputWidget", commandactor, 0x55f2, 2, 0, false, false, nil, false);
callClientFunction(player, "delegateCommand", harvestJudge, "textInputWidget", commandactor, 0x55f2, harvestJudge, 46,0, 0, 0, 0);
callClientFunction(player, "delegateCommand", harvestJudge, "askInputWidget", commandactor, 0x55f2, 2, 0, false, false, nil, false);
player:ChangeState(0);
player:EndEvent();
end

View file

@ -0,0 +1,5 @@
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
player.Cast(command.actorId, targetActor);
player:endEvent();
end

View file

@ -0,0 +1,24 @@
--[[
EmoteSitCommand Script
--]]
function onEventStarted(player, actor, triggerName, emoteId)
if (player:GetState() == 0) then
if (emoteId == 0x2712) then
player:ChangeState(11);
else
player:ChangeState(13);
end
else
player:ChangeState(0);
end
player:EndEvent();
end
function onEventUpdate(player, npc)
end

View file

@ -0,0 +1,90 @@
--[[
EmoteStandardCommand Script
Returns the correct animation and log description when an emote is activated.
If 'motion' parameter is used, it returns the blank description id 10105
--]]
emoteTable = {
[101] = {animId = 1, descId = 21001}, --Surprised
[102] = {animId = 2, descId = 21011}, --Angry
[103] = {animId = 3, descId = 21021}, --Furious
[104] = {animId = 4, descId = 21031}, --Blush
[105] = {animId = 5, descId = 21041}, --Bow
[106] = {animId = 6, descId = 21051}, --Cheer
[107] = {animId = 7, descId = 21061}, --Clap
[108] = {animId = 8, descId = 21071}, --Beckon
[109] = {animId = 9, descId = 21081}, --Comfort
[110] = {animId = 10, descId = 21091}, --Cry
[111] = {animId = 11, descId = 21101}, --Dance
[112] = {animId = 12, descId = 21111}, --Doubt
[113] = {animId = 13, descId = 21121}, --Doze
[114] = {animId = 14, descId = 21131}, --Fume
[115] = {animId = 15, descId = 21141}, --Goodbye
[116] = {animId = 16, descId = 21151}, --Wave
[117] = {animId = 17, descId = 21161}, --Huh
[118] = {animId = 18, descId = 21171}, --Joy
[119] = {animId = 19, descId = 21181}, --Kneel
[120] = {animId = 20, descId = 21191}, --Chuckle
[121] = {animId = 21, descId = 21201}, --Laugh
[122] = {animId = 22, descId = 21211}, --Lookout
[123] = {animId = 23, descId = 21221}, --Me
[124] = {animId = 24, descId = 21231}, --No
[125] = {animId = 25, descId = 21241}, --Deny
[126] = {animId = 26, descId = 21251}, --Panic
[127] = {animId = 27, descId = 21261}, --Point
[128] = {animId = 28, descId = 21271}, --Poke
[129] = {animId = 29, descId = 21281}, --Congratulate
[130] = {animId = 30, descId = 21291}, --Psych
[131] = {animId = 31, descId = 21301}, --Salute
[132] = {animId = 32, descId = 21311}, --Shocked
[133] = {animId = 33, descId = 21321}, --Shrug
[134] = {animId = 34, descId = 21331}, --Rally
[135] = {animId = 35, descId = 21341}, --Soothe
[136] = {animId = 36, descId = 21351}, --Stagger
[137] = {animId = 37, descId = 21361}, --Stretch
[138] = {animId = 38, descId = 21371}, --Sulk
[139] = {animId = 39, descId = 21381}, --Think
[140] = {animId = 40, descId = 21391}, --Upset
[141] = {animId = 41, descId = 21401}, --Welcome
[142] = {animId = 42, descId = 21411}, --Yes
[143] = {animId = 43, descId = 21421}, --Thumbs Up
[144] = {animId = 44, descId = 21423}, --Examine Self
[145] = {animId = 53, descId = 21425}, --Pose
[146] = {animId = 50, descId = 21427}, --Storm Salute
[147] = {animId = 51, descId = 21429}, --Serpent Salute
[148] = {animId = 52, descId = 21431}, --Flame Salute
[149] = {animId = 45, descId = 21433}, --Blow Kiss
[151] = {animId = 47, descId = 21435}, --Grovel
[152] = {animId = 48, descId = 21437}, --Happy
[153] = {animId = 49, descId = 21439}, --Disappointed
[154] = {animId = 46, descId = 10105}, --Air Quotes
[155] = {animId = 54, descId = 21442}, --Pray
[156] = {animId = 55, descId = 21445}, --Fire Dance
};
function onEventStarted(player, actor, triggerName, emoteId, showText, arg2, arg3, targetId)
if (targetId == nil) then
targetId = 0;
end
if (player:GetState() == 0 or player:GetState() == 11 or player:GetState() == 13) then
emote = emoteTable[emoteId];
if (emote ~= nil) then
if showText == 1 then
player:doEmote(targetId, emote.animId, emote.descId);
else
player:doEmote(targetId, emote.animId, 10105);
end
else
player:SendMessage(0x20, "", string.format("Not implemented; EmoteId: %d", emoteId));
end
end
player:EndEvent();
end

View file

@ -0,0 +1,85 @@
require ("global")
--player: Player that called this command
--equipAbilityWidget: Widget that calls this command
--triggername: Event Starter ?
--slot: Which slot the ability will go into
--commandid: command being equipped
function onEventStarted(player, equipAbilityWidget, triggername, slot, commandid, unkown, arg1, arg2, arg3, arg4, arg5, arg6)
local worldManager = GetWorldManager();
local ability = worldManager:GetBattleCommand(commandid);
--Equip
if (commandid > 0) then
--[[]]
--Can the player equip any more cross class actions
if (player.charaWork.parameterTemp.otherClassAbilityCount[0] >= player.charaWork.parameterTemp.otherClassAbilityCount[1]) then
--"You cannot set any more actions."
player:SendGameMessage(GetWorldMaster(), 30720, 0x20, 0, 0);
player:endEvent();
return;
end
--Is the player high enough level in that class to equip the ability
if (player.charaWork.battleSave.skillLevel[ability.job - 1] < ability.level) then
--"You have not yet acquired that action."
player:SendGameMessage(GetWorldMaster(), 30742, 0x20, 0, 0);
player:endEvent();
return;
end
local oldSlot = player:FindFirstCommandSlotById(commandid);
local isEquipped = oldSlot < player.charaWork.commandBorder + 30;
--If slot is 0, find the first open slot
if (slot == 0) then
--If the ability is already equipped and slot is 0, then it can't be equipped again
--If the slot isn't 0, it's a move or a swap command
if (isEquipped == true) then
--"That action is already set to an action slot."
player:SendGameMessage(GetWorldMaster(), 30719, 0x20, 0);
player:endEvent();
return;
end
slot = player:FindFirstCommandSlotById(0) - player.charaWork.commandBorder;
--If the first open slot is outside the hotbar, then the hotbar is full
if(slot >= 30) then
--"You cannot set any more actions."
player:SendGameMessage(Server.GetWorldManager().GetActor(), 30720, 0x20, 0);
player:endEvent();
return;
end
else
slot = slot - 1;
end
if(isEquipped == true) then
player:SwapAbilities(oldSlot, slot + player.charaWork.commandBorder);
else
local tslot = slot + player.charaWork.commandBorder;
player:EquipAbility(player.GetCurrentClassOrJob(), commandid, tslot, true);
end
--Unequip
elseif (commandid == 0) then
commandid = player.charaWork.command[slot + player.charaWork.commandBorder - 1];
ability = worldManager.GetBattleCommand(commandid);
--Is the ability a part of the player's current class?
--This check isn't correct because of jobs having different ids
local classId = player:GetCurrentClassOrJob();
local jobId = player:ConvertClassIdToJobId(classId);
if(ability.job == classId or ability.job == jobId) then
--"Actions of your current class or job cannot be removed."
player:SendGameMessage(GetWorldMaster(), 30745, 0x20, 0, 0);
elseif (commandid != 0) then
player:UnequipAbility(slot);
end
end
player:endEvent();
end

View file

@ -0,0 +1,220 @@
--[[
EquipCommand Script
Notes:
Gearset activating could be optimized a bit more by doing the item packets in one go.
The param "equippedItem" has the vars: actorId, unknown, slot, and inventoryType.
The param "itemDBIds" has the vars: item1 and item2.
--]]
EQUIPSLOT_MAINHAND = 0;
EQUIPSLOT_OFFHAND = 1;
EQUIPSLOT_THROWINGWEAPON = 4;
EQUIPSLOT_PACK = 5;
EQUIPSLOT_POUCH = 6;
EQUIPSLOT_HEAD = 8;
EQUIPSLOT_UNDERSHIRT = 9;
EQUIPSLOT_BODY = 10;
EQUIPSLOT_UNDERGARMENT = 11;
EQUIPSLOT_LEGS = 12;
EQUIPSLOT_HANDS = 13;
EQUIPSLOT_FEET = 14;
EQUIPSLOT_WAIST = 15;
EQUIPSLOT_NECK = 16;
EQUIPSLOT_EARS = 17;
EQUIPSLOT_WRIST = 19;
EQUIPSLOT_RFINGER = 21;
EQUIPSLOT_LFINGER = 22;
GRAPHICSLOT_MAINHAND = 5;
GRAPHICSLOT_OFFHAND = 6;
GRAPHICSLOT_SPMAINHAND = 7;
GRAPHICSLOT_SPOFFHAND = 8;
GRAPHICSLOT_THROWING = 9;
GRAPHICSLOT_PACK = 10;
GRAPHICSLOT_POUCH = 11;
GRAPHICSLOT_HEAD = 12;
GRAPHICSLOT_BODY = 13;
GRAPHICSLOT_LEGS = 14;
GRAPHICSLOT_HANDS = 15;
GRAPHICSLOT_FEET = 16;
GRAPHICSLOT_WAIST = 17;
GRAPHICSLOT_NECK = 18;
GRAPHICSLOT_R_EAR = 19;
GRAPHICSLOT_L_EAR = 20;
GRAPHICSLOT_R_WRIST = 21;
GRAPHICSLOT_L_WRIST = 22;
GRAPHICSLOT_R_RINGFINGER = 23;
GRAPHICSLOT_L_RINGFINGER = 24;
GRAPHICSLOT_R_INDEXFINGER = 25;
GRAPHICSLOT_L_INDEXFINGER = 26;
function onEventStarted(player, actor, triggerName, equippedItem, param1, param2, param3, param4, param5, param6, param7, equipSlot, itemDBIds)
equipSlot = equipSlot-1;
--Equip Item
if (equippedItem ~= nil) then
item = player:GetItemPackage(equippedItem.itemPackage):GetItemAtSlot(equippedItem.slot);
equipItem(player, equipSlot, item);
player:SendAppearance();
--Unequip Item
else
item = player:GetEquipment():GetItemAtSlot(equipSlot);
if (unequipItem(player, equipSlot, item) == true) then --Returns true only if something changed (didn't error out)
player:SendAppearance();
end
end
player.CalculateBaseStats(); --player.RecalculateStats();
player:EndEvent();
end
function loadGearset(player, classId)
player:GetEquipment():ToggleDBWrite(false);
local gearset = player:GetGearset(classId);
if gearset == nil then
return;
end
for slot = 0, 34 do
if (slot ~= EQUIPSLOT_MAINHAND and slot ~= EQUIPSLOT_UNDERSHIRT and slot ~= EQUIPSLOT_UNDERGARMENT) then
itemAtSlot = player:GetEquipment():GetItemAtSlot(slot);
itemAtGearsetSlot = gearset[slot];
if (itemAtSlot ~= nil or itemAtGearsetSlot ~= nil) then
if (itemAtSlot ~= nil and itemAtGearsetSlot == nil) then
unequipItem(player, slot, itemAtSlot);
elseif (itemAtSlot == nil and itemAtGearsetSlot ~= nil) then
equipItem(player, slot, itemAtGearsetSlot);
elseif (itemAtGearsetSlot.uniqueId ~= itemAtSlot.uniqueId) then
unequipItem(player, slot, itemAtSlot);
equipItem(player, slot, itemAtGearsetSlot)
end
end
end
end
player:GetEquipment():ToggleDBWrite(true);
end
function equipItem(player, equipSlot, item)
if (item ~= nil) then
local classId = nil;
local worldMaster = GetWorldMaster();
local gItem = GetItemGamedata(item.itemId);
--If it's the mainhand, begin class change based on weapon
if (equipSlot == EQUIPSLOT_MAINHAND) then
if (gItem:IsNailWeapon()) then classId = 2;
elseif (gItem:IsSwordWeapon()) then classId = 3;
elseif (gItem:IsAxeWeapon()) then classId = 4;
elseif (gItem:IsBowWeapon()) then classId = 7;
elseif (gItem:IsLanceWeapon()) then classId = 8;
elseif (gItem:IsThaumaturgeWeapon()) then classId = 22;
elseif (gItem:IsConjurerWeapon()) then classId = 23;
elseif (gItem:IsCarpenterWeapon()) then classId = 29;
elseif (gItem:IsBlackSmithWeapon()) then classId = 30;
elseif (gItem:IsArmorerWeapon()) then classId = 31;
elseif (gItem:IsGoldSmithWeapon()) then classId = 32;
elseif (gItem:IsTannerWeapon()) then classId = 33;
elseif (gItem:IsWeaverWeapon()) then classId = 34;
elseif (gItem:IsAlchemistWeapon()) then classId = 35;
elseif (gItem:IsCulinarianWeapon()) then classId = 36;
elseif (gItem:IsMinerWeapon()) then classId = 39;
elseif (gItem:IsBotanistWeapon()) then classId = 40;
elseif (gItem:IsFishingWeapon()) then classId = 41;
end
if (classId ~= nil) then
player:SendGameMessage(player, worldMaster, 30103, 0x20, 0, 0, player, classId);
player:PrepareClassChange(classId);
end
end
--Item Equipped message
player:SendGameMessage(player, worldMaster, 30601, 0x20, equipSlot+1, item.itemId, item.quality, 0, 0, 1);
--Load gearset for new class and begin class change
if (classId ~= nil) then
loadGearset(player, classId);
player:DoClassChange(classId);
end
player:GetEquipment():Set(equipSlot, item);
if (equipSlot == EQUIPSLOT_MAINHAND and gItem:IsNailWeapon() == false) then graphicSlot = GRAPHICSLOT_MAINHAND;
elseif (equipSlot == EQUIPSLOT_OFFHAND) then graphicSlot = GRAPHICSLOT_OFFHAND;
elseif (equipSlot == EQUIPSLOT_THROWINGWEAPON) then graphicSlot = GRAPHICSLOT_THROWING;
elseif (equipSlot == EQUIPSLOT_PACK) then graphicSlot = GRAPHICSLOT_PACK;
elseif (equipSlot == EQUIPSLOT_HEAD) then graphicSlot = GRAPHICSLOT_HEAD;
elseif (equipSlot == EQUIPSLOT_BODY) then graphicSlot = GRAPHICSLOT_BODY;
elseif (equipSlot == EQUIPSLOT_LEGS) then graphicSlot = GRAPHICSLOT_LEGS;
elseif (equipSlot == EQUIPSLOT_HANDS) then graphicSlot = GRAPHICSLOT_HANDS;
elseif (equipSlot == EQUIPSLOT_FEET) then graphicSlot = GRAPHICSLOT_FEET;
elseif (equipSlot == EQUIPSLOT_WAIST) then graphicSlot = GRAPHICSLOT_WAIST;
elseif (equipSlot == EQUIPSLOT_NECK) then graphicSlot = GRAPHICSLOT_NECK;
elseif (equipSlot == EQUIPSLOT_RFINGER) then graphicSlot = GRAPHICSLOT_R_RINGFINGER;
elseif (equipSlot == EQUIPSLOT_LFINGER) then graphicSlot = GRAPHICSLOT_L_RINGFINGER;
end
--Graphic Slot was set, otherwise it's a special case
if (graphicSlot ~= nil) then
player:GraphicChange(graphicSlot, item);
elseif (gItem:IsNailWeapon()) then
player:GraphicChange(GRAPHICSLOT_MAINHAND, item);
player:GraphicChange(GRAPHICSLOT_OFFHAND, item);
elseif (equipSlot == EQUIPSLOT_EARS) then
player:GraphicChange(GRAPHICSLOT_R_EAR, item);
player:GraphicChange(GRAPHICSLOT_L_EAR, item);
elseif (equipSlot == EQUIPSLOT_WRIST) then
player:GraphicChange(GRAPHICSLOT_R_WRIST, item);
player:GraphicChange(GRAPHICSLOT_L_WRIST, item);
end
end
end
function unequipItem(player, equipSlot, item)
worldMaster = GetWorldMaster();
if (item ~= nil and (equipSlot == EQUIPSLOT_MAINHAND or equipSlot == EQUIPSLOT_UNDERSHIRT or equipSlot == EQUIPSLOT_UNDERGARMENT)) then
player:SendGameMessage(player, worldMaster, 30730, 0x20, equipSlot+1, item.itemId, item.quality, 0, 0, 1); --Unable to unequip
elseif (item ~= nil) then
player:SendGameMessage(player, worldMaster, 30602, 0x20, equipSlot+1, item.itemId, item.quality, 0, 0, 1); --Item Removed
player:GetEquipment():Clear(equipSlot);
if (equipSlot == EQUIPSLOT_BODY) then --Show Undershirt
item = player:GetEquipment():GetItemAtSlot(EQUIPSLOT_UNDERSHIRT);
player:GraphicChange(GRAPHICSLOT_BODY, item);
elseif (equipSlot == EQUIPSLOT_LEGS) then --Show Undergarment
item = player:GetEquipment():GetItemAtSlot(EQUIPSLOT_UNDERGARMENT);
player:GraphicChange(GRAPHICSLOT_LEGS, item);
elseif (equipSlot == EQUIPSLOT_HANDS) then player:GraphicChange(15, 0, 1, 0, 0);
elseif (equipSlot == EQUIPSLOT_FEET) then player:GraphicChange(16, 0, 1, 0, 0);
else
if (equipSlot == EQUIPSLOT_MAINHAND) then player:GraphicChange(GRAPHICSLOT_MAINHAND, nil);
elseif (equipSlot == EQUIPSLOT_OFFHAND) then player:GraphicChange(GRAPHICSLOT_OFFHAND, nil);
elseif (equipSlot == EQUIPSLOT_THROWINGWEAPON) then player:GraphicChange(GRAPHICSLOT_THROWING, nil);
elseif (equipSlot == EQUIPSLOT_PACK) then player:GraphicChange(GRAPHICSLOT_PACK, nil);
elseif (equipSlot == EQUIPSLOT_HEAD) then player:GraphicChange(GRAPHICSLOT_HEAD, nil);
elseif (equipSlot == EQUIPSLOT_WAIST) then player:GraphicChange(GRAPHICSLOT_WAIST, nil);
elseif (equipSlot == EQUIPSLOT_NECK) then player:GraphicChange(GRAPHICSLOT_NECK, nil);
elseif (equipSlot == EQUIPSLOT_EARS) then player:GraphicChange(GRAPHICSLOT_L_EAR, nil); player:GraphicChange(GRAPHICSLOT_R_EAR, nil);
elseif (equipSlot == EQUIPSLOT_WRIST) then player:GraphicChange(GRAPHICSLOT_L_WRIST, nil); player:GraphicChange(GRAPHICSLOT_R_WRIST, nil);
elseif (equipSlot == EQUIPSLOT_RFINGER) then player:GraphicChange(GRAPHICSLOT_R_RINGFINGER, nil);
elseif (equipSlot == EQUIPSLOT_LFINGER) then player:GraphicChange(GRAPHICSLOT_L_RINGFINGER, nil);
end
end
return true;
end
end

View file

@ -0,0 +1,5 @@
function onEventStarted(player, command, triggerName, arg1, arg2, arg3, arg4, targetActor, arg5, arg6, arg7, arg8)
player.Cast(command.actorId, targetActor);
player:endEvent();
end

View file

@ -0,0 +1,13 @@
--[[
ItemMovePackageCommand Script
Handles moving items across item packages (IE: Taking loot)
--]]
function onEventStarted(player, actor, triggerName, itemReference, targetPackage, sourcePackage, arg1, arg2, unknown, arg3, arg4, arg5, type9ItemIds)
player:EndEvent();
end

View file

@ -0,0 +1,13 @@
--[[
ItemTransferCommand Script
Handles giving an item to another party member.
--]]
function onEventStarted(player, actor, triggerName, itemReference, targetPackage, sourcePackage, arg1, targetPlayer, arg2, arg3, arg4, arg5, type9ItemIds)
player:EndEvent();
end

Some files were not shown because too many files have changed in this diff Show more