comparison Modules/Scanner.lua @ 84:3bec0ea44607

Cleaned the Inventorium folder; moved all classes to classes directory, modules to modules directory and support addons to plugins directory. In addition support addons are now references within XML files rather than inside the TOC. Fixed the default local item count setting, you can now exclude bag and AH data from it. Fixed some mover algorithm bugs. Mover can no longer freeze the game but instead will terminate the process after a 1000 passes. Now reversing the moves table after making it, rather than every single time it is used. Fixed guild bank support. Now displaying the amount of items moved. Scanner now scans all guild bank tabs rather than only the current. Fixed a bug with local item data not being retrieved properly. Disabled ?enterClicksFirstButton? within dialogs as this causes the dialog to consume all keypress. Events are now at the addon object rather than local.
author Zerotorescue
date Thu, 06 Jan 2011 20:05:30 +0100
parents Scanner.lua@f885805da5d6
children a12d22ef3f39
comparison
equal deleted inserted replaced
83:6b60f7a1410c 84:3bec0ea44607
1 local addon = select(2, ...);
2 local mod = addon:NewModule("Scanner", "AceEvent-3.0", "AceTimer-3.0");
3
4 addon.Locations = {
5 Bag = 0,
6 Bank = 1,
7 Guild = 2,
8 };
9
10 local Mover, paused;
11 local itemCache = {};
12
13 function mod:ClearCache()
14 table.wipe(itemCache);
15 end
16
17 function mod:CacheLocation(location, remember)
18 if location == addon.Locations.Bag or location == addon.Locations.Bank then
19 -- Reset cache just in case it was filled
20 self:ClearCache();
21
22 local start, stop;
23 if location == addon.Locations.Bag then
24 start = 0;
25 stop = NUM_BAG_SLOTS;
26 else
27 -- If we requested the bank then we don't want the bag info
28 start = ( NUM_BAG_SLOTS + 1 );
29 stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS );
30 end
31
32 -- Go through all our bags, including the backpack
33 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
34 -- Scan the default 100 slots whenever we're at a non-existing index
35 local bagId = (i == (stop + 1) and BANK_CONTAINER) or i;
36 local slotId = GetContainerNumSlots(bagId);
37
38 while slotId ~= 0 do
39 -- A not equal-comparison should be quicker than a larger than-comparison
40
41 local itemId = GetContainerItemID(bagId, slotId);
42 local itemCount = itemId and select(2, GetContainerItemInfo(bagId, slotId));
43
44 if itemId and itemCount and itemCount > 0 then
45 local itemMove;
46 if not itemCache[itemId] then
47 -- If this is the first time we see this item, make a new object
48 itemMove = addon.ContainerItem:New();
49 itemCache[itemId] = itemMove;
50 else
51 -- If we had this item in another slot too
52 itemMove = itemCache[itemId];
53 end
54
55 itemMove:AddLocation(bagId, slotId, itemCount);
56 end
57
58 -- Continue scanning a different slot
59 slotId = (slotId - 1);
60 end
61 end
62 elseif location == addon.Locations.Guild then
63 -- Reset cache before we scan
64 self:ClearCache();
65
66 for tabId = 1, GetNumGuildBankTabs() do
67 local isViewable = select(3, GetGuildBankTabInfo(tabId));
68
69 if isViewable == 1 then
70 local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot
71
72 while slotId ~= 0 do
73 -- A not equal-comparison should be quicker than a larger than-comparison
74
75 local itemLink = GetGuildBankItemLink(tabId, slotId);
76 local itemId = itemLink and addon:GetItemID(itemLink);
77 local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId));
78
79 if itemLink and itemId and itemCount and itemCount > 0 then
80 -- If there is actually an item in this slot
81 local itemMove;
82 if not itemCache[itemId] then
83 -- If this is the first time we see this item, make a new object
84 itemMove = addon.ContainerItem:New();
85 itemCache[itemId] = itemMove;
86 else
87 -- If we had this item in another slot too
88 itemMove = itemCache[itemId];
89 end
90
91 itemMove:AddLocation(tabId, slotId, itemCount);
92 end
93
94 -- Continue scanning a different slot
95 slotId = (slotId - 1);
96 end
97 end
98 end
99 else
100 error("Invalid location provided for CacheLocation. Must be Bank or Guild.");
101 end
102
103 if not remember then
104 -- Copy the table as clearing the cache wipes it empty (and tables are passed by reference)
105 local cacheCopy = CopyTable(itemCache);
106
107 self:ClearCache();
108
109 return cacheCopy;
110 end
111 end
112
113 function mod:Scan(location)
114 -- We might pause the scanning when we invoke moves ourself
115 if paused then
116 return;
117 end
118
119 local playerName = UnitName("player");
120
121 self:CacheLocation(location, true);
122
123 -- Go through all groups
124 for groupName, values in pairs(addon.db.profile.groups) do
125 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
126 local localItemData = addon:GetOptionByKey(groupName, "localItemData");
127
128 if values.items and trackAt[playerName] and addon:GetOptionByKey(groupName, "autoRefill") and (location ~= addon.Locations.Bank or not localItemData or not localItemData["Bank"]) then
129 -- Is this character interested in this data?
130
131 local minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock");
132
133 -- Go through all items
134 for itemId, _ in pairs(values.items) do
135
136 -- Check if we have enough items local (but only do so if this location also has enough available)
137 local missingItems = itemCache[itemId] and (minLocalStock - addon:GetLocalItemCount(itemId, groupName));
138
139 if itemCache[itemId] and missingItems > 0 then
140 -- Check how many are available
141 local availableItems = ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
142
143 if availableItems > 0 then
144 print("Insufficient " .. select(2, GetItemInfo(itemId)) .. " but this location has " .. availableItems .. " (moving " .. missingItems .. ")");
145
146 Mover:AddMove(itemId, missingItems);
147 else
148 print("Insufficient " .. IdToItemLink(itemId));
149 end
150 end
151 end
152 end
153 end
154
155 self:ClearCache();
156
157 if Mover:HasMoves() then
158 StaticPopupDialogs["InventoriumRefill"] = {
159 text = "There are items that can be refilled from this location, do you wish to proceed?",
160 button1 = YES,
161 button2 = NO,
162 OnAccept = function()
163 mod:Pause();
164 Mover:BeginMove(location, self.Unpause);
165 end,
166 timeout = 0,
167 whileDead = 1,
168 hideOnEscape = 1,
169 exclusive = 1,
170 };
171 StaticPopup_Show("InventoriumRefill");
172 end
173 end
174
175
176
177 -- Events
178
179 -- Player bank
180
181 function mod:BANKFRAME_OPENED()
182 addon:Debug("Scanner:BANKFRAME_OPENED");
183
184 mod:RegisterEvent("BANKFRAME_CLOSED");
185
186 -- Scan once when the bank is opened, but no need to scan after
187 mod:Scan(addon.Locations.Bank);
188 end
189
190 function mod:BANKFRAME_CLOSED()
191 addon:Debug("Scanner:BANKFRAME_CLOSED");
192
193 mod:UnregisterEvent("BANKFRAME_CLOSED");
194
195 StaticPopup_Hide("InventoriumRefill");
196 end
197
198 -- Guild bank
199
200 local tmrScanGuild, scanned;
201 function mod:GUILDBANKBAGSLOTS_CHANGED()
202 -- This event is spammed the first time the guild bank is opened
203 if not scanned then
204 self:CancelTimer(tmrScanGuild, true); -- silent
205 tmrScanGuild = self:ScheduleTimer("DoScanGuild", 1);
206 end
207 end
208
209 function mod:DoScanGuild()
210 if not scanned then
211 addon:Debug("Scanner:GUILDBANKBAGSLOTS_CHANGED");
212
213 scanned = true;
214
215 self:Scan(addon.Locations.Guild);
216 end
217 end
218
219 function mod:GUILDBANKFRAME_CLOSED()
220 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
221
222 scanned = nil;
223
224 self:UnregisterEvent("GUILDBANKFRAME_CLOSED");
225 self:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
226
227 self:CancelTimer(tmrScanGuild, true); -- silent
228
229 StaticPopup_Hide("InventoriumRefill");
230 end
231
232 function mod:GUILDBANKFRAME_OPENED()
233 addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
234
235 scanned = nil;
236
237 -- Get the contents for every tab into our cache
238 for tabId = 1, GetNumGuildBankTabs() do
239 local isViewable = select(3, GetGuildBankTabInfo(tabId));
240 if isViewable == 1 then
241 QueryGuildBankTab(tabId);
242 end
243 end
244
245 self:RegisterEvent("GUILDBANKFRAME_CLOSED");
246 self:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED");
247 end
248
249 function mod:OnEnable()
250 -- Scan once when the bankframe is opened
251 self:RegisterEvent("BANKFRAME_OPENED");
252 self:RegisterEvent("GUILDBANKFRAME_OPENED");
253
254 Mover = addon:GetModule("Mover");
255 end
256
257 function mod:OnDisable()
258 Mover = nil;
259
260 -- Bank
261 self:UnregisterEvent("BANKFRAME_OPENED");
262
263 -- Guild
264 self:GUILDBANKFRAME_CLOSED();
265 self:UnregisterEvent("GUILDBANKFRAME_OPENED");
266 end
267
268 function mod:Pause()
269 paused = true;
270 end
271
272 function mod:Unpause()
273 paused = nil;
274 end