Zerotorescue@80
|
1 local addon = select(2, ...);
|
Zerotorescue@84
|
2 local mod = addon:NewModule("Scanner", "AceEvent-3.0", "AceTimer-3.0");
|
Zerotorescue@80
|
3
|
Zerotorescue@122
|
4 local _G = _G;
|
Zerotorescue@122
|
5 local select, pairs = _G.select, _G.pairs;
|
Zerotorescue@122
|
6 local twipe, tinsert, mceil = _G.table.wipe, _G.table.insert, _G.math.ceil;
|
Zerotorescue@122
|
7
|
Zerotorescue@101
|
8 local Mover, paused, currentLocation;
|
Zerotorescue@80
|
9 local itemCache = {};
|
Zerotorescue@80
|
10
|
Zerotorescue@110
|
11 local function OnMoveAccept()
|
Zerotorescue@101
|
12 mod:Pause();
|
Zerotorescue@101
|
13 Mover:BeginMove(currentLocation, mod.Unpause);
|
Zerotorescue@101
|
14
|
Zerotorescue@142
|
15 if InventoriumItemMover then
|
Zerotorescue@142
|
16 InventoriumItemMover:Hide();
|
Zerotorescue@142
|
17 end
|
Zerotorescue@101
|
18 end
|
Zerotorescue@101
|
19
|
Zerotorescue@110
|
20 local function OnMoveCancel()
|
Zerotorescue@101
|
21 Mover:ResetQueue();
|
Zerotorescue@101
|
22 currentLocation = nil;
|
Zerotorescue@101
|
23
|
Zerotorescue@142
|
24 if InventoriumItemMover then
|
Zerotorescue@142
|
25 InventoriumItemMover:Hide();
|
Zerotorescue@142
|
26 end
|
Zerotorescue@101
|
27 end
|
Zerotorescue@101
|
28
|
Zerotorescue@119
|
29 local function GetSmallCoinTextureString(coins)
|
Zerotorescue@119
|
30 if coins >= 10000000 then
|
Zerotorescue@119
|
31 -- When we have1000g, hide silver and copper
|
Zerotorescue@122
|
32 coins = (mceil(coins / 10000) * 10000);
|
Zerotorescue@119
|
33 elseif coins >= 10000 then
|
Zerotorescue@119
|
34 -- When we have 1g, hide copper
|
Zerotorescue@122
|
35 coins = (mceil(coins / 100) * 100);
|
Zerotorescue@119
|
36 end
|
Zerotorescue@119
|
37
|
Zerotorescue@119
|
38 return GetCoinTextureString(coins);
|
Zerotorescue@119
|
39 end
|
Zerotorescue@119
|
40
|
Zerotorescue@119
|
41 -- Refill moves window: refill form storage such as the bank, guild bank and mailbox
|
Zerotorescue@111
|
42 local function UseStorageRefillST()
|
Zerotorescue@142
|
43 if not InventoriumItemMover then
|
Zerotorescue@142
|
44 addon:CreateMoverFrame();
|
Zerotorescue@142
|
45 end
|
Zerotorescue@142
|
46
|
Zerotorescue@110
|
47 local frame = InventoriumItemMover; -- both for speed as code-consistency
|
Zerotorescue@110
|
48
|
Zerotorescue@110
|
49 -- Scrolling table with a list of items to be moved
|
Zerotorescue@110
|
50 local scrollTableWidth = ( frame.frmMeasureDummy:GetWidth() - 30 ); -- adjust width by the scrollbar size
|
Zerotorescue@110
|
51 local headers = {
|
Zerotorescue@110
|
52 {
|
Zerotorescue@110
|
53 ["name"] = "Item",
|
Zerotorescue@111
|
54 ["width"] = (scrollTableWidth * .60),
|
Zerotorescue@110
|
55 ["defaultsort"] = "asc",
|
Zerotorescue@110
|
56 ["comparesort"] = function(this, aRow, bRow, column)
|
Zerotorescue@110
|
57 local aName, _, aRarity = GetItemInfo(this:GetRow(aRow).rowData.itemId);
|
Zerotorescue@110
|
58 local bName, _, bRarity = GetItemInfo(this:GetRow(bRow).rowData.itemId);
|
Zerotorescue@110
|
59 local template = "%d%s";
|
Zerotorescue@110
|
60 aName = template:format((10 - (aRarity or 10)), (aName or ""):lower());
|
Zerotorescue@110
|
61 bName = template:format((10 - (bRarity or 10)), (bName or ""):lower());
|
Zerotorescue@110
|
62
|
Zerotorescue@110
|
63 if this.cols[column].sort == "dsc" then
|
Zerotorescue@110
|
64 return aName > bName;
|
Zerotorescue@110
|
65 else
|
Zerotorescue@110
|
66 return aName < bName;
|
Zerotorescue@110
|
67 end
|
Zerotorescue@110
|
68 end,
|
Zerotorescue@110
|
69 ["sort"] = "asc", -- when the data is set, use this column so sort the default data
|
Zerotorescue@144
|
70 ["tooltipTitle"] = "Item",
|
Zerotorescue@144
|
71 ["tooltip"] = "Click to sort the list by item quality then item name.",
|
Zerotorescue@110
|
72 },
|
Zerotorescue@110
|
73 {
|
Zerotorescue@110
|
74 ["name"] = "Moving",
|
Zerotorescue@110
|
75 ["width"] = (scrollTableWidth * .15),
|
Zerotorescue@110
|
76 ["align"] = "RIGHT",
|
Zerotorescue@110
|
77 ["defaultsort"] = "dsc",
|
Zerotorescue@110
|
78 ["sortnext"] = 1,
|
Zerotorescue@144
|
79 ["tooltipTitle"] = "Moving",
|
Zerotorescue@144
|
80 ["tooltip"] = "Click to sort the list by the amount of movable items.",
|
Zerotorescue@110
|
81 },
|
Zerotorescue@110
|
82 {
|
Zerotorescue@110
|
83 ["name"] = "Available",
|
Zerotorescue@111
|
84 ["width"] = (scrollTableWidth * .25),
|
Zerotorescue@110
|
85 ["align"] = "RIGHT",
|
Zerotorescue@110
|
86 ["defaultsort"] = "dsc",
|
Zerotorescue@110
|
87 ["sortnext"] = 1,
|
Zerotorescue@110
|
88 ["comparesort"] = function(this, aRow, bRow, column)
|
Zerotorescue@110
|
89 local aAvailablePercent = (this:GetRow(aRow).rowData.available / this:GetRow(aRow).rowData.missing);
|
Zerotorescue@110
|
90 local bAvailablePercent = (this:GetRow(bRow).rowData.available / this:GetRow(bRow).rowData.missing);
|
Zerotorescue@110
|
91
|
Zerotorescue@110
|
92 if this.cols[column].sort == "dsc" then
|
Zerotorescue@110
|
93 return aAvailablePercent > bAvailablePercent;
|
Zerotorescue@110
|
94 else
|
Zerotorescue@110
|
95 return aAvailablePercent < bAvailablePercent;
|
Zerotorescue@110
|
96 end
|
Zerotorescue@110
|
97 end,
|
Zerotorescue@144
|
98 ["tooltipTitle"] = "Item",
|
Zerotorescue@144
|
99 ["tooltip"] = "Click to sort the list by the availibility percentage.",
|
Zerotorescue@110
|
100 },
|
Zerotorescue@110
|
101 };
|
Zerotorescue@110
|
102
|
Zerotorescue@110
|
103 local proceedButton = {
|
Zerotorescue@110
|
104 text = "Move Items",
|
Zerotorescue@144
|
105 tooltipTitle = "Move Items",
|
Zerotorescue@144
|
106 tooltip = "Start moving these items from the bank.",
|
Zerotorescue@110
|
107 onClick = OnMoveAccept,
|
Zerotorescue@110
|
108 };
|
Zerotorescue@110
|
109 local cancelButton = {
|
Zerotorescue@110
|
110 text = "Cancel",
|
Zerotorescue@144
|
111 tooltipTitle = "Cancel",
|
Zerotorescue@144
|
112 tooltip = "Do not move anything and close the window.",
|
Zerotorescue@110
|
113 onClick = OnMoveCancel,
|
Zerotorescue@110
|
114 };
|
Zerotorescue@110
|
115
|
Zerotorescue@132
|
116 addon:SetMoverFrameSettings("Inventorium Storage Refill", "The items listed below can be refilled from this location, do you wish to move them to your bags?", proceedButton, cancelButton, headers);
|
Zerotorescue@119
|
117 end
|
Zerotorescue@119
|
118
|
Zerotorescue@119
|
119 -- Merchant restock window: restock from a merchant by buying items needed
|
Zerotorescue@119
|
120 local function UseMerchantRestockST(totalCost)
|
Zerotorescue@142
|
121 if not InventoriumItemMover then
|
Zerotorescue@142
|
122 addon:CreateMoverFrame();
|
Zerotorescue@142
|
123 end
|
Zerotorescue@142
|
124
|
Zerotorescue@119
|
125 local frame = InventoriumItemMover; -- both for speed as code-consistency
|
Zerotorescue@119
|
126
|
Zerotorescue@119
|
127 -- Scrolling table with a list of items to be moved
|
Zerotorescue@119
|
128 local scrollTableWidth = ( frame.frmMeasureDummy:GetWidth() - 30 ); -- adjust width by the scrollbar size
|
Zerotorescue@119
|
129 local headers = {
|
Zerotorescue@119
|
130 {
|
Zerotorescue@119
|
131 ["name"] = "Item",
|
Zerotorescue@119
|
132 ["width"] = (scrollTableWidth * .60),
|
Zerotorescue@119
|
133 ["defaultsort"] = "asc",
|
Zerotorescue@119
|
134 ["comparesort"] = function(this, aRow, bRow, column)
|
Zerotorescue@119
|
135 local aName, _, aRarity = GetItemInfo(this:GetRow(aRow).rowData.itemId);
|
Zerotorescue@119
|
136 local bName, _, bRarity = GetItemInfo(this:GetRow(bRow).rowData.itemId);
|
Zerotorescue@119
|
137 local template = "%d%s";
|
Zerotorescue@119
|
138 aName = template:format((10 - (aRarity or 10)), (aName or ""):lower());
|
Zerotorescue@119
|
139 bName = template:format((10 - (bRarity or 10)), (bName or ""):lower());
|
Zerotorescue@119
|
140
|
Zerotorescue@119
|
141 if this.cols[column].sort == "dsc" then
|
Zerotorescue@119
|
142 return aName > bName;
|
Zerotorescue@119
|
143 else
|
Zerotorescue@119
|
144 return aName < bName;
|
Zerotorescue@119
|
145 end
|
Zerotorescue@119
|
146 end,
|
Zerotorescue@119
|
147 ["sort"] = "asc", -- when the data is set, use this column so sort the default data
|
Zerotorescue@144
|
148 ["tooltipTitle"] = "Item",
|
Zerotorescue@144
|
149 ["tooltip"] = "Click to sort the list by item quality then item name.",
|
Zerotorescue@119
|
150 },
|
Zerotorescue@119
|
151 {
|
Zerotorescue@119
|
152 ["name"] = "Buying",
|
Zerotorescue@119
|
153 ["width"] = (scrollTableWidth * .20),
|
Zerotorescue@119
|
154 ["align"] = "RIGHT",
|
Zerotorescue@119
|
155 ["defaultsort"] = "dsc",
|
Zerotorescue@119
|
156 ["sortnext"] = 1,
|
Zerotorescue@144
|
157 ["tooltipTitle"] = "Buying",
|
Zerotorescue@144
|
158 ["tooltip"] = "Click to sort the list by the amount of purchasable items.",
|
Zerotorescue@119
|
159 },
|
Zerotorescue@119
|
160 {
|
Zerotorescue@119
|
161 ["name"] = "Cost",
|
Zerotorescue@119
|
162 ["width"] = (scrollTableWidth * .20),
|
Zerotorescue@119
|
163 ["align"] = "RIGHT",
|
Zerotorescue@119
|
164 ["defaultsort"] = "dsc",
|
Zerotorescue@119
|
165 ["sortnext"] = 1,
|
Zerotorescue@144
|
166 ["tooltipTitle"] = "Cost",
|
Zerotorescue@144
|
167 ["tooltip"] = "Click to sort the list by the total cost of buying all these items.",
|
Zerotorescue@119
|
168 },
|
Zerotorescue@119
|
169 };
|
Zerotorescue@119
|
170
|
Zerotorescue@119
|
171 local proceedButton = {
|
Zerotorescue@119
|
172 text = "Purchase Items",
|
Zerotorescue@144
|
173 tooltipTitle = "Purchase Items",
|
Zerotorescue@144
|
174 tooltip = "Start purchasing these items from this merchant.",
|
Zerotorescue@119
|
175 onClick = OnMoveAccept,
|
Zerotorescue@119
|
176 };
|
Zerotorescue@119
|
177 local cancelButton = {
|
Zerotorescue@119
|
178 text = "Cancel",
|
Zerotorescue@144
|
179 tooltipTitle = "Cancel",
|
Zerotorescue@144
|
180 tooltip = "Do not purchase anything and close the window.",
|
Zerotorescue@119
|
181 onClick = OnMoveCancel,
|
Zerotorescue@119
|
182 };
|
Zerotorescue@119
|
183
|
Zerotorescue@132
|
184 addon:SetMoverFrameSettings("Inventorium Merchant Restock", ("The following items can be restocked from this merchant for a total of %s. Do you wish to proceed?"):format(GetSmallCoinTextureString(totalCost)), proceedButton, cancelButton, headers);
|
Zerotorescue@110
|
185 end
|
Zerotorescue@110
|
186
|
Zerotorescue@80
|
187 function mod:ClearCache()
|
Zerotorescue@122
|
188 twipe(itemCache);
|
Zerotorescue@80
|
189 end
|
Zerotorescue@80
|
190
|
Zerotorescue@80
|
191 function mod:CacheLocation(location, remember)
|
Zerotorescue@89
|
192 -- Reset cache just in case it was filled
|
Zerotorescue@89
|
193 self:ClearCache();
|
Zerotorescue@89
|
194
|
Zerotorescue@80
|
195 if location == addon.Locations.Bag or location == addon.Locations.Bank then
|
Zerotorescue@80
|
196 local start, stop;
|
Zerotorescue@80
|
197 if location == addon.Locations.Bag then
|
Zerotorescue@80
|
198 start = 0;
|
Zerotorescue@80
|
199 stop = NUM_BAG_SLOTS;
|
Zerotorescue@80
|
200 else
|
Zerotorescue@80
|
201 -- If we requested the bank then we don't want the bag info
|
Zerotorescue@80
|
202 start = ( NUM_BAG_SLOTS + 1 );
|
Zerotorescue@80
|
203 stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS );
|
Zerotorescue@80
|
204 end
|
Zerotorescue@80
|
205
|
Zerotorescue@80
|
206 -- Go through all our bags, including the backpack
|
Zerotorescue@81
|
207 for i = start, ((location == addon.Locations.Bag and stop) or (location == addon.Locations.Bank and (stop + 1))) do -- if scanning bags stop at normal bag slot, if scanning bank, stop one later to allow BANK_CONTAINER to be scanned too
|
Zerotorescue@80
|
208 -- Scan the default 100 slots whenever we're at a non-existing index
|
Zerotorescue@80
|
209 local bagId = (i == (stop + 1) and BANK_CONTAINER) or i;
|
Zerotorescue@80
|
210 local slotId = GetContainerNumSlots(bagId);
|
Zerotorescue@80
|
211
|
Zerotorescue@80
|
212 while slotId ~= 0 do
|
Zerotorescue@80
|
213 -- A not equal-comparison should be quicker than a larger than-comparison
|
Zerotorescue@80
|
214
|
Zerotorescue@80
|
215 local itemId = GetContainerItemID(bagId, slotId);
|
Zerotorescue@80
|
216 local itemCount = itemId and select(2, GetContainerItemInfo(bagId, slotId));
|
Zerotorescue@80
|
217
|
Zerotorescue@80
|
218 if itemId and itemCount and itemCount > 0 then
|
Zerotorescue@119
|
219 local containerItem;
|
Zerotorescue@80
|
220 if not itemCache[itemId] then
|
Zerotorescue@80
|
221 -- If this is the first time we see this item, make a new object
|
Zerotorescue@119
|
222 containerItem = addon.ContainerItem:New();
|
Zerotorescue@119
|
223 itemCache[itemId] = containerItem;
|
Zerotorescue@80
|
224 else
|
Zerotorescue@80
|
225 -- If we had this item in another slot too
|
Zerotorescue@119
|
226 containerItem = itemCache[itemId];
|
Zerotorescue@80
|
227 end
|
Zerotorescue@80
|
228
|
Zerotorescue@119
|
229 containerItem:AddLocation(bagId, slotId, itemCount);
|
Zerotorescue@80
|
230 end
|
Zerotorescue@80
|
231
|
Zerotorescue@80
|
232 -- Continue scanning a different slot
|
Zerotorescue@80
|
233 slotId = (slotId - 1);
|
Zerotorescue@80
|
234 end
|
Zerotorescue@80
|
235 end
|
Zerotorescue@80
|
236 elseif location == addon.Locations.Guild then
|
Zerotorescue@84
|
237 for tabId = 1, GetNumGuildBankTabs() do
|
Zerotorescue@110
|
238 local _, _, isViewable, _, _, remainingWithdrawals = GetGuildBankTabInfo(tabId);
|
Zerotorescue@80
|
239
|
Zerotorescue@110
|
240 if isViewable and (remainingWithdrawals > 0 or remainingWithdrawals == -1) then
|
Zerotorescue@84
|
241 local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot
|
Zerotorescue@80
|
242
|
Zerotorescue@84
|
243 while slotId ~= 0 do
|
Zerotorescue@84
|
244 -- A not equal-comparison should be quicker than a larger than-comparison
|
Zerotorescue@84
|
245
|
Zerotorescue@84
|
246 local itemLink = GetGuildBankItemLink(tabId, slotId);
|
Zerotorescue@95
|
247 local itemId = itemLink and addon:GetItemId(itemLink);
|
Zerotorescue@84
|
248 local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId));
|
Zerotorescue@84
|
249
|
Zerotorescue@84
|
250 if itemLink and itemId and itemCount and itemCount > 0 then
|
Zerotorescue@84
|
251 -- If there is actually an item in this slot
|
Zerotorescue@119
|
252 local containerItem;
|
Zerotorescue@84
|
253 if not itemCache[itemId] then
|
Zerotorescue@84
|
254 -- If this is the first time we see this item, make a new object
|
Zerotorescue@119
|
255 containerItem = addon.ContainerItem:New();
|
Zerotorescue@119
|
256 itemCache[itemId] = containerItem;
|
Zerotorescue@84
|
257 else
|
Zerotorescue@84
|
258 -- If we had this item in another slot too
|
Zerotorescue@119
|
259 containerItem = itemCache[itemId];
|
Zerotorescue@84
|
260 end
|
Zerotorescue@84
|
261
|
Zerotorescue@119
|
262 containerItem:AddLocation(tabId, slotId, itemCount);
|
Zerotorescue@84
|
263 end
|
Zerotorescue@84
|
264
|
Zerotorescue@84
|
265 -- Continue scanning a different slot
|
Zerotorescue@84
|
266 slotId = (slotId - 1);
|
Zerotorescue@80
|
267 end
|
Zerotorescue@80
|
268 end
|
Zerotorescue@80
|
269 end
|
Zerotorescue@110
|
270 elseif location == addon.Locations.Mailbox then
|
Zerotorescue@110
|
271 for mailIndex = 1, GetInboxNumItems() do
|
Zerotorescue@110
|
272 -- All mail items
|
Zerotorescue@110
|
273
|
Zerotorescue@110
|
274 for attachIndex = 1, ATTACHMENTS_MAX_RECEIVE do
|
Zerotorescue@110
|
275 -- All attachments
|
Zerotorescue@110
|
276
|
Zerotorescue@110
|
277 local itemLink = GetInboxItemLink(mailIndex, attachIndex);
|
Zerotorescue@110
|
278 local itemId = itemLink and addon:GetItemId(itemLink);
|
Zerotorescue@110
|
279 local itemCount = itemLink and select(3, GetInboxItem(mailIndex, attachIndex));
|
Zerotorescue@110
|
280
|
Zerotorescue@110
|
281 if itemLink and itemId and itemCount and itemCount > 0 then
|
Zerotorescue@119
|
282 local containerItem;
|
Zerotorescue@110
|
283 if not itemCache[itemId] then
|
Zerotorescue@110
|
284 -- If this is the first time we see this item, make a new object
|
Zerotorescue@119
|
285 containerItem = addon.ContainerItem:New();
|
Zerotorescue@119
|
286 itemCache[itemId] = containerItem;
|
Zerotorescue@110
|
287 else
|
Zerotorescue@110
|
288 -- If we had this item in another slot too
|
Zerotorescue@119
|
289 containerItem = itemCache[itemId];
|
Zerotorescue@110
|
290 end
|
Zerotorescue@110
|
291
|
Zerotorescue@119
|
292 containerItem:AddLocation(mailIndex, attachIndex, itemCount);
|
Zerotorescue@110
|
293 end
|
Zerotorescue@110
|
294 end
|
Zerotorescue@110
|
295 end
|
Zerotorescue@119
|
296 elseif location == addon.Locations.Merchant then
|
Zerotorescue@119
|
297 for itemIndex = 1, GetMerchantNumItems() do
|
Zerotorescue@119
|
298 -- All merchant items
|
Zerotorescue@119
|
299
|
Zerotorescue@119
|
300 local itemLink = GetMerchantItemLink(itemIndex);
|
Zerotorescue@119
|
301 local itemId = itemLink and addon:GetItemId(itemLink);
|
Zerotorescue@119
|
302 local _, _, vendorValue, quantity, numAvailable, _, extendedCost = GetMerchantItemInfo(itemIndex);
|
Zerotorescue@119
|
303
|
Zerotorescue@119
|
304 if itemLink and itemId and numAvailable ~= 0 and not extendedCost then
|
Zerotorescue@119
|
305 local containerItem;
|
Zerotorescue@119
|
306 if not itemCache[itemId] then
|
Zerotorescue@119
|
307 -- If this is the first time we see this item, make a new object
|
Zerotorescue@119
|
308 containerItem = addon.ContainerItem:New();
|
Zerotorescue@119
|
309 containerItem.price = (vendorValue / quantity); -- remember the price for this item. We assume it's the same for this entire item id
|
Zerotorescue@119
|
310
|
Zerotorescue@119
|
311 itemCache[itemId] = containerItem;
|
Zerotorescue@119
|
312 else
|
Zerotorescue@119
|
313 -- If we had this item in another slot too
|
Zerotorescue@119
|
314 containerItem = itemCache[itemId];
|
Zerotorescue@119
|
315 end
|
Zerotorescue@119
|
316
|
Zerotorescue@119
|
317 containerItem:AddLocation(1, itemIndex, numAvailable);
|
Zerotorescue@119
|
318 end
|
Zerotorescue@119
|
319 end
|
Zerotorescue@80
|
320 else
|
Zerotorescue@119
|
321 error("Invalid location provided for CacheLocation.");
|
Zerotorescue@80
|
322 end
|
Zerotorescue@80
|
323
|
Zerotorescue@80
|
324 if not remember then
|
Zerotorescue@80
|
325 -- Copy the table as clearing the cache wipes it empty (and tables are passed by reference)
|
Zerotorescue@80
|
326 local cacheCopy = CopyTable(itemCache);
|
Zerotorescue@80
|
327
|
Zerotorescue@80
|
328 self:ClearCache();
|
Zerotorescue@80
|
329
|
Zerotorescue@80
|
330 return cacheCopy;
|
Zerotorescue@80
|
331 end
|
Zerotorescue@80
|
332 end
|
Zerotorescue@80
|
333
|
Zerotorescue@80
|
334 function mod:Scan(location)
|
Zerotorescue@80
|
335 -- We might pause the scanning when we invoke moves ourself
|
Zerotorescue@80
|
336 if paused then
|
Zerotorescue@110
|
337 addon:Debug("Not scanning; paused...");
|
Zerotorescue@80
|
338 return;
|
Zerotorescue@80
|
339 end
|
Zerotorescue@80
|
340
|
Zerotorescue@80
|
341 local playerName = UnitName("player");
|
Zerotorescue@80
|
342
|
Zerotorescue@101
|
343 currentLocation = location;
|
Zerotorescue@80
|
344 self:CacheLocation(location, true);
|
Zerotorescue@80
|
345
|
Zerotorescue@110
|
346 -- Ensure previous queue isn't remaining
|
Zerotorescue@110
|
347 Mover:ResetQueue();
|
Zerotorescue@110
|
348
|
Zerotorescue@119
|
349 -- Restock = obtaining more, refill = merely moving local. IsRestock = are we buying/making more?
|
Zerotorescue@119
|
350 local isRestock = (location == addon.Locations.Merchant);
|
Zerotorescue@119
|
351
|
Zerotorescue@80
|
352 -- Go through all groups
|
Zerotorescue@80
|
353 for groupName, values in pairs(addon.db.profile.groups) do
|
Zerotorescue@119
|
354 -- Settings
|
Zerotorescue@80
|
355 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
|
Zerotorescue@84
|
356 local localItemData = addon:GetOptionByKey(groupName, "localItemData");
|
Zerotorescue@218
|
357 local requiredItems, bonusQueue, priceThreshold, minCraftingQueue, isRefillEnabled;
|
Zerotorescue@123
|
358 if isRestock then
|
Zerotorescue@123
|
359 requiredItems = addon:GetOptionByKey(groupName, "restockTarget");
|
Zerotorescue@123
|
360 bonusQueue = addon:GetOptionByKey(groupName, "bonusQueue");
|
Zerotorescue@218
|
361 priceThreshold = addon:GetOptionByKey(groupName, "priceThreshold");
|
Zerotorescue@123
|
362 minCraftingQueue = floor( addon:GetOptionByKey(groupName, "minCraftingQueue") * requiredItems ); -- If the minCraftingQueue is 5% and restockTarget is 60, this will result in 3
|
Zerotorescue@123
|
363 else
|
Zerotorescue@123
|
364 isRefillEnabled = addon:GetOptionByKey(groupName, "autoRefill");
|
Zerotorescue@123
|
365 requiredItems = addon:GetOptionByKey(groupName, "minLocalStock");
|
Zerotorescue@123
|
366 end
|
Zerotorescue@80
|
367
|
Zerotorescue@119
|
368 local isTracked = (trackAt and trackAt[playerName]); -- Is this character interested in this data?
|
Zerotorescue@119
|
369 local isConsideredLocal = (localItemData and localItemData[location]); -- if this location was checked as local storage, don't refill from it
|
Zerotorescue@119
|
370
|
Zerotorescue@123
|
371 if values.items and isTracked and (isRestock or isRefillEnabled) and not isConsideredLocal then
|
Zerotorescue@119
|
372 addon:Debug("Scanning |cff00ff00%s|r", groupName);
|
Zerotorescue@80
|
373
|
Zerotorescue@80
|
374 for itemId, _ in pairs(values.items) do
|
Zerotorescue@119
|
375 -- Find this item in the source
|
Zerotorescue@119
|
376 local containerItem = itemCache[itemId];
|
Zerotorescue@80
|
377
|
Zerotorescue@119
|
378 if containerItem then
|
Zerotorescue@119
|
379 -- Only do all the CPU intensive checks if this item is available
|
Zerotorescue@80
|
380
|
Zerotorescue@119
|
381 -- When restocking use the global item count, when refilling use the local
|
Zerotorescue@119
|
382 local currentItemCount = ((isRestock and addon:GetItemCount(itemId, groupName)) or addon:GetLocalItemCount(itemId, groupName));
|
Zerotorescue@119
|
383
|
Zerotorescue@240
|
384 if currentItemCount < 0 then
|
Zerotorescue@240
|
385 addon:Print("Inventorium auto refill from storage could not be executed; no valid item count addon detected.", addon.Colors.Red);
|
Zerotorescue@240
|
386
|
Zerotorescue@240
|
387 return;
|
Zerotorescue@240
|
388 end
|
Zerotorescue@240
|
389
|
Zerotorescue@119
|
390 -- Check if we have enough items local (but only do so if this location also has enough available)
|
Zerotorescue@119
|
391 local missingItems = (requiredItems - currentItemCount);
|
Zerotorescue@119
|
392
|
Zerotorescue@123
|
393 if isRestock and currentItemCount == 0 and bonusQueue and bonusQueue > 0 then
|
Zerotorescue@123
|
394 -- If we have none left and the bonus queue is enabled, modify the amount to be queued
|
Zerotorescue@123
|
395
|
Zerotorescue@123
|
396 missingItems = floor( ( missingItems * ( bonusQueue + 1 ) ) + .5 ); -- round
|
Zerotorescue@123
|
397 end
|
Zerotorescue@123
|
398
|
Zerotorescue@123
|
399 if missingItems > 0 and (not isRestock or missingItems >= minCraftingQueue) then
|
Zerotorescue@218
|
400
|
Zerotorescue@218
|
401 -- Get auction value when it is relevant
|
Zerotorescue@218
|
402 local value = (isRestock and priceThreshold ~= 0 and addon:GetAuctionValue(IdToItemLink(itemId), groupName));
|
Zerotorescue@80
|
403
|
Zerotorescue@218
|
404 if not isRestock or priceThreshold == 0 or value == -1 or value >= priceThreshold then
|
Zerotorescue@218
|
405 -- Check how many are available
|
Zerotorescue@218
|
406 local availableItems = ((containerItem.totalCount) or 0);
|
Zerotorescue@218
|
407 -- Calculate how many we'll be moving (less missing than available? use missing, otherwise use available)
|
Zerotorescue@218
|
408 -- -1 available items indicates unlimited amount, in that case we must cap at missing items
|
Zerotorescue@218
|
409 local moving = (((availableItems == -1 or missingItems <= availableItems) and missingItems) or availableItems);
|
Zerotorescue@119
|
410
|
Zerotorescue@218
|
411 if availableItems == -1 or availableItems > 0 then
|
Zerotorescue@218
|
412 addon:Debug("Insufficient %s but this location has %d (moving %d)", IdToItemLink(itemId), availableItems, moving);
|
Zerotorescue@218
|
413
|
Zerotorescue@218
|
414 Mover:AddMove(itemId, moving, missingItems, availableItems, containerItem.price);
|
Zerotorescue@218
|
415 end
|
Zerotorescue@119
|
416 end
|
Zerotorescue@80
|
417 end
|
Zerotorescue@80
|
418 end
|
Zerotorescue@80
|
419 end
|
Zerotorescue@80
|
420 end
|
Zerotorescue@80
|
421 end
|
Zerotorescue@80
|
422
|
Zerotorescue@80
|
423 self:ClearCache();
|
Zerotorescue@80
|
424
|
Zerotorescue@81
|
425 if Mover:HasMoves() then
|
Zerotorescue@101
|
426 if addon.db.profile.defaults.autoRefillSkipConfirm then
|
Zerotorescue@110
|
427 OnMoveAccept();
|
Zerotorescue@101
|
428 else
|
Zerotorescue@119
|
429 local moves = Mover:GetMoves();
|
Zerotorescue@110
|
430
|
Zerotorescue@106
|
431 -- This table is never copied, just referenced. It is the same for every row.
|
Zerotorescue@119
|
432 local columns;
|
Zerotorescue@119
|
433
|
Zerotorescue@119
|
434 if isRestock then
|
Zerotorescue@119
|
435 local totalCost = 0;
|
Zerotorescue@119
|
436 for _, move in pairs(moves) do
|
Zerotorescue@119
|
437 totalCost = (totalCost + (move.cost * move.num));
|
Zerotorescue@119
|
438 end
|
Zerotorescue@119
|
439 UseMerchantRestockST(totalCost);
|
Zerotorescue@119
|
440
|
Zerotorescue@119
|
441 columns = {
|
Zerotorescue@119
|
442 {
|
Zerotorescue@119
|
443 ["value"] = function(data, cols, realrow, column, table)
|
Zerotorescue@119
|
444 return IdToItemLink(data[realrow].rowData.itemId);
|
Zerotorescue@119
|
445 end,
|
Zerotorescue@119
|
446 }, -- item
|
Zerotorescue@119
|
447 {
|
Zerotorescue@119
|
448 ["value"] = function(data, cols, realrow, column, table)
|
Zerotorescue@119
|
449 return data[realrow].rowData.num;
|
Zerotorescue@119
|
450 end,
|
Zerotorescue@119
|
451 }, -- buying
|
Zerotorescue@119
|
452 {
|
Zerotorescue@119
|
453 ["value"] = function(data, cols, realrow, column, table)
|
Zerotorescue@119
|
454 return GetSmallCoinTextureString((data[realrow].rowData.cost * data[realrow].rowData.num));
|
Zerotorescue@119
|
455 end,
|
Zerotorescue@119
|
456 }, -- cost
|
Zerotorescue@119
|
457 };
|
Zerotorescue@119
|
458 else
|
Zerotorescue@119
|
459 UseStorageRefillST();
|
Zerotorescue@119
|
460
|
Zerotorescue@119
|
461 columns = {
|
Zerotorescue@119
|
462 {
|
Zerotorescue@119
|
463 ["value"] = function(data, cols, realrow, column, table)
|
Zerotorescue@119
|
464 return IdToItemLink(data[realrow].rowData.itemId);
|
Zerotorescue@119
|
465 end,
|
Zerotorescue@119
|
466 }, -- item
|
Zerotorescue@119
|
467 {
|
Zerotorescue@119
|
468 ["value"] = function(data, cols, realrow, column, table)
|
Zerotorescue@119
|
469 return data[realrow].rowData.num;
|
Zerotorescue@119
|
470 end,
|
Zerotorescue@119
|
471 }, -- moving
|
Zerotorescue@119
|
472 {
|
Zerotorescue@119
|
473 ["value"] = function(data, cols, realrow, column, table)
|
Zerotorescue@119
|
474 return addon:DisplayItemCount(data[realrow].rowData.available, data[realrow].rowData.missing); -- available / missing
|
Zerotorescue@119
|
475 end,
|
Zerotorescue@119
|
476 ["color"] = function(data, cols, realrow, column, table)
|
Zerotorescue@119
|
477 return ((data[realrow].rowData.available < data[realrow].rowData.missing) and { r = 1, g = 0, b = 0, a = 1 }) or { r = 1, g = 1, b = 1, a = 1 };
|
Zerotorescue@119
|
478 end,
|
Zerotorescue@119
|
479 }, -- missing / available
|
Zerotorescue@119
|
480 };
|
Zerotorescue@119
|
481 end
|
Zerotorescue@101
|
482
|
Zerotorescue@106
|
483 -- Store the list with rows in this
|
Zerotorescue@106
|
484 local data = {};
|
Zerotorescue@101
|
485
|
Zerotorescue@119
|
486 for i, move in pairs(moves) do
|
Zerotorescue@122
|
487 tinsert(data, {
|
Zerotorescue@106
|
488 ["rowData"] = move, -- this is not a key usually found in a row item and ignored by the library
|
Zerotorescue@101
|
489 ["cols"] = columns,
|
Zerotorescue@106
|
490 });
|
Zerotorescue@101
|
491 end
|
Zerotorescue@101
|
492
|
Zerotorescue@101
|
493 addon:SetMoverFrameData(data);
|
Zerotorescue@101
|
494 end
|
Zerotorescue@81
|
495 end
|
Zerotorescue@81
|
496 end
|
Zerotorescue@81
|
497
|
Zerotorescue@84
|
498
|
Zerotorescue@84
|
499
|
Zerotorescue@84
|
500 -- Events
|
Zerotorescue@84
|
501
|
Zerotorescue@84
|
502 -- Player bank
|
Zerotorescue@84
|
503
|
Zerotorescue@84
|
504 function mod:BANKFRAME_OPENED()
|
Zerotorescue@84
|
505 addon:Debug("Scanner:BANKFRAME_OPENED");
|
Zerotorescue@84
|
506
|
Zerotorescue@84
|
507 mod:RegisterEvent("BANKFRAME_CLOSED");
|
Zerotorescue@84
|
508
|
Zerotorescue@84
|
509 -- Scan once when the bank is opened, but no need to scan after
|
Zerotorescue@84
|
510 mod:Scan(addon.Locations.Bank);
|
Zerotorescue@84
|
511 end
|
Zerotorescue@84
|
512
|
Zerotorescue@84
|
513 function mod:BANKFRAME_CLOSED()
|
Zerotorescue@81
|
514 addon:Debug("Scanner:BANKFRAME_CLOSED");
|
Zerotorescue@81
|
515
|
Zerotorescue@89
|
516 self:ClearCache();
|
Zerotorescue@89
|
517
|
Zerotorescue@81
|
518 mod:UnregisterEvent("BANKFRAME_CLOSED");
|
Zerotorescue@81
|
519
|
Zerotorescue@137
|
520 if InventoriumItemMover then
|
Zerotorescue@137
|
521 InventoriumItemMover:Hide();
|
Zerotorescue@137
|
522 end
|
Zerotorescue@101
|
523 Mover:ResetQueue();
|
Zerotorescue@80
|
524 end
|
Zerotorescue@80
|
525
|
Zerotorescue@84
|
526 -- Guild bank
|
Zerotorescue@84
|
527
|
Zerotorescue@84
|
528 local tmrScanGuild, scanned;
|
Zerotorescue@84
|
529 function mod:GUILDBANKBAGSLOTS_CHANGED()
|
Zerotorescue@84
|
530 -- This event is spammed the first time the guild bank is opened
|
Zerotorescue@84
|
531 if not scanned then
|
Zerotorescue@84
|
532 self:CancelTimer(tmrScanGuild, true); -- silent
|
Zerotorescue@84
|
533 tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1);
|
Zerotorescue@84
|
534 end
|
Zerotorescue@80
|
535 end
|
Zerotorescue@80
|
536
|
Zerotorescue@84
|
537 function mod:DoScanGuild()
|
Zerotorescue@84
|
538 if not scanned then
|
Zerotorescue@89
|
539 addon:Debug("Scanner:DoScanGuild");
|
Zerotorescue@84
|
540
|
Zerotorescue@84
|
541 scanned = true;
|
Zerotorescue@84
|
542
|
Zerotorescue@84
|
543 self:Scan(addon.Locations.Guild);
|
Zerotorescue@84
|
544 end
|
Zerotorescue@84
|
545 end
|
Zerotorescue@80
|
546
|
Zerotorescue@84
|
547 function mod:GUILDBANKFRAME_CLOSED()
|
Zerotorescue@81
|
548 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
|
Zerotorescue@81
|
549
|
Zerotorescue@84
|
550 scanned = nil;
|
Zerotorescue@89
|
551 self:ClearCache();
|
Zerotorescue@81
|
552
|
Zerotorescue@84
|
553 self:UnregisterEvent("GUILDBANKFRAME_CLOSED");
|
Zerotorescue@84
|
554 self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
|
Zerotorescue@84
|
555
|
Zerotorescue@84
|
556 self:CancelTimer(tmrScanGuild, true); -- silent
|
Zerotorescue@80
|
557
|
Zerotorescue@137
|
558 if InventoriumItemMover then
|
Zerotorescue@137
|
559 InventoriumItemMover:Hide();
|
Zerotorescue@137
|
560 end
|
Zerotorescue@101
|
561 Mover:ResetQueue();
|
Zerotorescue@80
|
562 end
|
Zerotorescue@80
|
563
|
Zerotorescue@84
|
564 function mod:GUILDBANKFRAME_OPENED()
|
Zerotorescue@81
|
565 addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
|
Zerotorescue@81
|
566
|
Zerotorescue@84
|
567 scanned = nil;
|
Zerotorescue@80
|
568
|
Zerotorescue@84
|
569 -- Get the contents for every tab into our cache
|
Zerotorescue@84
|
570 for tabId = 1, GetNumGuildBankTabs() do
|
Zerotorescue@110
|
571 local _, _, isViewable, _, _, remainingWithdrawals = GetGuildBankTabInfo(tabId);
|
Zerotorescue@110
|
572
|
Zerotorescue@110
|
573 if isViewable and (remainingWithdrawals > 0 or remainingWithdrawals == -1) then
|
Zerotorescue@84
|
574 QueryGuildBankTab(tabId);
|
Zerotorescue@84
|
575 end
|
Zerotorescue@84
|
576 end
|
Zerotorescue@84
|
577
|
Zerotorescue@84
|
578 self:RegisterEvent("GUILDBANKFRAME_CLOSED");
|
Zerotorescue@84
|
579 self:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED");
|
Zerotorescue@80
|
580 end
|
Zerotorescue@80
|
581
|
Zerotorescue@119
|
582 function mod:MERCHANT_SHOW()
|
Zerotorescue@119
|
583 addon:Debug("Scanner:MERCHANT_SHOW");
|
Zerotorescue@119
|
584
|
Zerotorescue@119
|
585 self:RegisterEvent("MERCHANT_CLOSED");
|
Zerotorescue@119
|
586
|
Zerotorescue@119
|
587 self:Scan(addon.Locations.Merchant);
|
Zerotorescue@119
|
588 end
|
Zerotorescue@119
|
589
|
Zerotorescue@119
|
590 function mod:MERCHANT_CLOSED()
|
Zerotorescue@119
|
591 addon:Debug("Scanner:MERCHANT_CLOSED");
|
Zerotorescue@119
|
592
|
Zerotorescue@119
|
593 self:ClearCache();
|
Zerotorescue@119
|
594
|
Zerotorescue@119
|
595 self:UnregisterEvent("MERCHANT_CLOSED");
|
Zerotorescue@119
|
596
|
Zerotorescue@137
|
597 if InventoriumItemMover then
|
Zerotorescue@137
|
598 InventoriumItemMover:Hide();
|
Zerotorescue@137
|
599 end
|
Zerotorescue@119
|
600 Mover:ResetQueue();
|
Zerotorescue@119
|
601 end
|
Zerotorescue@119
|
602
|
Zerotorescue@117
|
603 local previousMailCount;
|
Zerotorescue@117
|
604 function mod:MAIL_SHOW()
|
Zerotorescue@117
|
605 addon:Debug("Scanner:MAIL_SHOW");
|
Zerotorescue@117
|
606
|
Zerotorescue@117
|
607 self:RegisterEvent("MAIL_INBOX_UPDATE");
|
Zerotorescue@117
|
608 self:RegisterEvent("MAIL_CLOSED");
|
Zerotorescue@117
|
609
|
Zerotorescue@117
|
610 scanned = nil;
|
Zerotorescue@117
|
611 previousMailCount = nil;
|
Zerotorescue@117
|
612
|
Zerotorescue@117
|
613 self:Scan(addon.Locations.Mailbox);
|
Zerotorescue@117
|
614 end
|
Zerotorescue@110
|
615
|
Zerotorescue@117
|
616 function mod:MAIL_INBOX_UPDATE()
|
Zerotorescue@117
|
617 if not scanned then
|
Zerotorescue@117
|
618 addon:Debug("Scanner:MAIL_INBOX_UPDATE");
|
Zerotorescue@117
|
619
|
Zerotorescue@117
|
620 local current, total = GetInboxNumItems();
|
Zerotorescue@117
|
621
|
Zerotorescue@117
|
622 if not previousMailCount or current > previousMailCount then
|
Zerotorescue@117
|
623 -- New mail received
|
Zerotorescue@117
|
624
|
Zerotorescue@117
|
625 scanned = true;
|
Zerotorescue@117
|
626
|
Zerotorescue@117
|
627 self:Scan(addon.Locations.Mailbox);
|
Zerotorescue@117
|
628 end
|
Zerotorescue@117
|
629
|
Zerotorescue@117
|
630 -- Also remember the new mailcount when losing items, otherwise deleting item 50 and getting to 50 again wouldn't trigger a re-scan
|
Zerotorescue@117
|
631 previousMailCount = current;
|
Zerotorescue@117
|
632 else
|
Zerotorescue@117
|
633 addon:Debug("Scanner:MAIL_INBOX_UPDATE skipped, already scanned");
|
Zerotorescue@117
|
634 end
|
Zerotorescue@117
|
635 end
|
Zerotorescue@110
|
636
|
Zerotorescue@117
|
637 function mod:MAIL_CLOSED()
|
Zerotorescue@117
|
638 addon:Debug("Scanner:MAIL_CLOSED");
|
Zerotorescue@117
|
639
|
Zerotorescue@117
|
640 previousMailCount = nil;
|
Zerotorescue@117
|
641 scanned = nil;
|
Zerotorescue@117
|
642 self:ClearCache();
|
Zerotorescue@117
|
643
|
Zerotorescue@117
|
644 self:UnregisterEvent("MAIL_INBOX_UPDATE");
|
Zerotorescue@117
|
645 self:UnregisterEvent("MAIL_CLOSED");
|
Zerotorescue@117
|
646
|
Zerotorescue@137
|
647 if InventoriumItemMover then
|
Zerotorescue@137
|
648 InventoriumItemMover:Hide();
|
Zerotorescue@137
|
649 end
|
Zerotorescue@117
|
650 Mover:ResetQueue();
|
Zerotorescue@117
|
651 end
|
Zerotorescue@110
|
652
|
Zerotorescue@80
|
653 function mod:OnEnable()
|
Zerotorescue@80
|
654 -- Scan once when the bankframe is opened
|
Zerotorescue@84
|
655 self:RegisterEvent("BANKFRAME_OPENED");
|
Zerotorescue@84
|
656 self:RegisterEvent("GUILDBANKFRAME_OPENED");
|
Zerotorescue@117
|
657 self:RegisterEvent("MAIL_SHOW");
|
Zerotorescue@119
|
658 self:RegisterEvent("MERCHANT_SHOW");
|
Zerotorescue@80
|
659
|
Zerotorescue@80
|
660 Mover = addon:GetModule("Mover");
|
Zerotorescue@80
|
661 end
|
Zerotorescue@80
|
662
|
Zerotorescue@80
|
663 function mod:OnDisable()
|
Zerotorescue@80
|
664 Mover = nil;
|
Zerotorescue@101
|
665 currentLocation = nil;
|
Zerotorescue@101
|
666 paused = nil;
|
Zerotorescue@80
|
667
|
Zerotorescue@80
|
668 -- Bank
|
Zerotorescue@110
|
669 self:BANKFRAME_CLOSED();
|
Zerotorescue@84
|
670 self:UnregisterEvent("BANKFRAME_OPENED");
|
Zerotorescue@80
|
671
|
Zerotorescue@80
|
672 -- Guild
|
Zerotorescue@84
|
673 self:GUILDBANKFRAME_CLOSED();
|
Zerotorescue@84
|
674 self:UnregisterEvent("GUILDBANKFRAME_OPENED");
|
Zerotorescue@110
|
675
|
Zerotorescue@117
|
676 -- Mailbox
|
Zerotorescue@117
|
677 self:MAIL_CLOSED();
|
Zerotorescue@117
|
678 self:UnregisterEvent("MAIL_SHOW");
|
Zerotorescue@119
|
679
|
Zerotorescue@119
|
680 -- Merchant
|
Zerotorescue@119
|
681 self:MERCHANT_CLOSED();
|
Zerotorescue@119
|
682 self:UnregisterEvent("MERCHANT_SHOW");
|
Zerotorescue@80
|
683 end
|
Zerotorescue@80
|
684
|
Zerotorescue@80
|
685 function mod:Pause()
|
Zerotorescue@80
|
686 paused = true;
|
Zerotorescue@80
|
687 end
|
Zerotorescue@80
|
688
|
Zerotorescue@80
|
689 function mod:Unpause()
|
Zerotorescue@80
|
690 paused = nil;
|
Zerotorescue@80
|
691 end
|