-
Notifications
You must be signed in to change notification settings - Fork 0
/
organizer-lib.lua
237 lines (210 loc) · 9.17 KB
/
organizer-lib.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
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,13,14,15,16}
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