summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/statics.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/statics.lua')
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/statics.lua447
1 files changed, 447 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/statics.lua b/Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/statics.lua
new file mode 100644
index 0000000..2e9e46d
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/statics.lua
@@ -0,0 +1,447 @@
+--Copyright (c) 2013~2016, Byrthnoth
+--All rights reserved.
+
+--Redistribution and use in source and binary forms, with or without
+--modification, are permitted provided that the following conditions are met:
+
+-- * Redistributions of source code must retain the above copyright
+-- notice, this list of conditions and the following disclaimer.
+-- * Redistributions in binary form must reproduce the above copyright
+-- notice, this list of conditions and the following disclaimer in the
+-- documentation and/or other materials provided with the distribution.
+-- * Neither the name of <addon name> nor the
+-- names of its contributors may be used to endorse or promote products
+-- derived from this software without specific prior written permission.
+
+--THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+--ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+--WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+--DISCLAIMED. IN NO EVENT SHALL <your name> BE LIABLE FOR ANY
+--DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+--(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+--LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+--ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+--(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+-- Convert the spells and job abilities into a referenceable list of aliases --
+
+unify_prefix = {['/ma'] = '/ma', ['/magic']='/ma',['/jobability'] = '/ja',['/ja']='/ja',['/item']='/item',['/song']='/ma',
+ ['/so']='/ma',['/ninjutsu']='/ma',['/weaponskill']='/ws',['/ws']='/ws',['/ra']='/ra',['/rangedattack']='/ra',['/nin']='/ma',
+ ['/throw']='/ra',['/range']='/ra',['/shoot']='/ra',['/monsterskill']='/ms',['/ms']='/ms',['/pet']='/ja',['Monster']='Monster',['/bstpet']='/ja'}
+
+action_type_map = {['/ja']='Ability',['/jobability']='Ability',['/so']='Magic',['/song']='Magic',['/ma']='Magic',['/magic']='Magic',['/nin']='Magic',['/ninjutsu']='Magic',
+ ['/ra']='Ranged Attack',['/range']='Ranged Attack',['/throw']='Ranged Attack',['/shoot']='Ranged Attack',['/ms']='Ability',['/monsterskill']='Ability',
+ ['/ws']='Ability',['/weaponskill']='Ability',['/item']='Item',['/pet']='Ability',['/bstpet']='Ability',['Monster']='Monster Move'}
+
+usable_item_bags = {
+ res.bags[3], -- Temporary Items
+ res.bags[0], -- Inventory
+ res.bags[8], -- Wardrobe 1
+ res.bags[10], -- Wardrobe 2
+ res.bags[11], -- Wardrobe 3
+ res.bags[12]} -- Wardrobe 4
+
+equippable_item_bags = {
+ res.bags[0], -- Inventory
+ res.bags[8], -- Wardrobe 1
+ res.bags[10], -- Wardrobe 2
+ res.bags[11], -- Wardrobe 3
+ res.bags[12]} -- Wardrobe 4
+
+bag_string_lookup = {}
+for i,v in pairs(res.bags) do
+ bag_string_lookup[to_windower_bag_api(v.en)]=i
+end
+
+bstpet_range = {min=672,max=798} -- Range of the JA resource devoted to BST jugpet abilities
+
+delay_map_to_action_type = {['Ability']=3,['Magic']=20,['Ranged Attack']=10,['Item']=10,['Monster Move']=10,['Interruption']=3}
+
+validabils = {}
+validabils['english'] = {['/ma'] = {}, ['/ja'] = {}, ['/ws'] = {}, ['/item'] = {}, ['/ra'] = {}, ['/ms'] = {}, ['/pet'] = {}, ['/trig'] = {}, ['/echo'] = {}}
+validabils['french'] = {['/ma'] = {}, ['/ja'] = {}, ['/ws'] = {}, ['/item'] = {}, ['/ra'] = {}, ['/ms'] = {}, ['/pet'] = {}, ['/trig'] = {}, ['/echo'] = {}}
+validabils['german'] = {['/ma'] = {}, ['/ja'] = {}, ['/ws'] = {}, ['/item'] = {}, ['/ra'] = {}, ['/ms'] = {}, ['/pet'] = {}, ['/trig'] = {}, ['/echo'] = {}}
+validabils['japanese'] = {['/ma'] = {}, ['/ja'] = {}, ['/ws'] = {}, ['/item'] = {}, ['/ra'] = {}, ['/ms'] = {}, ['/pet'] = {}, ['/trig'] = {}, ['/echo'] = {}}
+
+function make_abil(abil,lang,i)
+ if not abil[lang] or not abil.prefix then return end
+ local sp,pref = abil[lang]:lower(), unify_prefix[abil.prefix:lower()]
+ validabils[lang][pref][sp] = i
+end
+
+function make_entry(v,i)
+ make_abil(v,'english',i)
+ make_abil(v,'german',i)
+ make_abil(v,'french',i)
+ make_abil(v,'japanese',i)
+end
+
+for i,v in pairs(res.spells) do
+ if not T{363,364}:contains(i) then
+ make_entry(v,i)
+ end
+end
+
+for i,v in pairs(res.job_abilities) do
+ make_entry(v,i)
+end
+
+for i,v in pairs(res.weapon_skills) do
+ v.type = 'WeaponSkill'
+ make_entry(v,i)
+end
+
+for i,v in pairs(res.monster_skills) do
+ v.type = 'MonsterSkill'
+ make_entry(v,i)
+end
+
+for i,v in pairs(res.items) do
+ v.prefix = '/item'
+ if not validabils['english'][v.prefix][v.english:lower()] or v.cast_delay then
+ make_entry(v,i)
+ end
+end
+
+ -- Should transition these slot maps to be based off res.slots, but it's very unlikely to change.
+default_slot_map = T{'sub','range','ammo','head','body','hands','legs','feet','neck','waist',
+ 'left_ear', 'right_ear', 'left_ring', 'right_ring','back'}
+default_slot_map[0]= 'main'
+
+jas = {false,false,false,false,false,true,false,false,false,false,false,false,false,true,true,false}-- {6,14,15}
+readies = {false,false,false,false,false,false,true,true,true,false,false,true,false,false,false,false} -- {7,8,9,12}
+uses = {false,true,true,true,true,false,false,false,false,false,true,false,true,false,false,false}--{2,3,4,5,11,13}
+unable_to_use = T{17,18,55,56,87,88,89,90,104,191,308,313,325,410,428,561,574,579,580,581,661,665,
+ 12,16,34,35,40,47,48,49,71,72,76,78,84,91,92,95,96,106,111,128,154,155,190,192,193,198,
+ 199,215,216,217,218,219,220,233,246,247,307,315,316,328,337,338,346,347,348,349,356,411,443,444,
+ 445,446,514,516,517,518,523,524,525,547,568,569,575,649,660,662,666,700,701,62,717} -- Probably don't need some of these (event action)
+ -- 94 removed - "You must wait longer to perform that action." -- I think this is only sent in response to engage packets.
+
+-- 192 : param_1 = Ability ID
+-- 17 : no information
+-- 34 : param_1 = Spell index
+pass_through_targs = {['<t>']=true,['<me>']=true,['<ft>']=true,['<scan>']=true,['<bt>']=true,['<lastst>']=true,
+ ['<r>']=true,['<pet>']=true,['<p0>']=true,['<p1>']=true,['<p2>']=true,['<p3>']=true,['<p4>']=true,
+ ['<p5>']=true,['<a10>']=true,['<a11>']=true,['<a12>']=true,['<a13>']=true,['<a14>']=true,['<a15>']=true,
+ ['<a20>']=true,['<a21>']=true,['<a22>']=true,['<a23>']=true,['<a24>']=true,['<a25>']=true,['<st>']=true,
+ ['<stnpc>']=true,['<stal>']=true,['<stpc>']=true,['<stpt>']=true}
+
+avatar_element = {Ifrit=0,Titan=3,Leviathan=5,Garuda=2,Shiva=1,Ramuh=4,Carbuncle=6,
+ Diabolos=7,Fenrir=7,['Cait Sith']=6,FireSpirit=0,EarthSpirit=3,WaterSpirit=5,
+ AirSpirit=2,IceSpirit=1,ThunderSpirit=4,LightSpirit=6,
+ DarkSpirit=7}
+
+encumbrance_map = {0x79,0x7F,0x7F,0x7A,0x7B,0x7C,0x7D,0x7D,0x7A,0x7E,0x80,0x80,0x80,0x80,0x7E}
+encumbrance_map[0] = 0x79 -- Slots mapped onto encumbrance byte values.
+
+addendum_white = {[14]="Poisona",[15]="Paralyna",[16]="Blindna",[17]="Silena",[18]="Stona",[19]="Viruna",[20]="Cursna",
+ [143]="Erase",[13]="Raise II",[140]="Raise III",[141]="Reraise II",[142]="Reraise III",[135]="Reraise"}
+
+addendum_black = {[253]="Sleep",[259]="Sleep II",[260]="Dispel",[162]="Stone IV",[163]="Stone V",[167]="Thunder IV",
+ [168]="Thunder V",[157]="Aero IV",[158]="Aero V",[152]="Blizzard IV",[153]="Blizzard V",[147]="Fire IV",[148]="Fire V",
+ [172]="Water IV",[173]="Water V",[255]="Break"}
+
+resources_ranged_attack = {id="0",index="0",prefix="/range",english="Ranged",german="Fernwaffe",french="Attaque à dist.",japanese="飛び道具",type="Misc",element="None",targets=S{"Enemy"}}
+
+
+-- _globals --
+user_data_table = {
+ __newindex = function(tab, key, val)
+ rawset(tab, user_key_filter(key), val)
+ end,
+
+ __index = function(tab, key)
+ return rawget(tab, user_key_filter(key))
+ end
+ }
+
+--[[eq_data_table = {
+ __newindex = function(tab, key, val)
+ rawset(tab, slot_map[user_key_filter(key)], newtab)
+ end,
+
+ __index = function(tab, key)
+ return rawget(tab, slot_map[user_key_filter(key)])
+ end
+ }]]
+
+slot_map = make_user_table()
+
+slot_map.main = 0
+slot_map.sub = 1
+slot_map.range = 2
+slot_map.ranged = 2
+slot_map.ammo = 3
+slot_map.head = 4
+slot_map.body = 5
+slot_map.hands = 6
+slot_map.legs = 7
+slot_map.feet = 8
+slot_map.neck = 9
+slot_map.waist = 10
+slot_map.ear1 = 11
+slot_map.ear2 = 12
+slot_map.left_ear = 11
+slot_map.right_ear = 12
+slot_map.learring = 11
+slot_map.rearring = 12
+slot_map.lear = 11
+slot_map.rear = 12
+slot_map.left_ring = 13
+slot_map.right_ring = 14
+slot_map.lring = 13
+slot_map.rring = 14
+slot_map.ring1 = 13
+slot_map.ring2 = 14
+slot_map.back = 15
+
+
+
+gearswap_disabled = false
+seen_0x063_type9 = false
+delay_0x063_v9 = false
+not_sent_out_equip = {}
+command_registry = Command_Registry.new()
+equip_list = {}
+equip_list_history = {}
+world = make_user_table()
+buffactive = make_user_table()
+alliance = make_user_table()
+st_targs = {['<st>']=true,['<stpc>']=true,['<stal>']=true,['<stnpc>']=true,['<stpt>']=true}
+current_file = nil
+disable_table = {false,false,false,false,false,false,false,false,false,false,false,false,false,false,false}
+disable_table[0] = false
+outgoing_action_category_table = {['/ma']=3,['/ws']=7,['/ja']=9,['/ra']=16,['/ms']=25}
+encumbrance_table = table.reassign({},disable_table)
+registered_user_events = {}
+unhandled_command_events = {}
+empty = {name="empty"}
+--outgoing_packet_table = {}
+last_refresh = 0
+
+injected_equipment_registry = {}
+for i=0,15 do
+ injected_equipment_registry[i] = L{}
+end
+
+
+_global = make_user_table()
+_global.pretarget_cast_delay = 0
+_global.precast_cast_delay = 0
+_global.cancel_spell = false
+_global.current_event = 'None'
+
+_settings = {debug_mode = false, demo_mode = false, show_swaps = false}
+
+-- _ExtraData is persistent information that isn't included in the windower API.
+-- Because player, pet, and so forth are regularly regenerated from the windower API,
+-- this table is necessary to maintain information that goes beyond the windower API.
+_ExtraData = {
+ player = {buff_details = {}},
+ pet = {},
+ world = {in_mog_house = false,conquest=false},
+ }
+
+unbridled_learning_set = {['Thunderbolt']=true,['Harden Shell']=true,['Absolute Terror']=true,
+ ['Gates of Hades']=true,['Tourbillion']=true,['Pyric Bulwark']=true,['Bilgestorm']=true,
+ ['Bloodrake']=true,['Droning Whirlwind']=true,['Carcharian Verve']=true,['Blistering Roar']=true,
+ ['Uproot']=true,['Crashing Thunder']=true,['Polar Roar']=true,['Mighty Guard']=true,['Cruel Joke']=true,
+ ['Cesspool']=true,['Tearing Gust']=true}
+
+tool_map = {
+ ['Katon: Ichi'] = res.items[1161],
+ ['Katon: Ni'] = res.items[1161],
+ ['Katon: San'] = res.items[1161],
+ ['Hyoton: Ichi'] = res.items[1164],
+ ['Hyoton: Ni'] = res.items[1164],
+ ['Hyoton: San'] = res.items[1164],
+ ['Huton: Ichi'] = res.items[1167],
+ ['Huton: Ni'] = res.items[1167],
+ ['Huton: San'] = res.items[1167],
+ ['Doton: Ichi'] = res.items[1170],
+ ['Doton: Ni'] = res.items[1170],
+ ['Doton: San'] = res.items[1170],
+ ['Raiton: Ichi'] = res.items[1173],
+ ['Raiton: Ni'] = res.items[1173],
+ ['Raiton: San'] = res.items[1173],
+ ['Suiton: Ichi'] = res.items[1176],
+ ['Suiton: Ni'] = res.items[1176],
+ ['Suiton: San'] = res.items[1176],
+ ['Utsusemi: Ichi'] = res.items[1179],
+ ['Utsusemi: Ni'] = res.items[1179],
+ ['Utsusemi: San'] = res.items[1179],
+ ['Jubaku: Ichi'] = res.items[1182],
+ ['Jubaku: Ni'] = res.items[1182],
+ ['Jubaku: San'] = res.items[1182],
+ ['Hojo: Ichi'] = res.items[1185],
+ ['Hojo: Ni'] = res.items[1185],
+ ['Hojo: San'] = res.items[1185],
+ ['Kurayami: Ichi'] = res.items[1188],
+ ['Kurayami: Ni'] = res.items[1188],
+ ['Kurayami: San'] = res.items[1188],
+ ['Dokumori: Ichi'] = res.items[1191],
+ ['Dokumori: Ni'] = res.items[1191],
+ ['Dokumori: San'] = res.items[1191],
+ ['Tonko: Ichi'] = res.items[1194],
+ ['Tonko: Ni'] = res.items[1194],
+ ['Tonko: San'] = res.items[1194],
+ ['Monomi: Ichi'] = res.items[2553],
+ ['Monomi: Ni'] = res.items[2553],
+ ['Aisha: Ichi'] = res.items[2555],
+ ['Myoshu: Ichi'] = res.items[2642],
+ ['Yurin: Ichi'] = res.items[2643],
+ ['Migawari: Ichi'] = res.items[2970],
+ ['Kakka: Ichi'] = res.items[2644],
+ ['Gekka: Ichi'] = res.items[8803],
+ ['Yain: Ichi'] = res.items[8804],
+ }
+
+universal_tool_map = {
+ ['Katon: Ichi'] = res.items[2971],
+ ['Katon: Ni'] = res.items[2971],
+ ['Katon: San'] = res.items[2971],
+ ['Hyoton: Ichi'] = res.items[2971],
+ ['Hyoton: Ni'] = res.items[2971],
+ ['Hyoton: San'] = res.items[2971],
+ ['Huton: Ichi'] = res.items[2971],
+ ['Huton: Ni'] = res.items[2971],
+ ['Huton: San'] = res.items[2971],
+ ['Doton: Ichi'] = res.items[2971],
+ ['Doton: Ni'] = res.items[2971],
+ ['Doton: San'] = res.items[2971],
+ ['Raiton: Ichi'] = res.items[2971],
+ ['Raiton: Ni'] = res.items[2971],
+ ['Raiton: San'] = res.items[2971],
+ ['Suiton: Ichi'] = res.items[2971],
+ ['Suiton: Ni'] = res.items[2971],
+ ['Suiton: San'] = res.items[2971],
+ ['Utsusemi: Ichi'] = res.items[2972],
+ ['Utsusemi: Ni'] = res.items[2972],
+ ['Utsusemi: San'] = res.items[2972],
+ ['Jubaku: Ichi'] = res.items[2973],
+ ['Jubaku: Ni'] = res.items[2973],
+ ['Jubaku: San'] = res.items[2973],
+ ['Hojo: Ichi'] = res.items[2973],
+ ['Hojo: Ni'] = res.items[2973],
+ ['Hojo: San'] = res.items[2973],
+ ['Kurayami: Ichi'] = res.items[2973],
+ ['Kurayami: Ni'] = res.items[2973],
+ ['Kurayami: San'] = res.items[2973],
+ ['Dokumori: Ichi'] = res.items[2973],
+ ['Dokumori: Ni'] = res.items[2973],
+ ['Dokumori: San'] = res.items[2973],
+ ['Tonko: Ichi'] = res.items[2972],
+ ['Tonko: Ni'] = res.items[2972],
+ ['Tonko: San'] = res.items[2972],
+ ['Monomi: Ichi'] = res.items[2972],
+ ['Aisha: Ichi'] = res.items[2973],
+ ['Myoshu: Ichi'] = res.items[2972],
+ ['Yurin: Ichi'] = res.items[2973],
+ ['Migawari: Ichi'] = res.items[2972],
+ ['Kakka: Ichi'] = res.items[2972],
+ ['Gekka: Ichi'] = res.items[2972],
+ ['Yain: Ichi'] = res.items[2972],
+ }
+
+region_to_zone_map = {
+ [4] = S{100,101,139,140,141,142,167,190},
+ [5] = S{102,103,108,193,196,248},
+ [6] = S{1,2,104,105,149,150,195},
+ [7] = S{106,107,143,144,172,173,191},
+ [8] = S{109,110,147,148,197},
+ [9] = S{115,116,145,146,169,170,192,194},
+ [10] = S{3,4,117,118,198,213,249},
+ [11] = S{7,8,119,120,151,152,200},
+ [12] = S{9,10,111,166,203,204,206},
+ [13] = S{5,6,112,161,162,165},
+ [14] = S{126,127,157,158,179,184},
+ [15] = S{121,122,153,154,202,251},
+ [16] = S{114,125,168,208,209,247},
+ [17] = S{113,128.174,201,212},
+ [18] = S{123,176,250,252},
+ [19] = S{124,159,160,163,205,207,211},
+ [20] = S{130,177,178,180,181},
+ [22] = S{11,12,13},
+ [24] = S{24,25,26,27,28,29,30,31,32},
+ }
+
+
+function initialize_globals()
+ local pl = windower.ffxi.get_player()
+ if not pl then
+ player = make_user_table()
+ player.vitals = {}
+ player.buffs = {}
+ player.skills = {}
+ player.jobs = {}
+ player.merits = {}
+ else
+ player = make_user_table()
+ table.reassign(player,pl)
+ if not player.vitals then player.vitals = {} end
+ if not player.buffs then player.buffs = {} end
+ if not player.skills then player.skills = {} end
+ if not player.jobs then player.jobs = {} end
+ if not player.merits then player.merits = {} end
+ end
+
+ player.equipment = make_user_table()
+ pet = make_user_table()
+ pet.isvalid = false
+ fellow = make_user_table()
+ fellow.isvalid = false
+ partybuffs = {}
+
+ -- GearSwap effectively needs to maintain two inventory structures:
+ -- one is the proposed current inventory based on equip packets sent to the server,
+ -- the other is the currently reported inventory based on packets sent from the server.
+ -- The problem with proposed_inv is that it doesn't know when actions force items to unequip or prevent them from equipping.
+ -- The problem with reported_inv is that packets can be dropped, so it doesn't always report everything accurately.
+ -- In an ideal world, gearswap would maintain a registry of expected changes for each slot,
+ -- and would advance along the registry as changes are reported by the server.
+ items = windower.ffxi.get_items()
+ if not items then
+ items = {
+ equipment = {},
+ }
+ for id,name in pairs(default_slot_map) do
+ items.equipment[name] = {slot = empty,bag_id=0}
+ end
+ else
+ if not items.equipment then
+ items.equipment = {}
+ for id,name in pairs(default_slot_map) do
+ items.equipment[name] = {slot = empty,bag_id=0}
+ end
+ else
+ for id,name in pairs(default_slot_map) do
+ items.equipment[name] = {
+ slot = items.equipment[name],
+ bag_id = items.equipment[name..'_bag']
+ }
+ items.equipment[name..'_bag'] = nil
+ if items.equipment[name].slot == 0 then items.equipment[name].slot = empty end
+ end
+ end
+ end
+ for i in pairs(windower.ffxi.get_bag_info()) do
+ if not items[i] then items[i] = make_inventory_table()
+ else items[i][0] = make_empty_item_table(0) end
+ end
+
+ local wo = windower.ffxi.get_info()
+ if wo then
+ for i,v in pairs(region_to_zone_map) do
+ if v:contains(wo.zone) then
+ _ExtraData.world.conquest = {
+ region_id = i,
+ region_name = res.regions[i][language],
+ }
+ break
+ end
+ end
+ end
+end
+
+initialize_globals()