comparison Scanner.lua @ 80:c0bf2ddb5288

Added initial item refilling from the bank/guild. Not yet fully functional.
author Zerotorescue
date Wed, 05 Jan 2011 13:05:15 +0100
parents
children 58617c7827fa
comparison
equal deleted inserted replaced
79:b89b6981783f 80:c0bf2ddb5288
1 local addon = select(2, ...);
2 local mod = addon:NewModule("Scanner", "AceEvent-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 local function _GetItemCount(itemId, location)
14 if location == addon.Locations.Bank then
15 -- No longer using GetItemCount as this includes equiped items and containers (e.g. bank bags)
16 --return (GetItemCount(itemId, true) - GetItemCount(itemId, false)); -- GetItemCount(X, true) provides count for bag+bank, GetItemCount(X, false) provides just bag, so (GetItemCount(X, true) - GetItemCount(X, false)) = just bank
17 return ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
18 elseif location == addon.Locations.Guild then
19 return ((itemCache[itemId] and itemCache[itemId].totalCount) or 0);
20 else
21 error("Invalid location provided for the local _GetItemCount. Must be Bag or Bank.");
22 end
23 end
24
25 local function GetItemID(link)
26 return tonumber(link:match("|Hitem:([-0-9]+):"));
27 end
28
29 function mod:ClearCache()
30 table.wipe(itemCache);
31 end
32
33 function mod:CacheLocation(location, remember)
34 if location == addon.Locations.Bag or location == addon.Locations.Bank then
35 -- Reset cache just in case it was filled
36 self:ClearCache();
37
38 local start, stop;
39 if location == addon.Locations.Bag then
40 start = 0;
41 stop = NUM_BAG_SLOTS;
42 else
43 -- If we requested the bank then we don't want the bag info
44 start = ( NUM_BAG_SLOTS + 1 );
45 stop = ( NUM_BAG_SLOTS + NUM_BANKBAGSLOTS );
46 end
47
48 -- Go through all our bags, including the backpack
49 for i = start, ((addon.Locations.Bag and stop) or (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
50 -- Scan the default 100 slots whenever we're at a non-existing index
51 local bagId = (i == (stop + 1) and BANK_CONTAINER) or i;
52 local slotId = GetContainerNumSlots(bagId);
53
54 while slotId ~= 0 do
55 -- A not equal-comparison should be quicker than a larger than-comparison
56
57 local itemId = GetContainerItemID(bagId, slotId);
58 local itemCount = itemId and select(2, GetContainerItemInfo(bagId, slotId));
59
60 if itemId and itemCount and itemCount > 0 then
61 local itemMove;
62 if not itemCache[itemId] then
63 -- If this is the first time we see this item, make a new object
64 itemMove = addon.ItemMove:New();
65 else
66 -- If we had this item in another slot too
67 itemMove = itemCache[itemId];
68 end
69
70 itemMove.AddLocation(bagId, slotId, itemCount);
71 end
72
73 -- Continue scanning a different slot
74 slotId = (slotId - 1);
75 end
76 end
77 elseif location == addon.Locations.Guild then
78 -- Reset cache before we scan
79 self:ClearCache();
80
81 local tabId = GetCurrentGuildBankTab();
82 local slotId = (MAX_GUILDBANK_SLOTS_PER_TAB or 98); -- start by scanning the last slot
83
84 if tabId == nil or tabId < 1 then return; end
85
86 while slotId ~= 0 do
87 -- A not equal-comparison should be quicker than a larger than-comparison
88
89 -- If there is actually an item in this slot
90
91 local itemLink = GetGuildBankItemLink(tabId, slotId);
92 local itemId = itemLink and GetItemId(itemLink);
93 local itemCount = itemLink and select(2, GetGuildBankItemInfo(tabId, slotId));
94
95 if itemLink and itemId and itemCount and itemCount > 0 then
96 local itemMove;
97 if not itemCache[itemId] then
98 -- If this is the first time we see this item, make a new object
99 itemMove = addon.ItemMove:New();
100 else
101 -- If we had this item in another slot too
102 itemMove = itemCache[itemId];
103 end
104
105 itemMove.AddLocation(tabId, slotId, itemCount);
106 end
107
108 -- Continue scanning a different slot
109 slotId = (slotId - 1);
110 end
111 else
112 error("Invalid location provided for the local _GetItemCount. Must be Bank or Guild.");
113 end
114
115 if not remember then
116 -- Copy the table as clearing the cache wipes it empty (and tables are passed by reference)
117 local cacheCopy = CopyTable(itemCache);
118
119 self:ClearCache();
120
121 return cacheCopy;
122 end
123 end
124
125 function mod:Scan(location)
126 -- We might pause the scanning when we invoke moves ourself
127 if paused then
128 return;
129 end
130
131 local playerName = UnitName("player");
132
133 self:CacheLocation(location, true);
134
135 -- Go through all groups
136 for groupName, values in pairs(addon.db.profile.groups) do
137 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
138
139 if values.items and trackAt[playerName] then
140 -- Is this character interested in this data?
141
142 local minLocalStock = addon:GetOptionByKey(groupName, "minLocalStock");
143
144 -- Go through all items
145 for itemId, _ in pairs(values.items) do
146
147 -- Check if we have enough items local
148 local missingItems = (minLocalStock - addon:GetLocalItemCount(itemId, groupName));
149
150 if missingItems > 0 then
151 -- Check how many are available
152 local availableItems = _GetItemCount(itemId, location);
153
154 if availableItems > 0 then
155 print("Insufficient " .. select(2, GetItemInfo(itemId)) .. " but this location has " .. availableItems .. " (moving " .. missingItems .. ")");
156
157 Mover:AddMove(itemId, missingItems);
158 else
159 print("Insufficient " .. select(2, GetItemInfo(itemId)));
160 end
161 end
162 end
163 end
164 end
165
166 self:ClearCache();
167
168 self:Pause();
169 Mover:BeginMove(location, self.Unpause);
170 end
171
172 local function BANKFRAME_OPENED()
173 -- Scan once when the bank is opened, but no need to scan after
174 mod:Scan(addon.Locations.Bank);
175
176 addon:Debug("Scanner:BANKFRAME_OPENED");
177 end
178
179 -- Remember which tabs were scanned and don't scan them again
180 local guildBankTabsScanned = {};
181
182 local function GUILDBANKFRAME_CLOSED()
183 mod:UnregisterEvent("GUILDBANKFRAME_CLOSED");
184 mod:UnregisterEvent("GUILDBANKBAGSLOTS_CHANGED");
185
186 table.wipe(guildBankTabsScanned);
187
188 addon:Debug("Scanner:GUILDBANKFRAME_CLOSED");
189 end
190
191 local function GUILDBANKBAGSLOTS_CHANGED()
192 if not guildBankTabsScanned[GetCurrentGuildBankTab()] then
193 mod:Scan(addon.Locations.Guild);
194 guildBankTabsScanned[GetCurrentGuildBankTab()] = true;
195
196 addon:Debug("Scanner:GUILDBANKBAGSLOTS_CHANGED (" .. GetCurrentGuildBankTab() .. ") - scanning");
197 else
198 addon:Debug("Scanner:GUILDBANKBAGSLOTS_CHANGED (" .. GetCurrentGuildBankTab() .. ") - not scanning");
199 end
200 end
201
202 local function GUILDBANKFRAME_OPENED()
203 table.wipe(guildBankTabsScanned);
204
205 mod:RegisterEvent("GUILDBANKFRAME_CLOSED", GUILDBANKFRAME_CLOSED);
206 mod:RegisterEvent("GUILDBANKBAGSLOTS_CHANGED", GUILDBANKBAGSLOTS_CHANGED);
207
208 addon:Debug("Scanner:GUILDBANKFRAME_OPENED");
209 end
210
211 function mod:OnEnable()
212 -- Scan once when the bankframe is opened
213 mod:RegisterEvent("BANKFRAME_OPENED", BANKFRAME_OPENED);
214 mod:RegisterEvent("GUILDBANKFRAME_OPENED", GUILDBANKFRAME_OPENED);
215
216 Mover = addon:GetModule("Mover");
217 end
218
219 function mod:OnDisable()
220 Mover = nil;
221
222 -- Bank
223 mod:UnregisterEvent("BANKFRAME_OPENED");
224
225 -- Guild
226 GUILDBANKFRAME_CLOSED();
227 mod:UnregisterEvent("GUILDBANKFRAME_OPENED");
228 end
229
230 function mod:Pause()
231 paused = true;
232 end
233
234 function mod:Unpause()
235 paused = nil;
236 end