summaryrefslogtreecommitdiff
path: root/Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/libs/organizer-lib.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/libs/organizer-lib.lua')
-rw-r--r--Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/libs/organizer-lib.lua237
1 files changed, 237 insertions, 0 deletions
diff --git a/Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/libs/organizer-lib.lua b/Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/libs/organizer-lib.lua
new file mode 100644
index 0000000..c3111f6
--- /dev/null
+++ b/Data/BuiltIn/Libraries/lua-addons/addons/GearSwap/libs/organizer-lib.lua
@@ -0,0 +1,237 @@
+-- Organizer library v2
+
+local org = {}
+register_unhandled_command(function(...)
+ local cmds = {...}
+ for _,v in ipairs(cmds) do
+ if S{'organizer','organize','org','o'}:contains(v:lower()) then
+ org.export_set()
+ return true
+ end
+ end
+ return false
+end)
+
+
+function org.export_set()
+ if not sets then
+ windower.add_to_chat(123,'Organizer Library: Cannot export your sets for collection because the table is nil.')
+ return
+ elseif not windower.dir_exists(windower.windower_path..'addons/organizer/') then
+ windower.add_to_chat(123,'Organizer Library: The organizer addon is not installed. Activate it in the launcher.')
+ return
+ end
+
+ -- Makes a big table keyed to item resource tables, with values that are 1-based
+ -- numerically indexed tables of different entries for each of the items from the sets table.
+ local item_list = org.unpack_names({},'L1',sets,{})
+
+ local trans_item_list = org.identify_items(item_list)
+
+ for i,v in pairs(trans_item_list) do
+ trans_item_list[i] = org.simplify_entry(v)
+ end
+
+ if trans_item_list:length() == 0 then
+ windower.add_to_chat(123,'Organizer Library: Your sets table is empty.')
+ return
+ end
+
+ local flattab = T{}
+ for name,tab in pairs(trans_item_list) do
+ for _,info in ipairs(tab) do
+ flattab:append({id=tab.id,name=tab.name,log_name=tab.log_name,augments=info.augments,count=info.count})
+ end
+ end
+
+ -- See if we have any non-equipment items to drag along
+ if organizer_items then
+ local organizer_item_list = org.unpack_names({}, 'L1', organizer_items, {})
+
+ for _,tab in pairs(org.identify_items(organizer_item_list)) do
+ count = gearswap.res.items[tab.id].stack
+ flattab:append({id=tab.id,name=tab.name,log_name=tab.log_name,count=count})
+ end
+ end
+
+ -- At this point I have a table of equipment pieces indexed by the inventory name.
+ -- I need to make a function that will translate that into a list of pieces in
+ -- inventory or wardrobe.
+ -- #trans_item_list[i] = Number of a given item
+ -- trans_item_list[i].id = item ID
+
+ local ward_ids = {8,10,11,12}
+ local wardrobes = {}
+ local ward = {}
+
+ for _,id in pairs(ward_ids) do
+ wardrobes[id] = windower.ffxi.get_items(id)
+ wardrobes[id].max = windower.ffxi.get_bag_info(id).max
+ ward[id] = T{}
+ end
+
+ local inv = T{}
+ for i,v in ipairs(flattab) do
+ local found
+ local ward_id
+ -- Iterate over the wardrobes and look for gear from the list that is already in wardrobes, then eliminate it from the list
+ for id,wardrobe in pairs(wardrobes) do
+ for n,m in ipairs(wardrobe) do
+ if m.id == v.id and (not v.augments or v.augments and gearswap.extdata.decode(m).augments and gearswap.extdata.compare_augments(v.augments,gearswap.extdata.decode(m).augments)) then
+ found = n
+ break
+ end
+ end
+ if found then
+ ward_id = id
+ break
+ end
+ end
+ if found then
+ table.remove(wardrobes[ward_id],found)
+ ward[ward_id]:append(v)
+ else
+ inv:append(v)
+ end
+ end
+
+ local inventory_max = windower.ffxi.get_bag_info(0).max
+
+ for id=1,4 do
+ if #inv > inventory_max and #ward[id] + (#inv-inventory_max) < wardrobes[id].max then
+ local available = wardrobes[id].max - #ward[id]
+ local length = math.min(#inv-80,available)
+ ward:extend(inv:slice(1-length))
+ end
+ end
+
+ if #inv > inventory_max then
+ windower.add_to_chat(123,'Organizer Library: Your sets table contains too many items.')
+ return
+ end
+
+ -- Scan wardrobe, eliminate items from your table that are in wardrobe
+ -- Scan inventory
+
+ local fi = file.new('../organizer/data/inventory/organizer-lib-file.lua')
+ fi:write('-- Generated by the Organizer Library ('..os.date()..')\nreturn '..(inv:tovstring({'augments','log_name','name','id','count'})))
+
+ for _,id in ipairs(ward_ids) do
+ local fw = file.new('../organizer/data/'..gearswap.res.bags[id].command..'/organizer-lib-file.lua')
+ fw:write('-- Generated by the Organizer Library ('..os.date()..')\nreturn '..(ward[id]:tovstring({'augments','log_name','name','id','count'})))
+ end
+
+ windower.send_command('wait 0.5;org o organizer-lib-file')
+end
+
+function org.simplify_entry(tab)
+ -- Some degree of this needs to be done in unpack_names or I won't be able to detect when two identical augmented items are equipped.
+ local output = T{id=tab.id,name=tab.name,log_name=tab.log_name}
+ local rare = gearswap.res.items[tab.id].flags:contains('Rare')
+ for i,v in ipairs(tab) do
+ local handled = false
+ if v.augment then
+ v.augments = {v.augment}
+ v.augment = nil
+ end
+
+ for n,m in ipairs(output) do
+ if (not v.bag or v.bag and v.bag == m.bag) and v.slot == m.slot and
+ (not v.augments or ( m.augments and gearswap.extdata.compare_augments(v.augments,m.augments))) then
+ output[n].count = math.min(math.max(output[n].count,v.count),gearswap.res.items[tab.id].stack)
+ handled = true
+ break
+ elseif (not v.bag or v.bag and v.bag == m.bag) and v.slot == m.slot and v.augments and not m.augments then
+ -- v has augments, but there currently exists a matching version of the
+ -- item without augments in the output table. Replace the entry with the augmented entry
+ local countmax = math.min(math.max(output[n].count,v.count),gearswap.res.items[tab.id].stack)
+ output[n] = v
+ output[n].count = countmax
+ handled = true
+ break
+ elseif rare then
+ handled = true
+ break
+ end
+ end
+ if not handled then
+ output:append(v)
+ end
+
+ end
+ return output
+end
+
+function org.identify_items(tab)
+ local name_to_id_map = {}
+ local items = windower.ffxi.get_items()
+ for id,inv in pairs(items) do
+ if type(inv) == 'table' then
+ for ind,item in ipairs(inv) do
+ if type(item) == 'table' and item.id and item.id ~= 0 then
+ name_to_id_map[gearswap.res.items[item.id][gearswap.language]:lower()] = item.id
+ name_to_id_map[gearswap.res.items[item.id][gearswap.language..'_log']:lower()] = item.id
+ end
+ end
+ end
+ end
+ local trans = T{}
+ for i,v in pairs(tab) do
+ local item = name_to_id_map[i:lower()] and table.reassign({},gearswap.res.items[name_to_id_map[i:lower()]]) --and org.identify_unpacked_name(i,name_to_id_map)
+ if item then
+ local n = gearswap.res.items[item.id][gearswap.language]:lower()
+ local ln = gearswap.res.items[item.id][gearswap.language..'_log']:lower()
+ if not trans[n] then
+ trans[n] = T{id=item.id,
+ name=n,
+ log_name=ln,
+ }
+ end
+ trans[n]:extend(v)
+ end
+ end
+ return trans
+end
+
+function org.unpack_names(ret_tab,up,tab_level,unpacked_table)
+ for i,v in pairs(tab_level) do
+ local flag = false
+ if type(v)=='table' and i ~= 'augments' and not ret_tab[tostring(tab_level[i])] then
+ ret_tab[tostring(tab_level[i])] = true
+ unpacked_table, ret_tab = org.unpack_names(ret_tab,i,v,unpacked_table)
+ elseif i=='name' then
+ -- v is supposed to be a name, then.
+ flag = true
+ elseif type(v) == 'string' and v~='augment' and v~= 'augments' and v~= 'priority' then
+ -- v is a string that's not any known option of gearswap, so treat it as an item name.
+ -- I really need to make a set of the known advanced table options and use that instead.
+ flag = true
+ end
+ if flag then
+ local n = tostring(v):lower()
+ if not unpacked_table[n] then unpacked_table[n] = {} end
+ local ind = #unpacked_table[n] + 1
+ if i == 'name' and gearswap.slot_map[tostring(up):lower()] then -- Advanced Table
+ unpacked_table[n][ind] = tab_level
+ unpacked_table[n][ind].count = unpacked_table[n][ind].count or 1
+ unpacked_table[n][ind].slot = gearswap.slot_map[up:lower()]
+ elseif gearswap.slot_map[tostring(i):lower()] then
+ unpacked_table[n][ind] = {slot=gearswap.slot_map[i:lower()],count=1}
+ end
+ end
+ end
+ return unpacked_table, ret_tab
+end
+
+function org.string_augments(tab)
+ local aug_str = ''
+ if tab.augments then
+ for aug_ind,augment in pairs(tab.augments) do
+ if augment ~= 'none' then aug_str = aug_str..'['..aug_ind..'] = '..'"'..augment..'",\n' end
+ end
+ end
+ if tab.augment then
+ if tab.augment ~= 'none' then aug_str = aug_str.."'"..augment.."'," end
+ end
+ if aug_str ~= '' then return '{\n'..aug_str..'}' end
+end \ No newline at end of file