vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | --[[ |
2 | DynamicData |
||
3 | |||
4 | By sarf |
||
5 | |||
6 | This mod allows you to access dynamic data in WoW without being forced to rely on strange Blizzard functions |
||
7 | |||
8 | Thanks goes to the Sea people, the UltimateUI team and finally the nice (but strange) people at |
||
9 | #ultimateuitesters and Blizzard. |
||
10 | |||
11 | UltimateUIUI URL: |
||
12 | http://www.ultimateuiui.org/forums/viewtopic.php?t=NOT_YET_ANNOUNCED |
||
13 | |||
14 | ]] |
||
15 | |||
16 | --[[ |
||
17 | Information returned by the DynamicData.item.get*Info() methods |
||
18 | |||
19 | An array is returned with the following values |
||
20 | |||
21 | name -- the name of the item |
||
22 | strings -- an array with strings that represent the tooltip of the item |
||
23 | count -- the number of items like this the user currently possesses |
||
24 | texture |
||
25 | cooldown = -- the cooldown of the item |
||
26 | { |
||
27 | start -- time when the cooldown started |
||
28 | duration -- duration of the cooldown |
||
29 | enable -- 1 or 0 |
||
30 | }; |
||
31 | |||
32 | -- each item may have these values: |
||
33 | |||
34 | durability -- current durability |
||
35 | maxDurability -- maximum durability |
||
36 | itemType -- type of item |
||
37 | locked -- ? |
||
38 | |||
39 | These values are 0 unless the item info derives from a ContainerInfo call (bag >= 0): |
||
40 | |||
41 | quality -- degree of commonness |
||
42 | readable -- ? |
||
43 | |||
44 | These values are 0 or "" unless the item info derives from a InventoryInfo call (bag == -1): |
||
45 | |||
46 | broken -- true if broken, false if not |
||
47 | slotTexture -- background texture of the slot that the item resides in. |
||
48 | |||
49 | |||
50 | ]]-- |
||
51 | |||
52 | |||
53 | DYNAMICDATA_ITEM_SCAN_TYPE_TOOLTIP = 1; |
||
54 | DYNAMICDATA_ITEM_SCAN_TYPE_ITEMINFO = 2; |
||
55 | DYNAMICDATA_ITEM_SCAN_TYPE_COOLDOWN = 4; |
||
56 | DYNAMICDATA_ITEM_SCAN_TYPE_EVERYTHING = 7; |
||
57 | DYNAMICDATA_ITEM_SCAN_TYPE_QUICK = 6; |
||
58 | |||
59 | |||
60 | -- Item information - what the player is wearing and so on. |
||
61 | DynamicData.item = { |
||
62 | |||
63 | -- public functions |
||
64 | |||
65 | -- |
||
66 | -- addOnInventoryUpdateHandler (func) |
||
67 | -- |
||
68 | -- Adds a function name that will be called on inventory updates. |
||
69 | -- Function will have two parameters: |
||
70 | -- bag, which may be nil. |
||
71 | -- scanType, which may be DYNAMICDATA_ITEM_SCAN_TYPE_* |
||
72 | -- |
||
73 | addOnInventoryUpdateHandler = function (func) |
||
74 | return DynamicData.util.addOnWhateverHandler(DynamicData.item.OnInventoryUpdateHandlers, func); |
||
75 | end; |
||
76 | |||
77 | -- |
||
78 | -- removeOnInventoryUpdateHandler (func) |
||
79 | -- |
||
80 | -- Removes the specified function, so that it will not be called on inventory updates. |
||
81 | -- |
||
82 | removeOnInventoryUpdateHandler = function (func) |
||
83 | return DynamicData.util.removeOnWhateverHandler(DynamicData.item.OnInventoryUpdateHandlers, func); |
||
84 | end; |
||
85 | |||
86 | -- LEGACY FUNCTION - covered in addOnInventoryUpdateHandler |
||
87 | -- |
||
88 | -- addOnInventoryCooldownUpdateHandler (func) |
||
89 | -- |
||
90 | -- Adds a function name that will be called on InventoryCooldown updates. |
||
91 | -- Function will have one paremeter - bag, which may be nil. |
||
92 | -- |
||
93 | addOnInventoryCooldownUpdateHandler = function (func) |
||
94 | return DynamicData.util.addOnWhateverHandler(DynamicData.item.OnInventoryCooldownUpdateHandlers, func); |
||
95 | end; |
||
96 | |||
97 | -- LEGACY FUNCTION - covered in removeOnInventoryUpdateHandler |
||
98 | -- |
||
99 | -- removeOnInventoryCooldownUpdateHandler (func) |
||
100 | -- |
||
101 | -- Removes the specified function, so that it will not be called on InventoryCooldown updates. |
||
102 | -- |
||
103 | removeOnInventoryCooldownUpdateHandler = function (func) |
||
104 | return DynamicData.util.removeOnWhateverHandler(DynamicData.item.OnInventoryCooldownUpdateHandlers, func); |
||
105 | end; |
||
106 | |||
107 | -- |
||
108 | -- getEquippedSlotInfo (slot) |
||
109 | -- |
||
110 | -- Retrieves information about the slot. |
||
111 | -- |
||
112 | getEquippedSlotInfo = function (slot) |
||
113 | if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) and ( DynamicData.item.player.itemsByBag[-1] ) and ( DynamicData.item.player.itemsByBag[-1][slot] ) ) then |
||
114 | return DynamicData.item.player.itemsByBag[-1][slot]; |
||
115 | else |
||
116 | return DynamicData.item.defaultItem; |
||
117 | end |
||
118 | end; |
||
119 | |||
120 | -- |
||
121 | -- getItemInfoByName (itemName) |
||
122 | -- |
||
123 | -- Retrieves information about an item by name. |
||
124 | -- Adds a new variable called position with the position(s) of the item. |
||
125 | -- |
||
126 | getItemInfoByName = function (itemName) |
||
127 | if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) ) then |
||
128 | local element = nil; |
||
129 | for bagNumber, bag in DynamicData.item.player.itemsByBag do |
||
130 | for slotNumber, slot in bag do |
||
131 | if ( slot.name == itemName ) then |
||
132 | if ( not element ) then |
||
133 | element = DynamicData.item.createBaseItem(slot); |
||
134 | else |
||
135 | if ( slot.count ) then |
||
136 | element.count = element.count + slot.count; |
||
137 | end |
||
138 | end |
||
139 | if ( not element.position ) then |
||
140 | element.position = {}; |
||
141 | end |
||
142 | local positionArray = {}; |
||
143 | positionArray.bag = bagNumber; |
||
144 | positionArray.slot = slotNumber; |
||
145 | table.insert(element.position, positionArray); |
||
146 | end |
||
147 | end |
||
148 | end |
||
149 | return element; |
||
150 | else |
||
151 | return DynamicData.item.defaultItem; |
||
152 | end |
||
153 | end; |
||
154 | |||
155 | -- |
||
156 | -- getItemInfoByType (itemType) |
||
157 | -- |
||
158 | -- Retrieves information about items with the specific type. Includes a new cute variable called totalCount. |
||
159 | -- |
||
160 | getItemInfoByType = function (itemName) |
||
161 | local bagNumber, bag; |
||
162 | local slotNumber, itemInfo; |
||
163 | local items = {}; |
||
164 | for bagNumber, bag in DynamicData.item.player.itemsByBag do |
||
165 | for slotNumber, itemInfo in bag do |
||
166 | if ( itemInfo.itemType == itemType ) then |
||
167 | table.insert(items, DynamicData.item.getItemInfoByName(itemInfo.name)); |
||
168 | end |
||
169 | end |
||
170 | end |
||
171 | return items; |
||
172 | end; |
||
173 | |||
174 | -- |
||
175 | -- getEquippedSlotCooldown (slot) |
||
176 | -- |
||
177 | -- Retrieves cooldown information about the slot. |
||
178 | -- |
||
179 | getEquippedSlotCooldown = function (slot) |
||
180 | if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) and ( DynamicData.item.player.itemsByBag[-1] ) and ( DynamicData.item.player.itemsByBag[-1][slot] ) ) then |
||
181 | local cooldown = DynamicData.item.player.itemsByBag[-1][slot].cooldown; |
||
182 | return cooldown[1], cooldown[2], cooldown[3]; |
||
183 | else |
||
184 | return 0, 0, 0; |
||
185 | end |
||
186 | end; |
||
187 | |||
188 | -- |
||
189 | -- getInventoryInfo (bag, slot) |
||
190 | -- |
||
191 | -- Retrieves information about the bag and slot. |
||
192 | -- |
||
193 | getInventoryInfo = function (bag, slot) |
||
194 | DynamicData.item.scanInventorySlotIfTime(bag, slot); |
||
195 | local element = DynamicData.item.player.itemsByBag[bag][slot]; |
||
196 | if ( not element ) then |
||
197 | element = DynamicData.item.defaultItem; |
||
198 | end |
||
199 | return element; |
||
200 | end; |
||
201 | |||
202 | -- |
||
203 | -- getInventoryName (bag, slot) |
||
204 | -- |
||
205 | -- Retrieves the name of the item in the bag and slot. |
||
206 | -- |
||
207 | getInventoryName = function (bag, slot) |
||
208 | if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) and ( DynamicData.item.player.itemsByBag[bag] ) and ( DynamicData.item.player.itemsByBag[bag][slot] ) ) then |
||
209 | local itemInfo = DynamicData.item.getInventoryInfo(bag, slot); |
||
210 | if ( ( not itemInfo ) or ( ( itemInfo.texture ) and ( strlen(itemInfo.texture) > 0 ) and ( ( not itemInfo.name ) or ( strlen(itemInfo.name) <= 0 ) ) ) ) then |
||
211 | DynamicData.item.scanItem(bag, slot); |
||
212 | itemInfo = DynamicData.item.player.itemsByBag[bag][slot]; |
||
213 | end |
||
214 | return itemInfo.name; |
||
215 | else |
||
216 | return DynamicData.item.defaultItem.name; |
||
217 | end |
||
218 | end; |
||
219 | |||
220 | -- |
||
221 | -- getInventoryCooldownInfo (bag, slot) |
||
222 | -- |
||
223 | -- Retrieves cooldown information about the bag and slot. |
||
224 | -- |
||
225 | getInventoryCooldown = function (bag, slot) |
||
226 | if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) and ( DynamicData.item.player.itemsByBag[bag] ) and ( DynamicData.item.player.itemsByBag[bag][slot] ) ) then |
||
227 | local cooldown = DynamicData.item.player.itemsByBag[bag][slot].cooldown; |
||
228 | return cooldown[1], cooldown[2], cooldown[3]; |
||
229 | else |
||
230 | return 0, 0, 0; |
||
231 | end |
||
232 | end; |
||
233 | |||
234 | -- |
||
235 | -- getEquippedSlotInfoBySlotName (slotName) |
||
236 | -- |
||
237 | -- Retrieves information about the slot with the specified name. |
||
238 | -- |
||
239 | getEquippedSlotInfoBySlotName = function (slotName) |
||
240 | for key, value in DynamicData.item.inventorySlotNames do |
||
241 | if ( value.name == slotName ) then |
||
242 | return DynamicData.item.getEquippedSlotInfo(value.id); |
||
243 | end |
||
244 | end |
||
245 | return DynamicData.item.defaultItem; |
||
246 | end; |
||
247 | |||
248 | -- |
||
249 | -- updateItems () |
||
250 | -- |
||
251 | -- Updates the inventory of the player. |
||
252 | -- |
||
253 | updateItems = function (bag) |
||
254 | params = { |
||
255 | func = DynamicData.item.doUpdateItems, |
||
256 | params = { bag }, |
||
257 | allowInitialUpdate = 1, |
||
258 | schedulingName = "DynamicData_item_UpdateItems", |
||
259 | }; |
||
260 | --DynamicData.util.postpone(params); |
||
261 | DynamicData.item.doUpdateItems(bag); |
||
262 | end; |
||
263 | |||
264 | -- |
||
265 | -- updateItemCooldowns () |
||
266 | -- |
||
267 | -- Updates the cooldowns of the players items. |
||
268 | -- |
||
269 | updateItemCooldowns = function () |
||
270 | local safe = true; --DynamicData.util.safeToUseTooltips({"MerchantFrame", "TradeSkillFrame", "AuctionFrame"}); |
||
271 | if ( not safe ) then |
||
272 | UltimateUI_ScheduleByName("DynamicData_item_updateItemCooldownsUnspecified", 0.1, DynamicData.item.updateItemCooldowns); |
||
273 | return; |
||
274 | end |
||
275 | DynamicData.item.doQuickScan(); |
||
276 | --[[ |
||
277 | local bag; |
||
278 | for bag = 0,4 do |
||
279 | DynamicData.item.doUpdateBagItemsCooldown(bag); |
||
280 | end |
||
281 | DynamicData.item.doUpdateBagItemsCooldown(-1); |
||
282 | bag = nil; |
||
283 | DynamicData.item.notifyUpdateHandlers(nil, DYNAMICDATA_ITEM_SCAN_TYPE_COOLDOWN); |
||
284 | DynamicData.item.notifyItemCooldownUpdateHandlers(); |
||
285 | ]]-- |
||
286 | end; |
||
287 | |||
288 | -- |
||
289 | -- updateItemLocks () |
||
290 | -- |
||
291 | -- Updates the locks of the players items. |
||
292 | -- |
||
293 | updateItemLocks = function () |
||
294 | DynamicData.item.updateItems(); |
||
295 | end; |
||
296 | |||
297 | -- |
||
298 | -- updateItemAlerts () |
||
299 | -- |
||
300 | -- Updates the alerts of the players items. |
||
301 | -- You can never have too many lerts. |
||
302 | -- |
||
303 | updateItemAlerts = function () |
||
304 | DynamicData.item.updateItems(); |
||
305 | end; |
||
306 | |||
307 | -- protected functions |
||
308 | |||
309 | |||
310 | -- |
||
311 | -- doUpdateSeperateBagItems (bag) |
||
312 | -- |
||
313 | -- Updates a bag seperately from the rest of the inventory of the player. |
||
314 | -- Saves some time. |
||
315 | -- |
||
316 | doUpdateSeperateBagItems = function (bag) |
||
317 | if ( not bag ) then |
||
318 | return; |
||
319 | end |
||
320 | if ( DynamicData.item.player.itemsByBag ) then |
||
321 | table.remove(DynamicData.item.player.itemsByBag, bag); |
||
322 | end |
||
323 | DynamicData.item.doUpdateBagItems(bag); |
||
324 | end; |
||
325 | |||
326 | -- |
||
327 | -- doUpdateBagItems (bag) |
||
328 | -- |
||
329 | -- Updates a bag of the inventory of the player. |
||
330 | -- |
||
331 | doUpdateBagItems = function (bag) |
||
332 | DynamicData.item.scanItemsInBag(bag); |
||
333 | end; |
||
334 | |||
335 | -- |
||
336 | -- doUpdateItems () |
||
337 | -- |
||
338 | -- Initiates updates of the inventory of the player. |
||
339 | -- |
||
340 | doUpdateItems = function (bag) |
||
341 | local safe = true; --DynamicData.util.safeToUseTooltips({"MerchantFrame", "TradeSkillFrame", "AuctionFrame"}); |
||
342 | if ( not safe ) then |
||
343 | if ( bag ) then |
||
344 | UltimateUI_ScheduleByName("DynamicData_item_doUpdateItems", 0.1, DynamicData.item.doUpdateItems, bag); |
||
345 | else |
||
346 | UltimateUI_ScheduleByName("DynamicData_item_doUpdateItemsUnspecified", 0.1, DynamicData.item.doUpdateItems); |
||
347 | end |
||
348 | return; |
||
349 | end |
||
350 | DynamicData.item.doQuickScan(); |
||
351 | if ( ( bag ) and ( DynamicData.item.player ) ) then |
||
352 | --DynamicData.item.doQuickScan(bag); |
||
353 | --local scanLists = DynamicData.item.generateScanLists(nil, bag); |
||
354 | --DynamicData.item.addScans(scanLists); |
||
355 | DynamicData.item.makeScanLists(bag); |
||
356 | if ( not DynamicData.item.itemScanInProgress ) then |
||
357 | --DynamicData.item.doScans(nil, nil, bag); |
||
358 | DynamicData.item.doScans(nil, nil, bag); |
||
359 | --UltimateUI_ScheduleByName("DynamicData_Item_doScans", 0.1, DynamicData.item.doScans); |
||
360 | end |
||
361 | --DynamicData.item.doUpdateSeperateBagItems(bag); |
||
362 | --DynamicData.item.notifyUpdateHandlers(bag); |
||
363 | --DynamicData.item.notifyItemCooldownUpdateHandlers(); |
||
364 | else |
||
365 | --DynamicData.item.player = {}; |
||
366 | --local scanLists = DynamicData.item.generateScanLists(); |
||
367 | --DynamicData.item.addScans(scanLists); |
||
368 | DynamicData.item.makeScanLists(); |
||
369 | --DynamicData.item.doQuickScan(); |
||
370 | if ( not DynamicData.item.itemScanInProgress ) then |
||
371 | DynamicData.item.doScans(nil); |
||
372 | --UltimateUI_ScheduleByName("DynamicData_Item_doScans", 0.1, DynamicData.item.doScans); |
||
373 | end |
||
374 | end |
||
375 | end; |
||
376 | |||
377 | -- |
||
378 | -- addScans(scanLists) |
||
379 | -- |
||
380 | -- Adds scan lists to the global scanlist thingy. |
||
381 | -- |
||
382 | addScans = function (scanLists) |
||
383 | for k, v in scanLists do |
||
384 | for bag, slot in v do |
||
385 | if ( not DynamicData.item.scanList ) then |
||
386 | DynamicData.item.scanList = {}; |
||
387 | end |
||
388 | if ( not DynamicData.item.scanList[bag] ) then |
||
389 | DynamicData.item.scanList[bag] = {}; |
||
390 | end |
||
391 | if ( not DynamicData.item.scanList[bag][slot] ) then |
||
392 | DynamicData.item.scanList[bag][slot] = 0; |
||
393 | end |
||
394 | DynamicData.item.scanList[bag][slot] = 1; |
||
395 | end |
||
396 | --table.insert(DynamicData.item.scanList, v); |
||
397 | end |
||
398 | end; |
||
399 | |||
400 | |||
401 | |||
402 | -- |
||
403 | -- doScans (scanLists, currentIndex) |
||
404 | -- |
||
405 | -- scans the currently indicated list and schedules next scan list. |
||
406 | -- when completed, generates update notification. |
||
407 | -- |
||
408 | doScans = function (scanLists, currentIndex, bag) |
||
409 | scanLists = nil; |
||
410 | --[[ |
||
411 | if ( not scanLists ) then |
||
412 | scanLists = DynamicData.item.scanList; |
||
413 | end |
||
414 | ]]-- |
||
415 | local scheduleName = "DynamicData_Item_doScans"; |
||
416 | if ( bag ) then |
||
417 | --scheduleName = scheduleName.."_"..bag; |
||
418 | end |
||
419 | DynamicData.item.itemScanInProgress = true; |
||
420 | if ( not currentIndex ) then |
||
421 | -- if first time, then we schedule a new scan - this is to prevent the stuttering effect when receiving loads of updates in short succession. |
||
422 | --[[ |
||
423 | if ( scanLists == DynamicData.item.scanList ) then |
||
424 | scanLists = nil; |
||
425 | end |
||
426 | ]]-- |
||
427 | UltimateUI_ScheduleByName(scheduleName, 0.1, DynamicData.item.doScans, scanLists, 1, bag); |
||
428 | return; |
||
429 | else |
||
430 | -- prevents old scans from continuing. |
||
431 | UltimateUI_ScheduleByName(scheduleName, 0.1, DynamicData.item.doScans); |
||
432 | end |
||
433 | local scanType = DYNAMICDATA_ITEM_SCAN_TYPE_TOOLTIP; |
||
434 | if ( DynamicData.item.scanItems(scanType) ) then |
||
435 | if ( scanLists == DynamicData.item.scanList ) then |
||
436 | scanLists = nil; |
||
437 | end |
||
438 | UltimateUI_ScheduleByName(scheduleName, 0.1, DynamicData.item.doScans, scanLists, currentIndex, bag); |
||
439 | return; |
||
440 | else |
||
441 | if ( scanLists == DynamicData.item.scanList ) then |
||
442 | --DynamicData.item.scanList = {}; |
||
443 | end |
||
444 | DynamicData.item.itemScanInProgress = false; |
||
445 | DynamicData.item.notifyUpdateHandlers(bag, scanType); |
||
446 | --DynamicData.item.notifyItemCooldownUpdateHandlers(); |
||
447 | end |
||
448 | end; |
||
449 | |||
450 | |||
451 | -- |
||
452 | -- doUpdateBagItemsCooldown (bag) |
||
453 | -- |
||
454 | -- Updates the cooldown a bag of the inventory of the player. |
||
455 | -- |
||
456 | doUpdateBagItemsCooldown = function (bag) |
||
457 | if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) and ( DynamicData.item.player.itemsByBag[bag] ) ) then |
||
458 | if ( bag > -1 ) then |
||
459 | local element = nil; |
||
460 | for slot = 1,GetContainerNumSlots(bag) do |
||
461 | if ( DynamicData.item.player.itemsByBag[bag][slot] ) then |
||
462 | local ic_start, ic_duration, ic_enable = GetContainerItemCooldown(bag, slot); |
||
463 | local itemCooldown = DynamicData.item.getOldCooldown(bag, slot); |
||
464 | itemCooldown[1] = ic_start; |
||
465 | itemCooldown[2] = ic_duration; |
||
466 | itemCooldown[3] = ic_enable; |
||
467 | itemCooldown.start = ic_start; |
||
468 | itemCooldown.duration = ic_duration; |
||
469 | itemCooldown.enable = ic_enable; |
||
470 | DynamicData.item.player.itemsByBag[bag][slot].cooldown = itemCooldown; |
||
471 | end |
||
472 | end |
||
473 | else |
||
474 | for k, v in DynamicData.item.inventorySlotNames do |
||
475 | slot = v.id; |
||
476 | if ( DynamicData.item.player.itemsByBag[bag][slot] ) then |
||
477 | local ic_start, ic_duration, ic_enable = GetInventoryItemCooldown("player", slot); |
||
478 | local itemCooldown = DynamicData.item.getOldCooldown(bag, slot); |
||
479 | itemCooldown[1] = ic_start; |
||
480 | itemCooldown[2] = ic_duration; |
||
481 | itemCooldown[3] = ic_enable; |
||
482 | itemCooldown.start = ic_start; |
||
483 | itemCooldown.duration = ic_duration; |
||
484 | itemCooldown.enable = ic_enable; |
||
485 | DynamicData.item.player.itemsByBag[bag][slot].cooldown = itemCooldown; |
||
486 | end |
||
487 | end |
||
488 | end |
||
489 | end |
||
490 | end; |
||
491 | |||
492 | -- private functions |
||
493 | |||
494 | -- |
||
495 | -- notifyUpdateHandlers (bag) |
||
496 | -- |
||
497 | -- Args: |
||
498 | -- bag - if not nil, the bag that has been updated |
||
499 | -- scanType - the type of scan that has completed |
||
500 | -- |
||
501 | -- Notifies all update handlers that an update has occurred. |
||
502 | -- |
||
503 | notifyUpdateHandlers = function (bag, scanType) |
||
504 | DynamicData.util.notifyWhateverHandlers(DynamicData.item.OnInventoryUpdateHandlers, bag, scanType); |
||
505 | end; |
||
506 | |||
507 | -- LEGACY FUNCTION |
||
508 | -- |
||
509 | -- notifyItemCooldownUpdateHandlers () |
||
510 | -- |
||
511 | -- Notifies all item cooldown update handlers that an item cooldown has occurred. |
||
512 | -- |
||
513 | notifyItemCooldownUpdateHandlers = function () |
||
514 | DynamicData.util.notifyWhateverHandlers(DynamicData.item.OnInventoryCooldownUpdateHandlers); |
||
515 | end; |
||
516 | |||
517 | -- |
||
518 | -- OnLoad () |
||
519 | -- |
||
520 | -- Sets up the DynamicData.item for operation. |
||
521 | -- In this case, it retrieves the IDs for the inventory slots. |
||
522 | -- |
||
523 | OnLoad = function () |
||
524 | for key, value in DynamicData.item.inventorySlotNames do |
||
525 | DynamicData.item.inventorySlotNames[key].id = GetInventorySlotInfo(value.name); |
||
526 | end |
||
527 | DynamicData.item.doUpdateItems(); |
||
528 | UltimateUI_AfterInit(DynamicData.item.doUpdateItems); |
||
529 | UltimateUI_AfterInit(UltimateUI_Schedule, 30, DynamicData.item.doUpdateItems); |
||
530 | UltimateUI_AfterInit(UltimateUI_Schedule, 60, DynamicData.item.doUpdateItems); |
||
531 | UltimateUI_AfterInit(UltimateUI_Schedule, 90, DynamicData.item.doUpdateItems); |
||
532 | end; |
||
533 | |||
534 | -- variables |
||
535 | |||
536 | -- Taken from ItemBuff - thanks, Telo! |
||
537 | -- Used for mapping inventory (equipment) ids and slot names |
||
538 | inventorySlotNames = { |
||
539 | { name = "HeadSlot" }, |
||
540 | { name = "NeckSlot" }, |
||
541 | { name = "ShoulderSlot" }, |
||
542 | { name = "BackSlot" }, |
||
543 | { name = "ChestSlot" }, |
||
544 | { name = "ShirtSlot" }, |
||
545 | { name = "TabardSlot" }, |
||
546 | { name = "WristSlot" }, |
||
547 | { name = "HandsSlot" }, |
||
548 | { name = "WaistSlot" }, |
||
549 | { name = "LegsSlot" }, |
||
550 | { name = "FeetSlot" }, |
||
551 | { name = "Finger0Slot" }, |
||
552 | { name = "Finger1Slot" }, |
||
553 | { name = "Trinket0Slot" }, |
||
554 | { name = "Trinket1Slot" }, |
||
555 | { name = "MainHandSlot" }, |
||
556 | { name = "SecondaryHandSlot" }, |
||
557 | { name = "RangedSlot" }, |
||
558 | }; |
||
559 | |||
560 | -- Contains lists of items that should be scanned. |
||
561 | scanList = {}; |
||
562 | |||
563 | -- Contains lists of when item slots were scanned. |
||
564 | scanListScanned = {}; |
||
565 | |||
566 | -- Whether a scan is in progress or not. |
||
567 | itemScanInProgress = false; |
||
568 | |||
569 | -- Contains item data about the player's items. |
||
570 | player = {}; |
||
571 | |||
572 | -- Contains the function pointers to functions that want to be called whenever the inventory updates. |
||
573 | -- Will be called AFTER the DynamicData has parsed the inventory. |
||
574 | OnInventoryUpdateHandlers = {}; |
||
575 | |||
576 | -- Contains the function pointers to functions that want to be called whenever the inventory cooldown updates. |
||
577 | -- Will be called AFTER the DynamicData has parsed the inventory. |
||
578 | OnInventoryCooldownUpdateHandlers = {}; |
||
579 | |||
580 | defaultItem = { |
||
581 | name = "", |
||
582 | strings = { |
||
583 | [1] = {}, |
||
584 | [2] = {}, |
||
585 | [3] = {}, |
||
586 | [4] = {}, |
||
587 | [5] = {}, |
||
588 | [6] = {}, |
||
589 | [7] = {}, |
||
590 | [8] = {}, |
||
591 | [9] = {}, |
||
592 | [10] = {}, |
||
593 | [11] = {}, |
||
594 | [12] = {}, |
||
595 | [13] = {}, |
||
596 | [14] = {}, |
||
597 | [15] = {} |
||
598 | }, |
||
599 | count = 0, |
||
600 | slotCount = 0, |
||
601 | texture = "", |
||
602 | cooldown = { |
||
603 | [1] = 0, |
||
604 | [2] = 0, |
||
605 | [3] = 0, |
||
606 | start = 0, |
||
607 | duration = 0, |
||
608 | enable = 0 |
||
609 | }, |
||
610 | itemType = "", |
||
611 | locked = 0, |
||
612 | durability = nil, |
||
613 | maxDurability = nil, |
||
614 | quality = 0, |
||
615 | readable = 0, |
||
616 | broken = 0, |
||
617 | slotTexture = "" |
||
618 | }; |
||
619 | |||
620 | -- |
||
621 | -- createBaseItem () |
||
622 | -- |
||
623 | -- creates a basic item with all attributes set to defaults. |
||
624 | -- |
||
625 | createBaseItem = function (baseItem) |
||
626 | local newItem = {}; |
||
627 | for k, v in DynamicData.item.defaultItem do |
||
628 | newItem[k] = v; |
||
629 | end |
||
630 | if ( baseItem ) then |
||
631 | for k, v in baseItem do |
||
632 | newItem[k] = v; |
||
633 | end |
||
634 | end |
||
635 | return newItem; |
||
636 | end; |
||
637 | |||
638 | |||
639 | -- |
||
640 | -- makeScanList (numberOfScansPerList, bag) |
||
641 | -- |
||
642 | -- Makes a list of scans. |
||
643 | -- |
||
644 | makeScanLists = function (bag) |
||
645 | if ( not DynamicData.item.scanList ) then |
||
646 | DynamicData.item.scanList = {}; |
||
647 | end |
||
648 | if ( not bag ) then |
||
649 | for bag = 0, 4, 1 do |
||
650 | for slot = 1, GetContainerNumSlots(bag), 1 do |
||
651 | if ( not DynamicData.item.scanList[bag] ) then |
||
652 | DynamicData.item.scanList[bag] = {}; |
||
653 | end |
||
654 | DynamicData.item.scanList[bag][slot] = 1; |
||
655 | end |
||
656 | end |
||
657 | bag = -1; |
||
658 | for slot = 1, 19, 1 do |
||
659 | if ( not DynamicData.item.scanList[bag] ) then |
||
660 | DynamicData.item.scanList[bag] = {}; |
||
661 | end |
||
662 | DynamicData.item.scanList[bag][slot] = 1; |
||
663 | end |
||
664 | elseif ( bag <= -1 ) then |
||
665 | bag = -1; |
||
666 | if ( not DynamicData.item.scanList[bag] ) then |
||
667 | DynamicData.item.scanList[bag] = {}; |
||
668 | end |
||
669 | for slot = 1, 19, 1 do |
||
670 | DynamicData.item.scanList[bag][slot] = 1; |
||
671 | end |
||
672 | else |
||
673 | if ( not DynamicData.item.scanList[bag] ) then |
||
674 | DynamicData.item.scanList[bag] = {}; |
||
675 | end |
||
676 | for slot = 1, GetContainerNumSlots(bag), 1 do |
||
677 | DynamicData.item.scanList[bag][slot] = 1; |
||
678 | end |
||
679 | end |
||
680 | end; |
||
681 | |||
682 | -- |
||
683 | -- generateScanLists (numberOfScansPerList, bag) |
||
684 | -- |
||
685 | -- Generates a list of scans. |
||
686 | -- |
||
687 | generateScanLists = function (numberOfScansPerList, bag) |
||
688 | if ( not numberOfScansPerList ) then |
||
689 | numberOfScansPerList = DYNAMICDATA_DEFAULT_NUMBER_OF_TOOLTIP_SCANS_PER_UPDATE; |
||
690 | end |
||
691 | local lists = {}; |
||
692 | local numberOfCurrentScans = 0; |
||
693 | local currentList = {}; |
||
694 | local slot; |
||
695 | if ( not bag ) then |
||
696 | for bag = 0, 4, 1 do |
||
697 | for slot = 1, GetContainerNumSlots(bag), 1 do |
||
698 | if ( not currentList[bag] ) then |
||
699 | currentList[bag] = {}; |
||
700 | end |
||
701 | table.insert(currentList[bag], slot); |
||
702 | numberOfCurrentScans = numberOfCurrentScans + 1; |
||
703 | if ( numberOfCurrentScans >= numberOfScansPerList) then |
||
704 | table.insert(lists, currentList); |
||
705 | currentList = {}; |
||
706 | numberOfCurrentScans = 0; |
||
707 | end |
||
708 | end |
||
709 | end |
||
710 | bag = -1; |
||
711 | for slot = 1, 19, 1 do |
||
712 | if ( not currentList[bag] ) then |
||
713 | currentList[bag] = {}; |
||
714 | end |
||
715 | table.insert(currentList[bag], slot); |
||
716 | numberOfCurrentScans = numberOfCurrentScans + 1; |
||
717 | if ( numberOfCurrentScans >= numberOfScansPerList) then |
||
718 | table.insert(lists, currentList); |
||
719 | currentList = {}; |
||
720 | numberOfCurrentScans = 0; |
||
721 | end |
||
722 | end |
||
723 | elseif ( bag <= -1 ) then |
||
724 | bag = -1; |
||
725 | for slot = 1, 19, 1 do |
||
726 | if ( not currentList[bag] ) then |
||
727 | currentList[bag] = {}; |
||
728 | end |
||
729 | table.insert(currentList[bag], slot); |
||
730 | numberOfCurrentScans = numberOfCurrentScans + 1; |
||
731 | if ( numberOfCurrentScans >= numberOfScansPerList) then |
||
732 | table.insert(lists, currentList); |
||
733 | currentList = {}; |
||
734 | numberOfCurrentScans = 0; |
||
735 | end |
||
736 | end |
||
737 | else |
||
738 | for slot = 1, GetContainerNumSlots(bag), 1 do |
||
739 | if ( not currentList[bag] ) then |
||
740 | currentList[bag] = {}; |
||
741 | end |
||
742 | table.insert(currentList[bag], slot); |
||
743 | numberOfCurrentScans = numberOfCurrentScans + 1; |
||
744 | if ( numberOfCurrentScans >= numberOfScansPerList) then |
||
745 | table.insert(lists, currentList); |
||
746 | currentList = {}; |
||
747 | numberOfCurrentScans = 0; |
||
748 | end |
||
749 | end |
||
750 | end |
||
751 | if ( numberOfCurrentScans > 0) then |
||
752 | table.insert(lists, currentList); |
||
753 | end |
||
754 | return lists; |
||
755 | end; |
||
756 | |||
757 | -- |
||
758 | -- doQuickScan (bag) |
||
759 | -- |
||
760 | -- does a quick scan of the bag (or of the whole inventory if bag is not specified). |
||
761 | -- |
||
762 | doQuickScan = function(bag) |
||
763 | if ( bag ) then |
||
764 | DynamicData.item.scanItemsInBag(bag, DYNAMICDATA_ITEM_SCAN_TYPE_QUICK); |
||
765 | else |
||
766 | for i = 0, 4, 1 do |
||
767 | DynamicData.item.scanItemsInBag(i, DYNAMICDATA_ITEM_SCAN_TYPE_QUICK); |
||
768 | end |
||
769 | DynamicData.item.scanItemsInBag(-1, DYNAMICDATA_ITEM_SCAN_TYPE_QUICK); |
||
770 | end |
||
771 | DynamicData.item.notifyUpdateHandlers(bag, DYNAMICDATA_ITEM_SCAN_TYPE_QUICK); |
||
772 | DynamicData.item.notifyItemCooldownUpdateHandlers(); |
||
773 | end; |
||
774 | |||
775 | -- |
||
776 | -- scanItemsInBag (bag, scanType) |
||
777 | -- |
||
778 | -- scans all items in bag and puts the info into the database |
||
779 | -- can be retailored to only scan the tooltip, everything but the tooltip and everything. |
||
780 | -- |
||
781 | scanItemsInBag = function(bag, scanType) |
||
782 | local bag, slot, v; |
||
783 | if ( not bag ) then |
||
784 | return; |
||
785 | end |
||
786 | if ( bag <= -1 ) then |
||
787 | for slot = 1, 19, 1 do |
||
788 | DynamicData.item.scanItem(-1, slot, scanType); |
||
789 | end |
||
790 | else |
||
791 | for slot = 1, GetContainerNumSlots(bag), 1 do |
||
792 | DynamicData.item.scanItem(bag, slot, scanType); |
||
793 | end |
||
794 | end |
||
795 | end; |
||
796 | |||
797 | -- |
||
798 | -- scanItems (list, scanType) |
||
799 | -- |
||
800 | -- scans a list of item slots item and puts the info into the database |
||
801 | -- can be retailored to only scan the tooltip, everything but the tooltip and everything. |
||
802 | -- list format : list[bag] = { slot1, slot2, slot3 ... }; |
||
803 | -- |
||
804 | scanItems = function(scanType) |
||
805 | local curTime = GetTime(); |
||
806 | local numberScanned = 0; |
||
807 | local scanned = false; |
||
808 | for bag, bagValue in DynamicData.item.scanList do |
||
809 | for slot, value in bagValue do |
||
810 | if ( value == 1 ) then |
||
811 | DynamicData.item.scanItem(bag, slot, scanType); |
||
812 | DynamicData.item.scanList[bag][slot] = 0; |
||
813 | if ( not DynamicData.item.scanListScanned ) then |
||
814 | DynamicData.item.scanListScanned = {}; |
||
815 | end |
||
816 | if ( not DynamicData.item.scanListScanned[bag] ) then |
||
817 | DynamicData.item.scanListScanned[bag] = {}; |
||
818 | end |
||
819 | DynamicData.item.scanListScanned[bag][slot] = curTime; |
||
820 | numberScanned = numberScanned + 1; |
||
821 | scanned = true; |
||
822 | if ( numberScanned >= DYNAMICDATA_DEFAULT_NUMBER_OF_TOOLTIP_SCANS_PER_UPDATE ) then |
||
823 | return scanned; |
||
824 | end |
||
825 | end |
||
826 | end |
||
827 | end |
||
828 | return scanned; |
||
829 | --[[ |
||
830 | for bag, v in list do |
||
831 | for key, slot in v do |
||
832 | DynamicData.item.scanItem(bag, slot, scanType); |
||
833 | end |
||
834 | end |
||
835 | ]]-- |
||
836 | end; |
||
837 | |||
838 | -- |
||
839 | -- scanItem (bag, slot) |
||
840 | -- |
||
841 | -- scans an item and puts the info into the item database |
||
842 | -- |
||
843 | scanItem = function(bag, slot, scanType) |
||
844 | if ( not scanType ) then |
||
845 | scanType = DYNAMICDATA_ITEM_SCAN_TYPE_EVERYTHING; |
||
846 | end |
||
847 | local strings = nil; |
||
848 | local itemName = nil; |
||
849 | local element = nil; |
||
850 | if ( not DynamicData.item.scanListScanned ) then |
||
851 | DynamicData.item.scanListScanned = {}; |
||
852 | end |
||
853 | if ( not DynamicData.item.scanListScanned[bag] ) then |
||
854 | DynamicData.item.scanListScanned[bag] = {}; |
||
855 | end |
||
856 | if ( not DynamicData.item.scanListScanned[bag][slot] ) then |
||
857 | DynamicData.item.scanListScanned[bag][slot] = GetTime(); |
||
858 | end |
||
859 | if ( bag > -1 ) then |
||
860 | if ( not DynamicData.item.player ) then |
||
861 | DynamicData.item.player = {}; |
||
862 | end |
||
863 | if ( not DynamicData.item.player.itemsByBag ) then |
||
864 | DynamicData.item.player.itemsByBag = {}; |
||
865 | end |
||
866 | if ( not DynamicData.item.player.itemsByBag[bag] ) then |
||
867 | DynamicData.item.player.itemsByBag[bag] = {}; |
||
868 | end |
||
869 | if ( GetContainerNumSlots(bag) < slot ) then |
||
870 | return nil; |
||
871 | end |
||
872 | if ( not DynamicData.item.player.itemsByBag[bag][slot] ) then |
||
873 | DynamicData.item.player.itemsByBag[bag][slot] = DynamicData.item.createBaseItem(); |
||
874 | end |
||
875 | element = DynamicData.item.player.itemsByBag[bag][slot]; |
||
876 | if ( not element.previousElement ) then |
||
877 | element.previousElement = {}; |
||
878 | end |
||
879 | if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_COOLDOWN ) > 0 ) then |
||
880 | local ic_start, ic_duration, ic_enable = GetContainerItemCooldown(bag, slot); |
||
881 | local itemCooldown = DynamicData.item.getOldCooldown(bag, slot); |
||
882 | itemCooldown[1] = ic_start; |
||
883 | itemCooldown[2] = ic_duration; |
||
884 | itemCooldown[3] = ic_enable; |
||
885 | itemCooldown.start = ic_start; |
||
886 | itemCooldown.duration = ic_duration; |
||
887 | itemCooldown.enable = ic_enable; |
||
888 | element.cooldown = itemCooldown; |
||
889 | end |
||
890 | if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_ITEMINFO ) > 0 ) then |
||
891 | local textureName, itemCount, itemLocked, itemQuality, itemReadable = GetContainerItemInfo(bag, slot); |
||
892 | local name = DynamicData.util.getItemNameFromLink(GetContainerItemLink(bag, slot)); |
||
893 | if ( name ) then |
||
894 | element.name = name; |
||
895 | end |
||
896 | element.count = itemCount; |
||
897 | element.texture = textureName; |
||
898 | element.locked = itemLocked; |
||
899 | element.quality = itemQuality; |
||
900 | element.readable = itemReadable; |
||
901 | end |
||
902 | if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_TOOLTIP ) > 0 ) then |
||
903 | if ( scanType == DYNAMICDATA_ITEM_SCAN_TYPE_TOOLTIP ) or ( not element.previousElement ) or ( element.previousElement.name ~= element.name ) or ( element.previousElement.cooldown.start ~= 0 ) or ( element.cooldown.start ~= 0 ) then |
||
904 | strings = DynamicData.util.getItemTooltipInfo(bag, slot); |
||
905 | if ( strings[1] ) and ( strings[1].left ) then |
||
906 | itemName = strings[1].left; |
||
907 | else |
||
908 | itemName = ""; |
||
909 | end |
||
910 | element.name = itemName; |
||
911 | element.strings = strings; |
||
912 | element.itemType = DynamicData.util.getItemStringType(strings); |
||
913 | |||
914 | local itemCurrentDurability, itemMaxDurability = DynamicData.util.getCurrentAndMaxDurability(strings); |
||
915 | element.durability = itemCurrentDurability; |
||
916 | element.maxDurability = itemMaxDurability; |
||
917 | if ( not element.previousElement ) then |
||
918 | element.previousElement = {}; |
||
919 | end |
||
920 | for k, v in element do |
||
921 | if ( type(v) == "table" ) then |
||
922 | if ( not element.previousElement[k] ) then |
||
923 | element.previousElement[k] = {}; |
||
924 | end |
||
925 | for key, value in v do |
||
926 | if ( type(value) == "table" ) then |
||
927 | if ( not element.previousElement[k][key] ) then |
||
928 | element.previousElement[k][key] = {}; |
||
929 | end |
||
930 | for keyKey, valueValue in value do |
||
931 | element.previousElement[k][key][keyKey] = valueValue; |
||
932 | end |
||
933 | else |
||
934 | element.previousElement[k][key] = value; |
||
935 | end |
||
936 | end |
||
937 | else |
||
938 | element.previousElement[k] = v; |
||
939 | end |
||
940 | end |
||
941 | end |
||
942 | end |
||
943 | DynamicData.item.player.itemsByBag[bag][slot] = element; |
||
944 | else |
||
945 | bag = -1; |
||
946 | if ( not DynamicData.item.player ) then |
||
947 | DynamicData.item.player = {}; |
||
948 | end |
||
949 | if ( not DynamicData.item.player.itemsByBag ) then |
||
950 | DynamicData.item.player.itemsByBag = {}; |
||
951 | end |
||
952 | if ( not DynamicData.item.player.itemsByBag[bag] ) then |
||
953 | DynamicData.item.player.itemsByBag[bag] = {}; |
||
954 | end |
||
955 | if ( not DynamicData.item.player.itemsByBag[bag][slot] ) then |
||
956 | DynamicData.item.player.itemsByBag[bag][slot] = DynamicData.item.createBaseItem(); |
||
957 | end |
||
958 | element = DynamicData.item.player.itemsByBag[bag][slot]; |
||
959 | |||
960 | if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_COOLDOWN ) > 0 ) then |
||
961 | local ic_start, ic_duration, ic_enable = GetInventoryItemCooldown("player", slot); |
||
962 | local itemCooldown = DynamicData.item.getOldCooldown(bag, slot); |
||
963 | itemCooldown[1] = ic_start; |
||
964 | itemCooldown[2] = ic_duration; |
||
965 | itemCooldown[3] = ic_enable; |
||
966 | itemCooldown.start = ic_start; |
||
967 | itemCooldown.duration = ic_duration; |
||
968 | itemCooldown.enable = ic_enable; |
||
969 | element.cooldown = itemCooldown; |
||
970 | end |
||
971 | if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_ITEMINFO ) > 0 ) then |
||
972 | local itemCount = GetInventoryItemCount("player", slot); |
||
973 | local textureName = GetInventoryItemTexture("player", slot); |
||
974 | element.count = itemCount; |
||
975 | element.slotTexture = slotTextureName; |
||
976 | element.texture = textureName; |
||
977 | element.locked = IsInventoryItemLocked(slot); |
||
978 | element.broken = GetInventoryItemBroken("player", slot); |
||
979 | --element.quality = GetInventoryItemQuality("player", slot); |
||
980 | end |
||
981 | if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_TOOLTIP ) > 0 ) then |
||
982 | strings = DynamicData.util.getItemTooltipInfo(-1, slot); |
||
983 | element.strings = strings; |
||
984 | if ( strings[1] ) and ( strings[1].left ) then |
||
985 | itemName = strings[1].left; |
||
986 | else |
||
987 | itemName = ""; |
||
988 | end |
||
989 | element.name = itemName; |
||
990 | element.itemType = DynamicData.util.getItemStringType(strings); |
||
991 | |||
992 | local itemCurrentDurability, itemMaxDurability = DynamicData.util.getCurrentAndMaxDurability(strings); |
||
993 | element.durability = itemCurrentDurability; |
||
994 | element.maxDurability = itemMaxDurability; |
||
995 | end |
||
996 | DynamicData.item.player.itemsByBag[bag][slot] = element; |
||
997 | end |
||
998 | return element; |
||
999 | end; |
||
1000 | |||
1001 | getOldCooldown = function(bag, slot) |
||
1002 | if ( DynamicData.item.player.itemsByBag ) |
||
1003 | and ( DynamicData.item.player.itemsByBag[bag] ) |
||
1004 | and ( DynamicData.item.player.itemsByBag[bag][slot] ) |
||
1005 | and ( DynamicData.item.player.itemsByBag[bag][slot].cooldown ) then |
||
1006 | itemCooldown = DynamicData.item.player.itemsByBag[bag][slot].cooldown; |
||
1007 | else |
||
1008 | itemCooldown = { }; |
||
1009 | end |
||
1010 | return itemCooldown; |
||
1011 | end; |
||
1012 | |||
1013 | -- |
||
1014 | -- getInventorySlotScanned(bag, slot) |
||
1015 | -- |
||
1016 | -- retrieves when the slot was last scanned or nil if never |
||
1017 | -- |
||
1018 | getInventorySlotScanned = function (bag, slot) |
||
1019 | if ( not DynamicData.item.scanListScanned ) then |
||
1020 | DynamicData.item.scanListScanned = {}; |
||
1021 | end |
||
1022 | if ( not DynamicData.item.scanListScanned[bag] ) then |
||
1023 | DynamicData.item.scanListScanned[bag] = {}; |
||
1024 | end |
||
1025 | return DynamicData.item.scanListScanned[bag][slot]; |
||
1026 | end; |
||
1027 | |||
1028 | -- |
||
1029 | -- scanInventorySlotIfTime(bag, slot) |
||
1030 | -- |
||
1031 | -- scans the slot if necessary. |
||
1032 | -- |
||
1033 | scanInventorySlotIfTime = function(bag, slot) |
||
1034 | local curTime = GetTime(); |
||
1035 | local lastScanned = DynamicData.item.getInventorySlotScanned(bag, slot); |
||
1036 | if ( not lastScanned ) or ( ( lastScanned + 0.2 ) < GetTime() ) then |
||
1037 | DynamicData.item.scanItem(bag, slot, DYNAMICDATA_ITEM_SCAN_TYPE_QUICK); |
||
1038 | end |
||
1039 | end; |
||
1040 | |||
1041 | }; |
||
1042 |