vanilla-wow-addons – Rev 1
?pathlinks?
--[[
DynamicData
By sarf
This mod allows you to access dynamic data in WoW without being forced to rely on strange Blizzard functions
Thanks goes to the Sea people, the UltimateUI team and finally the nice (but strange) people at
#ultimateuitesters and Blizzard.
UltimateUIUI URL:
http://www.ultimateuiui.org/forums/viewtopic.php?t=NOT_YET_ANNOUNCED
]]
--[[
Information returned by the DynamicData.item.get*Info() methods
An array is returned with the following values
name -- the name of the item
strings -- an array with strings that represent the tooltip of the item
count -- the number of items like this the user currently possesses
texture
cooldown = -- the cooldown of the item
{
start -- time when the cooldown started
duration -- duration of the cooldown
enable -- 1 or 0
};
-- each item may have these values:
durability -- current durability
maxDurability -- maximum durability
itemType -- type of item
locked -- ?
These values are 0 unless the item info derives from a ContainerInfo call (bag >= 0):
quality -- degree of commonness
readable -- ?
These values are 0 or "" unless the item info derives from a InventoryInfo call (bag == -1):
broken -- true if broken, false if not
slotTexture -- background texture of the slot that the item resides in.
]]--
DYNAMICDATA_ITEM_SCAN_TYPE_TOOLTIP = 1;
DYNAMICDATA_ITEM_SCAN_TYPE_ITEMINFO = 2;
DYNAMICDATA_ITEM_SCAN_TYPE_COOLDOWN = 4;
DYNAMICDATA_ITEM_SCAN_TYPE_EVERYTHING = 7;
DYNAMICDATA_ITEM_SCAN_TYPE_QUICK = 6;
-- Item information - what the player is wearing and so on.
DynamicData.item = {
-- public functions
--
-- addOnInventoryUpdateHandler (func)
--
-- Adds a function name that will be called on inventory updates.
-- Function will have two parameters:
-- bag, which may be nil.
-- scanType, which may be DYNAMICDATA_ITEM_SCAN_TYPE_*
--
addOnInventoryUpdateHandler = function (func)
return DynamicData.util.addOnWhateverHandler(DynamicData.item.OnInventoryUpdateHandlers, func);
end;
--
-- removeOnInventoryUpdateHandler (func)
--
-- Removes the specified function, so that it will not be called on inventory updates.
--
removeOnInventoryUpdateHandler = function (func)
return DynamicData.util.removeOnWhateverHandler(DynamicData.item.OnInventoryUpdateHandlers, func);
end;
-- LEGACY FUNCTION - covered in addOnInventoryUpdateHandler
--
-- addOnInventoryCooldownUpdateHandler (func)
--
-- Adds a function name that will be called on InventoryCooldown updates.
-- Function will have one paremeter - bag, which may be nil.
--
addOnInventoryCooldownUpdateHandler = function (func)
return DynamicData.util.addOnWhateverHandler(DynamicData.item.OnInventoryCooldownUpdateHandlers, func);
end;
-- LEGACY FUNCTION - covered in removeOnInventoryUpdateHandler
--
-- removeOnInventoryCooldownUpdateHandler (func)
--
-- Removes the specified function, so that it will not be called on InventoryCooldown updates.
--
removeOnInventoryCooldownUpdateHandler = function (func)
return DynamicData.util.removeOnWhateverHandler(DynamicData.item.OnInventoryCooldownUpdateHandlers, func);
end;
--
-- getEquippedSlotInfo (slot)
--
-- Retrieves information about the slot.
--
getEquippedSlotInfo = function (slot)
if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) and ( DynamicData.item.player.itemsByBag[-1] ) and ( DynamicData.item.player.itemsByBag[-1][slot] ) ) then
return DynamicData.item.player.itemsByBag[-1][slot];
else
return DynamicData.item.defaultItem;
end
end;
--
-- getItemInfoByName (itemName)
--
-- Retrieves information about an item by name.
-- Adds a new variable called position with the position(s) of the item.
--
getItemInfoByName = function (itemName)
if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) ) then
local element = nil;
for bagNumber, bag in DynamicData.item.player.itemsByBag do
for slotNumber, slot in bag do
if ( slot.name == itemName ) then
if ( not element ) then
element = DynamicData.item.createBaseItem(slot);
else
if ( slot.count ) then
element.count = element.count + slot.count;
end
end
if ( not element.position ) then
element.position = {};
end
local positionArray = {};
positionArray.bag = bagNumber;
positionArray.slot = slotNumber;
table.insert(element.position, positionArray);
end
end
end
return element;
else
return DynamicData.item.defaultItem;
end
end;
--
-- getItemInfoByType (itemType)
--
-- Retrieves information about items with the specific type. Includes a new cute variable called totalCount.
--
getItemInfoByType = function (itemName)
local bagNumber, bag;
local slotNumber, itemInfo;
local items = {};
for bagNumber, bag in DynamicData.item.player.itemsByBag do
for slotNumber, itemInfo in bag do
if ( itemInfo.itemType == itemType ) then
table.insert(items, DynamicData.item.getItemInfoByName(itemInfo.name));
end
end
end
return items;
end;
--
-- getEquippedSlotCooldown (slot)
--
-- Retrieves cooldown information about the slot.
--
getEquippedSlotCooldown = function (slot)
if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) and ( DynamicData.item.player.itemsByBag[-1] ) and ( DynamicData.item.player.itemsByBag[-1][slot] ) ) then
local cooldown = DynamicData.item.player.itemsByBag[-1][slot].cooldown;
return cooldown[1], cooldown[2], cooldown[3];
else
return 0, 0, 0;
end
end;
--
-- getInventoryInfo (bag, slot)
--
-- Retrieves information about the bag and slot.
--
getInventoryInfo = function (bag, slot)
DynamicData.item.scanInventorySlotIfTime(bag, slot);
local element = DynamicData.item.player.itemsByBag[bag][slot];
if ( not element ) then
element = DynamicData.item.defaultItem;
end
return element;
end;
--
-- getInventoryName (bag, slot)
--
-- Retrieves the name of the item in the bag and slot.
--
getInventoryName = function (bag, slot)
if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) and ( DynamicData.item.player.itemsByBag[bag] ) and ( DynamicData.item.player.itemsByBag[bag][slot] ) ) then
local itemInfo = DynamicData.item.getInventoryInfo(bag, slot);
if ( ( not itemInfo ) or ( ( itemInfo.texture ) and ( strlen(itemInfo.texture) > 0 ) and ( ( not itemInfo.name ) or ( strlen(itemInfo.name) <= 0 ) ) ) ) then
DynamicData.item.scanItem(bag, slot);
itemInfo = DynamicData.item.player.itemsByBag[bag][slot];
end
return itemInfo.name;
else
return DynamicData.item.defaultItem.name;
end
end;
--
-- getInventoryCooldownInfo (bag, slot)
--
-- Retrieves cooldown information about the bag and slot.
--
getInventoryCooldown = function (bag, slot)
if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) and ( DynamicData.item.player.itemsByBag[bag] ) and ( DynamicData.item.player.itemsByBag[bag][slot] ) ) then
local cooldown = DynamicData.item.player.itemsByBag[bag][slot].cooldown;
return cooldown[1], cooldown[2], cooldown[3];
else
return 0, 0, 0;
end
end;
--
-- getEquippedSlotInfoBySlotName (slotName)
--
-- Retrieves information about the slot with the specified name.
--
getEquippedSlotInfoBySlotName = function (slotName)
for key, value in DynamicData.item.inventorySlotNames do
if ( value.name == slotName ) then
return DynamicData.item.getEquippedSlotInfo(value.id);
end
end
return DynamicData.item.defaultItem;
end;
--
-- updateItems ()
--
-- Updates the inventory of the player.
--
updateItems = function (bag)
params = {
func = DynamicData.item.doUpdateItems,
params = { bag },
allowInitialUpdate = 1,
schedulingName = "DynamicData_item_UpdateItems",
};
--DynamicData.util.postpone(params);
DynamicData.item.doUpdateItems(bag);
end;
--
-- updateItemCooldowns ()
--
-- Updates the cooldowns of the players items.
--
updateItemCooldowns = function ()
local safe = true; --DynamicData.util.safeToUseTooltips({"MerchantFrame", "TradeSkillFrame", "AuctionFrame"});
if ( not safe ) then
UltimateUI_ScheduleByName("DynamicData_item_updateItemCooldownsUnspecified", 0.1, DynamicData.item.updateItemCooldowns);
return;
end
DynamicData.item.doQuickScan();
--[[
local bag;
for bag = 0,4 do
DynamicData.item.doUpdateBagItemsCooldown(bag);
end
DynamicData.item.doUpdateBagItemsCooldown(-1);
bag = nil;
DynamicData.item.notifyUpdateHandlers(nil, DYNAMICDATA_ITEM_SCAN_TYPE_COOLDOWN);
DynamicData.item.notifyItemCooldownUpdateHandlers();
]]--
end;
--
-- updateItemLocks ()
--
-- Updates the locks of the players items.
--
updateItemLocks = function ()
DynamicData.item.updateItems();
end;
--
-- updateItemAlerts ()
--
-- Updates the alerts of the players items.
-- You can never have too many lerts.
--
updateItemAlerts = function ()
DynamicData.item.updateItems();
end;
-- protected functions
--
-- doUpdateSeperateBagItems (bag)
--
-- Updates a bag seperately from the rest of the inventory of the player.
-- Saves some time.
--
doUpdateSeperateBagItems = function (bag)
if ( not bag ) then
return;
end
if ( DynamicData.item.player.itemsByBag ) then
table.remove(DynamicData.item.player.itemsByBag, bag);
end
DynamicData.item.doUpdateBagItems(bag);
end;
--
-- doUpdateBagItems (bag)
--
-- Updates a bag of the inventory of the player.
--
doUpdateBagItems = function (bag)
DynamicData.item.scanItemsInBag(bag);
end;
--
-- doUpdateItems ()
--
-- Initiates updates of the inventory of the player.
--
doUpdateItems = function (bag)
local safe = true; --DynamicData.util.safeToUseTooltips({"MerchantFrame", "TradeSkillFrame", "AuctionFrame"});
if ( not safe ) then
if ( bag ) then
UltimateUI_ScheduleByName("DynamicData_item_doUpdateItems", 0.1, DynamicData.item.doUpdateItems, bag);
else
UltimateUI_ScheduleByName("DynamicData_item_doUpdateItemsUnspecified", 0.1, DynamicData.item.doUpdateItems);
end
return;
end
DynamicData.item.doQuickScan();
if ( ( bag ) and ( DynamicData.item.player ) ) then
--DynamicData.item.doQuickScan(bag);
--local scanLists = DynamicData.item.generateScanLists(nil, bag);
--DynamicData.item.addScans(scanLists);
DynamicData.item.makeScanLists(bag);
if ( not DynamicData.item.itemScanInProgress ) then
--DynamicData.item.doScans(nil, nil, bag);
DynamicData.item.doScans(nil, nil, bag);
--UltimateUI_ScheduleByName("DynamicData_Item_doScans", 0.1, DynamicData.item.doScans);
end
--DynamicData.item.doUpdateSeperateBagItems(bag);
--DynamicData.item.notifyUpdateHandlers(bag);
--DynamicData.item.notifyItemCooldownUpdateHandlers();
else
--DynamicData.item.player = {};
--local scanLists = DynamicData.item.generateScanLists();
--DynamicData.item.addScans(scanLists);
DynamicData.item.makeScanLists();
--DynamicData.item.doQuickScan();
if ( not DynamicData.item.itemScanInProgress ) then
DynamicData.item.doScans(nil);
--UltimateUI_ScheduleByName("DynamicData_Item_doScans", 0.1, DynamicData.item.doScans);
end
end
end;
--
-- addScans(scanLists)
--
-- Adds scan lists to the global scanlist thingy.
--
addScans = function (scanLists)
for k, v in scanLists do
for bag, slot in v do
if ( not DynamicData.item.scanList ) then
DynamicData.item.scanList = {};
end
if ( not DynamicData.item.scanList[bag] ) then
DynamicData.item.scanList[bag] = {};
end
if ( not DynamicData.item.scanList[bag][slot] ) then
DynamicData.item.scanList[bag][slot] = 0;
end
DynamicData.item.scanList[bag][slot] = 1;
end
--table.insert(DynamicData.item.scanList, v);
end
end;
--
-- doScans (scanLists, currentIndex)
--
-- scans the currently indicated list and schedules next scan list.
-- when completed, generates update notification.
--
doScans = function (scanLists, currentIndex, bag)
scanLists = nil;
--[[
if ( not scanLists ) then
scanLists = DynamicData.item.scanList;
end
]]--
local scheduleName = "DynamicData_Item_doScans";
if ( bag ) then
--scheduleName = scheduleName.."_"..bag;
end
DynamicData.item.itemScanInProgress = true;
if ( not currentIndex ) then
-- if first time, then we schedule a new scan - this is to prevent the stuttering effect when receiving loads of updates in short succession.
--[[
if ( scanLists == DynamicData.item.scanList ) then
scanLists = nil;
end
]]--
UltimateUI_ScheduleByName(scheduleName, 0.1, DynamicData.item.doScans, scanLists, 1, bag);
return;
else
-- prevents old scans from continuing.
UltimateUI_ScheduleByName(scheduleName, 0.1, DynamicData.item.doScans);
end
local scanType = DYNAMICDATA_ITEM_SCAN_TYPE_TOOLTIP;
if ( DynamicData.item.scanItems(scanType) ) then
if ( scanLists == DynamicData.item.scanList ) then
scanLists = nil;
end
UltimateUI_ScheduleByName(scheduleName, 0.1, DynamicData.item.doScans, scanLists, currentIndex, bag);
return;
else
if ( scanLists == DynamicData.item.scanList ) then
--DynamicData.item.scanList = {};
end
DynamicData.item.itemScanInProgress = false;
DynamicData.item.notifyUpdateHandlers(bag, scanType);
--DynamicData.item.notifyItemCooldownUpdateHandlers();
end
end;
--
-- doUpdateBagItemsCooldown (bag)
--
-- Updates the cooldown a bag of the inventory of the player.
--
doUpdateBagItemsCooldown = function (bag)
if ( ( DynamicData.item.player ) and ( DynamicData.item.player.itemsByBag ) and ( DynamicData.item.player.itemsByBag[bag] ) ) then
if ( bag > -1 ) then
local element = nil;
for slot = 1,GetContainerNumSlots(bag) do
if ( DynamicData.item.player.itemsByBag[bag][slot] ) then
local ic_start, ic_duration, ic_enable = GetContainerItemCooldown(bag, slot);
local itemCooldown = DynamicData.item.getOldCooldown(bag, slot);
itemCooldown[1] = ic_start;
itemCooldown[2] = ic_duration;
itemCooldown[3] = ic_enable;
itemCooldown.start = ic_start;
itemCooldown.duration = ic_duration;
itemCooldown.enable = ic_enable;
DynamicData.item.player.itemsByBag[bag][slot].cooldown = itemCooldown;
end
end
else
for k, v in DynamicData.item.inventorySlotNames do
slot = v.id;
if ( DynamicData.item.player.itemsByBag[bag][slot] ) then
local ic_start, ic_duration, ic_enable = GetInventoryItemCooldown("player", slot);
local itemCooldown = DynamicData.item.getOldCooldown(bag, slot);
itemCooldown[1] = ic_start;
itemCooldown[2] = ic_duration;
itemCooldown[3] = ic_enable;
itemCooldown.start = ic_start;
itemCooldown.duration = ic_duration;
itemCooldown.enable = ic_enable;
DynamicData.item.player.itemsByBag[bag][slot].cooldown = itemCooldown;
end
end
end
end
end;
-- private functions
--
-- notifyUpdateHandlers (bag)
--
-- Args:
-- bag - if not nil, the bag that has been updated
-- scanType - the type of scan that has completed
--
-- Notifies all update handlers that an update has occurred.
--
notifyUpdateHandlers = function (bag, scanType)
DynamicData.util.notifyWhateverHandlers(DynamicData.item.OnInventoryUpdateHandlers, bag, scanType);
end;
-- LEGACY FUNCTION
--
-- notifyItemCooldownUpdateHandlers ()
--
-- Notifies all item cooldown update handlers that an item cooldown has occurred.
--
notifyItemCooldownUpdateHandlers = function ()
DynamicData.util.notifyWhateverHandlers(DynamicData.item.OnInventoryCooldownUpdateHandlers);
end;
--
-- OnLoad ()
--
-- Sets up the DynamicData.item for operation.
-- In this case, it retrieves the IDs for the inventory slots.
--
OnLoad = function ()
for key, value in DynamicData.item.inventorySlotNames do
DynamicData.item.inventorySlotNames[key].id = GetInventorySlotInfo(value.name);
end
DynamicData.item.doUpdateItems();
UltimateUI_AfterInit(DynamicData.item.doUpdateItems);
UltimateUI_AfterInit(UltimateUI_Schedule, 30, DynamicData.item.doUpdateItems);
UltimateUI_AfterInit(UltimateUI_Schedule, 60, DynamicData.item.doUpdateItems);
UltimateUI_AfterInit(UltimateUI_Schedule, 90, DynamicData.item.doUpdateItems);
end;
-- variables
-- Taken from ItemBuff - thanks, Telo!
-- Used for mapping inventory (equipment) ids and slot names
inventorySlotNames = {
{ name = "HeadSlot" },
{ name = "NeckSlot" },
{ name = "ShoulderSlot" },
{ name = "BackSlot" },
{ name = "ChestSlot" },
{ name = "ShirtSlot" },
{ name = "TabardSlot" },
{ name = "WristSlot" },
{ name = "HandsSlot" },
{ name = "WaistSlot" },
{ name = "LegsSlot" },
{ name = "FeetSlot" },
{ name = "Finger0Slot" },
{ name = "Finger1Slot" },
{ name = "Trinket0Slot" },
{ name = "Trinket1Slot" },
{ name = "MainHandSlot" },
{ name = "SecondaryHandSlot" },
{ name = "RangedSlot" },
};
-- Contains lists of items that should be scanned.
scanList = {};
-- Contains lists of when item slots were scanned.
scanListScanned = {};
-- Whether a scan is in progress or not.
itemScanInProgress = false;
-- Contains item data about the player's items.
player = {};
-- Contains the function pointers to functions that want to be called whenever the inventory updates.
-- Will be called AFTER the DynamicData has parsed the inventory.
OnInventoryUpdateHandlers = {};
-- Contains the function pointers to functions that want to be called whenever the inventory cooldown updates.
-- Will be called AFTER the DynamicData has parsed the inventory.
OnInventoryCooldownUpdateHandlers = {};
defaultItem = {
name = "",
strings = {
[1] = {},
[2] = {},
[3] = {},
[4] = {},
[5] = {},
[6] = {},
[7] = {},
[8] = {},
[9] = {},
[10] = {},
[11] = {},
[12] = {},
[13] = {},
[14] = {},
[15] = {}
},
count = 0,
slotCount = 0,
texture = "",
cooldown = {
[1] = 0,
[2] = 0,
[3] = 0,
start = 0,
duration = 0,
enable = 0
},
itemType = "",
locked = 0,
durability = nil,
maxDurability = nil,
quality = 0,
readable = 0,
broken = 0,
slotTexture = ""
};
--
-- createBaseItem ()
--
-- creates a basic item with all attributes set to defaults.
--
createBaseItem = function (baseItem)
local newItem = {};
for k, v in DynamicData.item.defaultItem do
newItem[k] = v;
end
if ( baseItem ) then
for k, v in baseItem do
newItem[k] = v;
end
end
return newItem;
end;
--
-- makeScanList (numberOfScansPerList, bag)
--
-- Makes a list of scans.
--
makeScanLists = function (bag)
if ( not DynamicData.item.scanList ) then
DynamicData.item.scanList = {};
end
if ( not bag ) then
for bag = 0, 4, 1 do
for slot = 1, GetContainerNumSlots(bag), 1 do
if ( not DynamicData.item.scanList[bag] ) then
DynamicData.item.scanList[bag] = {};
end
DynamicData.item.scanList[bag][slot] = 1;
end
end
bag = -1;
for slot = 1, 19, 1 do
if ( not DynamicData.item.scanList[bag] ) then
DynamicData.item.scanList[bag] = {};
end
DynamicData.item.scanList[bag][slot] = 1;
end
elseif ( bag <= -1 ) then
bag = -1;
if ( not DynamicData.item.scanList[bag] ) then
DynamicData.item.scanList[bag] = {};
end
for slot = 1, 19, 1 do
DynamicData.item.scanList[bag][slot] = 1;
end
else
if ( not DynamicData.item.scanList[bag] ) then
DynamicData.item.scanList[bag] = {};
end
for slot = 1, GetContainerNumSlots(bag), 1 do
DynamicData.item.scanList[bag][slot] = 1;
end
end
end;
--
-- generateScanLists (numberOfScansPerList, bag)
--
-- Generates a list of scans.
--
generateScanLists = function (numberOfScansPerList, bag)
if ( not numberOfScansPerList ) then
numberOfScansPerList = DYNAMICDATA_DEFAULT_NUMBER_OF_TOOLTIP_SCANS_PER_UPDATE;
end
local lists = {};
local numberOfCurrentScans = 0;
local currentList = {};
local slot;
if ( not bag ) then
for bag = 0, 4, 1 do
for slot = 1, GetContainerNumSlots(bag), 1 do
if ( not currentList[bag] ) then
currentList[bag] = {};
end
table.insert(currentList[bag], slot);
numberOfCurrentScans = numberOfCurrentScans + 1;
if ( numberOfCurrentScans >= numberOfScansPerList) then
table.insert(lists, currentList);
currentList = {};
numberOfCurrentScans = 0;
end
end
end
bag = -1;
for slot = 1, 19, 1 do
if ( not currentList[bag] ) then
currentList[bag] = {};
end
table.insert(currentList[bag], slot);
numberOfCurrentScans = numberOfCurrentScans + 1;
if ( numberOfCurrentScans >= numberOfScansPerList) then
table.insert(lists, currentList);
currentList = {};
numberOfCurrentScans = 0;
end
end
elseif ( bag <= -1 ) then
bag = -1;
for slot = 1, 19, 1 do
if ( not currentList[bag] ) then
currentList[bag] = {};
end
table.insert(currentList[bag], slot);
numberOfCurrentScans = numberOfCurrentScans + 1;
if ( numberOfCurrentScans >= numberOfScansPerList) then
table.insert(lists, currentList);
currentList = {};
numberOfCurrentScans = 0;
end
end
else
for slot = 1, GetContainerNumSlots(bag), 1 do
if ( not currentList[bag] ) then
currentList[bag] = {};
end
table.insert(currentList[bag], slot);
numberOfCurrentScans = numberOfCurrentScans + 1;
if ( numberOfCurrentScans >= numberOfScansPerList) then
table.insert(lists, currentList);
currentList = {};
numberOfCurrentScans = 0;
end
end
end
if ( numberOfCurrentScans > 0) then
table.insert(lists, currentList);
end
return lists;
end;
--
-- doQuickScan (bag)
--
-- does a quick scan of the bag (or of the whole inventory if bag is not specified).
--
doQuickScan = function(bag)
if ( bag ) then
DynamicData.item.scanItemsInBag(bag, DYNAMICDATA_ITEM_SCAN_TYPE_QUICK);
else
for i = 0, 4, 1 do
DynamicData.item.scanItemsInBag(i, DYNAMICDATA_ITEM_SCAN_TYPE_QUICK);
end
DynamicData.item.scanItemsInBag(-1, DYNAMICDATA_ITEM_SCAN_TYPE_QUICK);
end
DynamicData.item.notifyUpdateHandlers(bag, DYNAMICDATA_ITEM_SCAN_TYPE_QUICK);
DynamicData.item.notifyItemCooldownUpdateHandlers();
end;
--
-- scanItemsInBag (bag, scanType)
--
-- scans all items in bag and puts the info into the database
-- can be retailored to only scan the tooltip, everything but the tooltip and everything.
--
scanItemsInBag = function(bag, scanType)
local bag, slot, v;
if ( not bag ) then
return;
end
if ( bag <= -1 ) then
for slot = 1, 19, 1 do
DynamicData.item.scanItem(-1, slot, scanType);
end
else
for slot = 1, GetContainerNumSlots(bag), 1 do
DynamicData.item.scanItem(bag, slot, scanType);
end
end
end;
--
-- scanItems (list, scanType)
--
-- scans a list of item slots item and puts the info into the database
-- can be retailored to only scan the tooltip, everything but the tooltip and everything.
-- list format : list[bag] = { slot1, slot2, slot3 ... };
--
scanItems = function(scanType)
local curTime = GetTime();
local numberScanned = 0;
local scanned = false;
for bag, bagValue in DynamicData.item.scanList do
for slot, value in bagValue do
if ( value == 1 ) then
DynamicData.item.scanItem(bag, slot, scanType);
DynamicData.item.scanList[bag][slot] = 0;
if ( not DynamicData.item.scanListScanned ) then
DynamicData.item.scanListScanned = {};
end
if ( not DynamicData.item.scanListScanned[bag] ) then
DynamicData.item.scanListScanned[bag] = {};
end
DynamicData.item.scanListScanned[bag][slot] = curTime;
numberScanned = numberScanned + 1;
scanned = true;
if ( numberScanned >= DYNAMICDATA_DEFAULT_NUMBER_OF_TOOLTIP_SCANS_PER_UPDATE ) then
return scanned;
end
end
end
end
return scanned;
--[[
for bag, v in list do
for key, slot in v do
DynamicData.item.scanItem(bag, slot, scanType);
end
end
]]--
end;
--
-- scanItem (bag, slot)
--
-- scans an item and puts the info into the item database
--
scanItem = function(bag, slot, scanType)
if ( not scanType ) then
scanType = DYNAMICDATA_ITEM_SCAN_TYPE_EVERYTHING;
end
local strings = nil;
local itemName = nil;
local element = nil;
if ( not DynamicData.item.scanListScanned ) then
DynamicData.item.scanListScanned = {};
end
if ( not DynamicData.item.scanListScanned[bag] ) then
DynamicData.item.scanListScanned[bag] = {};
end
if ( not DynamicData.item.scanListScanned[bag][slot] ) then
DynamicData.item.scanListScanned[bag][slot] = GetTime();
end
if ( bag > -1 ) then
if ( not DynamicData.item.player ) then
DynamicData.item.player = {};
end
if ( not DynamicData.item.player.itemsByBag ) then
DynamicData.item.player.itemsByBag = {};
end
if ( not DynamicData.item.player.itemsByBag[bag] ) then
DynamicData.item.player.itemsByBag[bag] = {};
end
if ( GetContainerNumSlots(bag) < slot ) then
return nil;
end
if ( not DynamicData.item.player.itemsByBag[bag][slot] ) then
DynamicData.item.player.itemsByBag[bag][slot] = DynamicData.item.createBaseItem();
end
element = DynamicData.item.player.itemsByBag[bag][slot];
if ( not element.previousElement ) then
element.previousElement = {};
end
if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_COOLDOWN ) > 0 ) then
local ic_start, ic_duration, ic_enable = GetContainerItemCooldown(bag, slot);
local itemCooldown = DynamicData.item.getOldCooldown(bag, slot);
itemCooldown[1] = ic_start;
itemCooldown[2] = ic_duration;
itemCooldown[3] = ic_enable;
itemCooldown.start = ic_start;
itemCooldown.duration = ic_duration;
itemCooldown.enable = ic_enable;
element.cooldown = itemCooldown;
end
if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_ITEMINFO ) > 0 ) then
local textureName, itemCount, itemLocked, itemQuality, itemReadable = GetContainerItemInfo(bag, slot);
local name = DynamicData.util.getItemNameFromLink(GetContainerItemLink(bag, slot));
if ( name ) then
element.name = name;
end
element.count = itemCount;
element.texture = textureName;
element.locked = itemLocked;
element.quality = itemQuality;
element.readable = itemReadable;
end
if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_TOOLTIP ) > 0 ) then
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
strings = DynamicData.util.getItemTooltipInfo(bag, slot);
if ( strings[1] ) and ( strings[1].left ) then
itemName = strings[1].left;
else
itemName = "";
end
element.name = itemName;
element.strings = strings;
element.itemType = DynamicData.util.getItemStringType(strings);
local itemCurrentDurability, itemMaxDurability = DynamicData.util.getCurrentAndMaxDurability(strings);
element.durability = itemCurrentDurability;
element.maxDurability = itemMaxDurability;
if ( not element.previousElement ) then
element.previousElement = {};
end
for k, v in element do
if ( type(v) == "table" ) then
if ( not element.previousElement[k] ) then
element.previousElement[k] = {};
end
for key, value in v do
if ( type(value) == "table" ) then
if ( not element.previousElement[k][key] ) then
element.previousElement[k][key] = {};
end
for keyKey, valueValue in value do
element.previousElement[k][key][keyKey] = valueValue;
end
else
element.previousElement[k][key] = value;
end
end
else
element.previousElement[k] = v;
end
end
end
end
DynamicData.item.player.itemsByBag[bag][slot] = element;
else
bag = -1;
if ( not DynamicData.item.player ) then
DynamicData.item.player = {};
end
if ( not DynamicData.item.player.itemsByBag ) then
DynamicData.item.player.itemsByBag = {};
end
if ( not DynamicData.item.player.itemsByBag[bag] ) then
DynamicData.item.player.itemsByBag[bag] = {};
end
if ( not DynamicData.item.player.itemsByBag[bag][slot] ) then
DynamicData.item.player.itemsByBag[bag][slot] = DynamicData.item.createBaseItem();
end
element = DynamicData.item.player.itemsByBag[bag][slot];
if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_COOLDOWN ) > 0 ) then
local ic_start, ic_duration, ic_enable = GetInventoryItemCooldown("player", slot);
local itemCooldown = DynamicData.item.getOldCooldown(bag, slot);
itemCooldown[1] = ic_start;
itemCooldown[2] = ic_duration;
itemCooldown[3] = ic_enable;
itemCooldown.start = ic_start;
itemCooldown.duration = ic_duration;
itemCooldown.enable = ic_enable;
element.cooldown = itemCooldown;
end
if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_ITEMINFO ) > 0 ) then
local itemCount = GetInventoryItemCount("player", slot);
local textureName = GetInventoryItemTexture("player", slot);
element.count = itemCount;
element.slotTexture = slotTextureName;
element.texture = textureName;
element.locked = IsInventoryItemLocked(slot);
element.broken = GetInventoryItemBroken("player", slot);
--element.quality = GetInventoryItemQuality("player", slot);
end
if ( ( scanType and DYNAMICDATA_ITEM_SCAN_TYPE_TOOLTIP ) > 0 ) then
strings = DynamicData.util.getItemTooltipInfo(-1, slot);
element.strings = strings;
if ( strings[1] ) and ( strings[1].left ) then
itemName = strings[1].left;
else
itemName = "";
end
element.name = itemName;
element.itemType = DynamicData.util.getItemStringType(strings);
local itemCurrentDurability, itemMaxDurability = DynamicData.util.getCurrentAndMaxDurability(strings);
element.durability = itemCurrentDurability;
element.maxDurability = itemMaxDurability;
end
DynamicData.item.player.itemsByBag[bag][slot] = element;
end
return element;
end;
getOldCooldown = function(bag, slot)
if ( DynamicData.item.player.itemsByBag )
and ( DynamicData.item.player.itemsByBag[bag] )
and ( DynamicData.item.player.itemsByBag[bag][slot] )
and ( DynamicData.item.player.itemsByBag[bag][slot].cooldown ) then
itemCooldown = DynamicData.item.player.itemsByBag[bag][slot].cooldown;
else
itemCooldown = { };
end
return itemCooldown;
end;
--
-- getInventorySlotScanned(bag, slot)
--
-- retrieves when the slot was last scanned or nil if never
--
getInventorySlotScanned = function (bag, slot)
if ( not DynamicData.item.scanListScanned ) then
DynamicData.item.scanListScanned = {};
end
if ( not DynamicData.item.scanListScanned[bag] ) then
DynamicData.item.scanListScanned[bag] = {};
end
return DynamicData.item.scanListScanned[bag][slot];
end;
--
-- scanInventorySlotIfTime(bag, slot)
--
-- scans the slot if necessary.
--
scanInventorySlotIfTime = function(bag, slot)
local curTime = GetTime();
local lastScanned = DynamicData.item.getInventorySlotScanned(bag, slot);
if ( not lastScanned ) or ( ( lastScanned + 0.2 ) < GetTime() ) then
DynamicData.item.scanItem(bag, slot, DYNAMICDATA_ITEM_SCAN_TYPE_QUICK);
end
end;
};