annotate Scanner.lua @ 82:f885805da5d6

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