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