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