Zerotorescue@176
|
1 local addon = select(2, ...);
|
Zerotorescue@176
|
2 local mod = addon:NewModule("Alerts", "AceEvent-3.0", "AceTimer-3.0");
|
Zerotorescue@176
|
3
|
Zerotorescue@176
|
4 local queue, cache = {}, {};
|
Zerotorescue@176
|
5
|
Zerotorescue@176
|
6 function mod:OnEnable()
|
Zerotorescue@176
|
7 addon:Debug("Alerts:OnEnable");
|
Zerotorescue@176
|
8
|
Zerotorescue@176
|
9 -- Register our alert slash command
|
Zerotorescue@176
|
10 -- /im alert
|
Zerotorescue@176
|
11 addon:RegisterSlash(function(this)
|
Zerotorescue@176
|
12 mod:Scan(true);
|
Zerotorescue@176
|
13 end, { "a", "alert" }, "|Hfunction:InventoriumCommandHandler:alert|h|cff00fff7/im alert|r|h (or /im a) - Rescan the items within all tracked groups and show item alerts for those items missing.");
|
Zerotorescue@176
|
14
|
Zerotorescue@184
|
15 mod:Scan(false);
|
Zerotorescue@176
|
16
|
Zerotorescue@176
|
17 --[[if addon.db.profile.defaults.scanInterval["00Login"] then
|
Zerotorescue@176
|
18 self:RegisterEvent("PLAYER_LOGIN", "Scan");
|
Zerotorescue@176
|
19 end
|
Zerotorescue@176
|
20
|
Zerotorescue@176
|
21 if addon.db.profile.defaults.scanInterval["01Repeat5"] then
|
Zerotorescue@176
|
22 self:ScheduleTimer("Scan", 5 * 60);
|
Zerotorescue@176
|
23 elseif addon.db.profile.defaults.scanInterval["01Repeat10"] then
|
Zerotorescue@176
|
24 self:ScheduleTimer("Scan", 10 * 60);
|
Zerotorescue@176
|
25 elseif addon.db.profile.defaults.scanInterval["01Repeat15"] then
|
Zerotorescue@176
|
26 self:ScheduleTimer("Scan", 15 * 60);
|
Zerotorescue@176
|
27 elseif addon.db.profile.defaults.scanInterval["01Repeat30"] then
|
Zerotorescue@176
|
28 self:ScheduleTimer("Scan", 30 * 60);
|
Zerotorescue@176
|
29 elseif addon.db.profile.defaults.scanInterval["01Repeat60"] then
|
Zerotorescue@176
|
30 self:ScheduleTimer("Scan", 60 * 60);
|
Zerotorescue@176
|
31 elseif addon.db.profile.defaults.scanInterval["01Repeat120"] then
|
Zerotorescue@176
|
32 self:ScheduleTimer("Scan", 120 * 60);
|
Zerotorescue@176
|
33 end]]
|
Zerotorescue@176
|
34 end
|
Zerotorescue@176
|
35
|
Zerotorescue@176
|
36 local scanTypes = {
|
Zerotorescue@176
|
37 Local = "local",
|
Zerotorescue@176
|
38 Global = "global",
|
Zerotorescue@176
|
39 };
|
Zerotorescue@176
|
40
|
Zerotorescue@176
|
41 function mod:Scan(verbal)
|
Zerotorescue@176
|
42 addon:Debug("Alerts:Scan");
|
Zerotorescue@176
|
43
|
Zerotorescue@176
|
44 if verbal then
|
Zerotorescue@176
|
45 addon:Print("Scanning items, the results will be presented to you in a moment. Please be patient.");
|
Zerotorescue@176
|
46 end
|
Zerotorescue@176
|
47
|
Zerotorescue@176
|
48 local playerName = UnitName("player");
|
Zerotorescue@176
|
49
|
Zerotorescue@176
|
50 table.wipe(queue);
|
Zerotorescue@176
|
51 table.wipe(cache);
|
Zerotorescue@176
|
52
|
Zerotorescue@176
|
53 -- Go through all groups
|
Zerotorescue@176
|
54 for groupName, values in pairs(addon.db.profile.groups) do
|
Zerotorescue@176
|
55 -- Settings
|
Zerotorescue@176
|
56 local trackAt = addon:GetOptionByKey(groupName, "trackAtCharacters");
|
Zerotorescue@176
|
57 local dontAlertAt = addon:GetOptionByKey(groupName, "dontAlertAtCharacters");
|
Zerotorescue@176
|
58
|
Zerotorescue@176
|
59 local alertBelowLocalMinimum = addon:GetOptionByKey(groupName, "alertBelowLocalMinimum");
|
Zerotorescue@176
|
60 local minLocalStock = alertBelowLocalMinimum and addon:GetOptionByKey(groupName, "minLocalStock");
|
Zerotorescue@176
|
61
|
Zerotorescue@176
|
62 local alertBelowGlobalMinimum = addon:GetOptionByKey(groupName, "alertBelowGlobalMinimum");
|
Zerotorescue@176
|
63 local minGlobalStock = alertBelowGlobalMinimum and addon:GetOptionByKey(groupName, "minGlobalStock");
|
Zerotorescue@176
|
64
|
Zerotorescue@176
|
65 local isTracked = (trackAt and trackAt[playerName] and (not dontAlertAt or not dontAlertAt[playerName])); -- Is this character interested in this data and does it want alerts?
|
Zerotorescue@176
|
66
|
Zerotorescue@176
|
67 if values.items and isTracked and (alertBelowLocalMinimum or alertBelowGlobalMinimum) then
|
Zerotorescue@176
|
68 addon:Debug("Scanning |cff00ff00%s|r", groupName);
|
Zerotorescue@176
|
69
|
Zerotorescue@176
|
70 local groupSettings = {
|
Zerotorescue@176
|
71 ["name"] = groupName,
|
Zerotorescue@176
|
72 ["minLocalStock"] = minLocalStock,
|
Zerotorescue@176
|
73 ["minGlobalStock"] = minGlobalStock,
|
Zerotorescue@176
|
74 };
|
Zerotorescue@176
|
75
|
Zerotorescue@176
|
76 for itemId, _ in pairs(values.items) do
|
Zerotorescue@176
|
77 if alertBelowLocalMinimum then
|
Zerotorescue@176
|
78 self:QeueueScan(groupSettings, itemId, scanTypes.Local);
|
Zerotorescue@176
|
79 end
|
Zerotorescue@176
|
80
|
Zerotorescue@176
|
81 if alertBelowGlobalMinimum then
|
Zerotorescue@176
|
82 self:QeueueScan(groupSettings, itemId, scanTypes.Global);
|
Zerotorescue@176
|
83 end
|
Zerotorescue@176
|
84 end
|
Zerotorescue@176
|
85 end
|
Zerotorescue@176
|
86 end
|
Zerotorescue@176
|
87
|
Zerotorescue@176
|
88 if self:HasQueue() then
|
Zerotorescue@176
|
89 addon:Debug("Alerts:HasQueue, processing");
|
Zerotorescue@176
|
90 --addon:Debug(queue);
|
Zerotorescue@176
|
91
|
Zerotorescue@176
|
92 self:ProcessScan(verbal);
|
Zerotorescue@176
|
93 end
|
Zerotorescue@176
|
94 end
|
Zerotorescue@176
|
95
|
Zerotorescue@176
|
96 function mod:QeueueScan(groupSettings, itemId, scanType)
|
Zerotorescue@176
|
97 table.insert(queue, {
|
Zerotorescue@176
|
98 ["group"] = groupSettings,
|
Zerotorescue@176
|
99 ["itemId"] = itemId,
|
Zerotorescue@176
|
100 ["type"] = scanType,
|
Zerotorescue@176
|
101 });
|
Zerotorescue@176
|
102 end
|
Zerotorescue@176
|
103
|
Zerotorescue@176
|
104 function mod:HasQueue()
|
Zerotorescue@176
|
105 return (#queue > 0);
|
Zerotorescue@176
|
106 end
|
Zerotorescue@176
|
107
|
Zerotorescue@176
|
108 function mod:ProcessScan(verbal)
|
Zerotorescue@184
|
109 local nextScanDelay = (tonumber(addon.db.profile.defaults.scanInterval) or .1);
|
Zerotorescue@184
|
110 local runs = (0.1 / nextScanDelay); -- 0.01 = 10, 0.05 = 2, 0.1 and smaller = 1
|
Zerotorescue@184
|
111 runs = (runs < 1 and 1) or runs;
|
Zerotorescue@184
|
112 runs = (nextScanDelay == 0 and 100) or runs;
|
Zerotorescue@176
|
113
|
Zerotorescue@184
|
114 for no = 1, runs do
|
Zerotorescue@184
|
115 -- Get the last item added to the queue
|
Zerotorescue@184
|
116 local thisItem = table.remove(queue, 1);
|
Zerotorescue@176
|
117
|
Zerotorescue@184
|
118 if not thisItem then
|
Zerotorescue@184
|
119 -- If no item exists then we processed everything, show summary
|
Zerotorescue@184
|
120 self:ScanFinished();
|
Zerotorescue@184
|
121 return;
|
Zerotorescue@176
|
122 end
|
Zerotorescue@176
|
123
|
Zerotorescue@184
|
124 if thisItem.type == scanTypes.Global then
|
Zerotorescue@184
|
125 -- Global scan
|
Zerotorescue@184
|
126 local globalCount = addon:GetItemCount(thisItem.itemId, thisItem.group.name);
|
Zerotorescue@184
|
127
|
Zerotorescue@184
|
128 if not cache[thisItem.itemId] then
|
Zerotorescue@184
|
129 cache[thisItem.itemId] = {
|
Zerotorescue@184
|
130 ["itemId"] = thisItem.itemId, -- needed later for displaying
|
Zerotorescue@184
|
131 ["group"] = thisItem.group,
|
Zerotorescue@184
|
132 ["globalCount"] = globalCount,
|
Zerotorescue@184
|
133 };
|
Zerotorescue@184
|
134 else
|
Zerotorescue@184
|
135 cache[thisItem.itemId].globalCount = globalCount;
|
Zerotorescue@184
|
136 end
|
Zerotorescue@184
|
137 elseif thisItem.type == scanTypes.Local then
|
Zerotorescue@184
|
138 -- Local scan
|
Zerotorescue@184
|
139 local localCount = addon:GetLocalItemCount(thisItem.itemId, thisItem.group.name);
|
Zerotorescue@184
|
140
|
Zerotorescue@184
|
141 if not cache[thisItem.itemId] then
|
Zerotorescue@184
|
142 cache[thisItem.itemId] = {
|
Zerotorescue@184
|
143 ["itemId"] = thisItem.itemId, -- needed later for displaying
|
Zerotorescue@184
|
144 ["group"] = thisItem.group,
|
Zerotorescue@184
|
145 ["localCount"] = localCount,
|
Zerotorescue@184
|
146 };
|
Zerotorescue@184
|
147 else
|
Zerotorescue@184
|
148 cache[thisItem.itemId].globalCount = localCount;
|
Zerotorescue@184
|
149 end
|
Zerotorescue@176
|
150 end
|
Zerotorescue@176
|
151 end
|
Zerotorescue@176
|
152
|
Zerotorescue@184
|
153 self:ScheduleTimer(function()
|
Zerotorescue@176
|
154 mod:ProcessScan(verbal);
|
Zerotorescue@184
|
155 end, nextScanDelay); -- scan next item in nextScanDelay seconds
|
Zerotorescue@176
|
156 end
|
Zerotorescue@176
|
157
|
Zerotorescue@176
|
158 local function OnProceed()
|
Zerotorescue@176
|
159 InventoriumCommandHandler("summary");
|
Zerotorescue@176
|
160
|
Zerotorescue@176
|
161 if InventoriumItemMover then
|
Zerotorescue@176
|
162 InventoriumItemMover:Hide();
|
Zerotorescue@176
|
163 end
|
Zerotorescue@176
|
164 end
|
Zerotorescue@176
|
165
|
Zerotorescue@176
|
166 local function OnCancel()
|
Zerotorescue@176
|
167 if InventoriumItemMover then
|
Zerotorescue@176
|
168 InventoriumItemMover:Hide();
|
Zerotorescue@176
|
169 end
|
Zerotorescue@176
|
170 end
|
Zerotorescue@176
|
171
|
Zerotorescue@176
|
172 local function UseScanST()
|
Zerotorescue@176
|
173 if not InventoriumItemMover then
|
Zerotorescue@176
|
174 addon:CreateMoverFrame();
|
Zerotorescue@176
|
175 end
|
Zerotorescue@176
|
176
|
Zerotorescue@176
|
177 local frame = InventoriumItemMover; -- both for speed as code-consistency
|
Zerotorescue@176
|
178
|
Zerotorescue@176
|
179 -- Scrolling table with a list of items to be moved
|
Zerotorescue@176
|
180 local scrollTableWidth = ( frame.frmMeasureDummy:GetWidth() - 30 ); -- adjust width by the scrollbar size
|
Zerotorescue@176
|
181 local headers = {
|
Zerotorescue@176
|
182 {
|
Zerotorescue@176
|
183 ["name"] = "Item",
|
Zerotorescue@176
|
184 ["width"] = (scrollTableWidth * .6),
|
Zerotorescue@176
|
185 ["defaultsort"] = "asc",
|
Zerotorescue@176
|
186 ["comparesort"] = function(this, aRow, bRow, column)
|
Zerotorescue@176
|
187 local aName, _, aRarity = GetItemInfo(this:GetRow(aRow).rowData.itemId);
|
Zerotorescue@176
|
188 local bName, _, bRarity = GetItemInfo(this:GetRow(bRow).rowData.itemId);
|
Zerotorescue@176
|
189 local template = "%d%s";
|
Zerotorescue@176
|
190 aName = template:format((10 - (aRarity or 10)), (aName or ""):lower());
|
Zerotorescue@176
|
191 bName = template:format((10 - (bRarity or 10)), (bName or ""):lower());
|
Zerotorescue@176
|
192
|
Zerotorescue@176
|
193 if this.cols[column].sort == "dsc" then
|
Zerotorescue@176
|
194 return aName > bName;
|
Zerotorescue@176
|
195 else
|
Zerotorescue@176
|
196 return aName < bName;
|
Zerotorescue@176
|
197 end
|
Zerotorescue@176
|
198 end,
|
Zerotorescue@176
|
199 ["sort"] = "asc", -- when the data is set, use this column so sort the default data
|
Zerotorescue@176
|
200 ["tooltipTitle"] = "Item",
|
Zerotorescue@176
|
201 ["tooltip"] = "Click to sort the list by item quality then item name.",
|
Zerotorescue@176
|
202 },
|
Zerotorescue@176
|
203 {
|
Zerotorescue@176
|
204 ["name"] = "Local",
|
Zerotorescue@176
|
205 ["width"] = (scrollTableWidth * .2),
|
Zerotorescue@176
|
206 ["align"] = "RIGHT",
|
Zerotorescue@176
|
207 ["defaultsort"] = "dsc",
|
Zerotorescue@176
|
208 ["sortnext"] = 1,
|
Zerotorescue@176
|
209 ["comparesort"] = function(this, aRow, bRow, column)
|
Zerotorescue@176
|
210 local aAvailablePercent = (this:GetRow(aRow).rowData.localCount / this:GetRow(aRow).rowData.group.minLocalStock);
|
Zerotorescue@176
|
211 local bAvailablePercent = (this:GetRow(bRow).rowData.localCount / this:GetRow(bRow).rowData.group.minLocalStock);
|
Zerotorescue@176
|
212
|
Zerotorescue@176
|
213 if this.cols[column].sort == "dsc" then
|
Zerotorescue@176
|
214 return aAvailablePercent > bAvailablePercent;
|
Zerotorescue@176
|
215 else
|
Zerotorescue@176
|
216 return aAvailablePercent < bAvailablePercent;
|
Zerotorescue@176
|
217 end
|
Zerotorescue@176
|
218 end,
|
Zerotorescue@176
|
219 ["tooltipTitle"] = "Local Stock",
|
Zerotorescue@176
|
220 ["tooltip"] = "Click to sort the list by the local stock percentage.",
|
Zerotorescue@176
|
221 },
|
Zerotorescue@176
|
222 {
|
Zerotorescue@176
|
223 ["name"] = "Global",
|
Zerotorescue@176
|
224 ["width"] = (scrollTableWidth * .2),
|
Zerotorescue@176
|
225 ["align"] = "RIGHT",
|
Zerotorescue@176
|
226 ["defaultsort"] = "dsc",
|
Zerotorescue@176
|
227 ["sortnext"] = 1,
|
Zerotorescue@176
|
228 ["comparesort"] = function(this, aRow, bRow, column)
|
Zerotorescue@176
|
229 local aAvailablePercent = (this:GetRow(aRow).rowData.globalCount / this:GetRow(aRow).rowData.group.minGlobalStock);
|
Zerotorescue@176
|
230 local bAvailablePercent = (this:GetRow(bRow).rowData.globalCount / this:GetRow(bRow).rowData.group.minGlobalStock);
|
Zerotorescue@176
|
231
|
Zerotorescue@176
|
232 if this.cols[column].sort == "dsc" then
|
Zerotorescue@176
|
233 return aAvailablePercent > bAvailablePercent;
|
Zerotorescue@176
|
234 else
|
Zerotorescue@176
|
235 return aAvailablePercent < bAvailablePercent;
|
Zerotorescue@176
|
236 end
|
Zerotorescue@176
|
237 end,
|
Zerotorescue@176
|
238 ["tooltipTitle"] = "Global Stock",
|
Zerotorescue@176
|
239 ["tooltip"] = "Click to sort the list by the global stock percentage.",
|
Zerotorescue@176
|
240 },
|
Zerotorescue@176
|
241 };
|
Zerotorescue@176
|
242
|
Zerotorescue@176
|
243 local proceedButton = {
|
Zerotorescue@176
|
244 text = "Show in summary",
|
Zerotorescue@176
|
245 tooltipTitle = "Show in Summary",
|
Zerotorescue@176
|
246 tooltip = "Show the summary giving a more detailed list of missing items.",
|
Zerotorescue@176
|
247 onClick = OnProceed,
|
Zerotorescue@176
|
248 };
|
Zerotorescue@176
|
249 local cancelButton = {
|
Zerotorescue@176
|
250 text = "Cancel",
|
Zerotorescue@176
|
251 tooltipTitle = "Cancel",
|
Zerotorescue@176
|
252 tooltip = "Close the window.",
|
Zerotorescue@176
|
253 onClick = OnCancel,
|
Zerotorescue@176
|
254 };
|
Zerotorescue@176
|
255
|
Zerotorescue@176
|
256 addon:SetMoverFrameSettings("Inventorium Stock Alert", "You have elected to receive an alert when the following items are under your minimum stock requirement:", proceedButton, cancelButton, headers);
|
Zerotorescue@176
|
257 end
|
Zerotorescue@176
|
258
|
Zerotorescue@176
|
259 function mod:ScanFinished()
|
Zerotorescue@176
|
260 table.wipe(queue);
|
Zerotorescue@176
|
261
|
Zerotorescue@176
|
262 --addon:Debug(cache);
|
Zerotorescue@176
|
263
|
Zerotorescue@176
|
264 -- This table is never copied, just referenced. It is the same for every row.
|
Zerotorescue@176
|
265 local missingRow = {
|
Zerotorescue@176
|
266 {
|
Zerotorescue@176
|
267 ["value"] = function(data, cols, realrow, column, table)
|
Zerotorescue@176
|
268 return IdToItemLink(data[realrow].rowData.itemId);
|
Zerotorescue@176
|
269 end,
|
Zerotorescue@176
|
270 }, -- item
|
Zerotorescue@176
|
271 {
|
Zerotorescue@176
|
272 ["value"] = function(data, cols, realrow, column, table)
|
Zerotorescue@188
|
273 return addon:DisplayItemCount(data[realrow].rowData.localCount or -2, data[realrow].rowData.group.minLocalStock);
|
Zerotorescue@176
|
274 end,
|
Zerotorescue@176
|
275 }, -- local
|
Zerotorescue@176
|
276 {
|
Zerotorescue@176
|
277 ["value"] = function(data, cols, realrow, column, table)
|
Zerotorescue@188
|
278 return addon:DisplayItemCount(data[realrow].rowData.globalCount or -2, data[realrow].rowData.group.minGlobalStock);
|
Zerotorescue@176
|
279 end,
|
Zerotorescue@176
|
280 }, -- global
|
Zerotorescue@176
|
281 };
|
Zerotorescue@176
|
282
|
Zerotorescue@176
|
283 -- Store the list with rows in this
|
Zerotorescue@176
|
284 local missingList = {};
|
Zerotorescue@176
|
285
|
Zerotorescue@176
|
286 for itemId, info in pairs(cache) do
|
Zerotorescue@176
|
287 if (info.globalCount and info.globalCount < info.group.minGlobalStock) or (info.localCount and info.localCount < info.group.minLocalStock) then
|
Zerotorescue@176
|
288 -- Not enough global or not enough local
|
Zerotorescue@176
|
289
|
Zerotorescue@176
|
290 tinsert(missingList, {
|
Zerotorescue@176
|
291 ["rowData"] = info, -- this is not a key usually found in a row item and ignored by the library
|
Zerotorescue@176
|
292 ["cols"] = missingRow,
|
Zerotorescue@176
|
293 });
|
Zerotorescue@176
|
294 end
|
Zerotorescue@176
|
295 end
|
Zerotorescue@176
|
296
|
Zerotorescue@176
|
297 table.wipe(cache); -- no longer needed, all missing items are now stored in the missingList
|
Zerotorescue@176
|
298
|
Zerotorescue@176
|
299 if #missingList > 0 then
|
Zerotorescue@176
|
300 UseScanST();
|
Zerotorescue@176
|
301
|
Zerotorescue@176
|
302 addon:SetMoverFrameData(missingList);
|
Zerotorescue@176
|
303
|
Zerotorescue@176
|
304 if verbal then
|
Zerotorescue@176
|
305 addon:Print("Presenting the data...");
|
Zerotorescue@176
|
306 end
|
Zerotorescue@176
|
307 elseif verbal then
|
Zerotorescue@176
|
308 addon:Print("No items that you elected to be alerted about are below the selected stock thresholds.");
|
Zerotorescue@176
|
309 end
|
Zerotorescue@176
|
310 end
|