Thread Tools Display Modes
08-13-15, 07:51 AM   #1
Endzeit
A Deviate Faerie Dragon
Join Date: Aug 2015
Posts: 12
Problems with Big Tables

Edit#2:
It works now.. but i got stutter when hover over items.. is there a way with a ~1800 table to improve performance?
-----
EDIT:
i found the problem.. this is working:
Code:
local setName =  {
[1] = {  name = "Mystic's Regalia (Recolor)", items = {14090, 26008, 14094}, },
-- [2......1778]
[1779] = {  name = "Imperial Plate", items = {31436, 30002, 12424, 12425, 12422, 12427, 12429}, },
}
function addline_gametip()
local itemName,itemLink = GameTooltip:GetItem()
	if itemLink ~= nil then	   
		local itemString = string.match(itemLink, "item[%-?%d:]+");
		local _, itemId, enchantId, jewelId1, jewelId2, jewelId3, jewelId4, suffixId, uniqueId, linkLevel, reforgeId = strsplit(":", itemString);

 for i = 1, #setName do
j = 1 
while j <= 8 do

if (setName[i]['items'][j] ~= nil) and (format("%u",itemId) == format("%u", setName[i]['items'][j])) then
 		GameTooltip:AddLine("Transmog Set: " .. setName[i]['name'])
 		GameTooltip:Show();
 		end
j = j + 1
		end
 end
 end
 end

 

GameTooltip:HookScript("OnTooltipSetItem", addline_gametip);
-------

I'm working on my first wow addon and i'm a big newbie with lua and coding. I think im finished, but it dont work.

problems are the do while i think. here is my code:

Code:
local setName =  {
[1] = {  name = "Mystic's Regalia (Recolor)", items = {14090, 26008, 14094}, },
-- [2......1778]
[1779] = {  name = "Imperial Plate", items = {31436, 30002, 12424, 12425, 12422, 12427, 12429}, },
}

function addline_gametip()
local itemName,itemLink = GameTooltip:GetItem()
	if itemLink ~= nil then	   
		local itemString = string.match(itemLink, "item[%-?%d:]+");
		local _, itemId, enchantId, jewelId1, jewelId2, jewelId3, jewelId4, suffixId, uniqueId, linkLevel, reforgeId = strsplit(":", itemString);

 for i = 1, #setName do
j = 1 
while j <= 8 do
 if (itemId == setName[i]['items'][j]) then
 		GameTooltip:AddLine("Transmog Set: " .. setName[i]['name'])
 		GameTooltip:Show();
 		end
j = j + 1
		end
 end
 end
 end


GameTooltip:HookScript("OnTooltipSetItem", addline_gametip);
hope someone can help me

Last edited by Endzeit : 08-13-15 at 10:32 AM.
  Reply With Quote
08-13-15, 04:26 PM   #2
Mazzop
A Cliff Giant
AddOn Author - Click to view addons
Join Date: Dec 2011
Posts: 74
cannot help on technical side and i am not sure if i get, what you trying to do
but what if you do table other way around and index by itemID with aray of sets name that item is in
adding tooltip then would be trivial
  Reply With Quote
08-13-15, 05:08 PM   #3
elcius
A Cliff Giant
AddOn Author - Click to view addons
Join Date: Sep 2011
Posts: 75
lua has no problem with very large tables, just make an itemid to setid lookup table.
Lua Code:
  1. local setName =  {
  2. [1] = {  name = "Mystic's Regalia (Recolor)", items = {14090, 26008, 14094}, },
  3. -- [2......1778]
  4. [1779] = {  name = "Imperial Plate", items = {31436, 30002, 12424, 12425, 12422, 12427, 12429}, },
  5. }
  6.  
  7. -- make lookup table, ideally this would be pre-made
  8. local itemSet = {};
  9. for i,set in pairs(setName) do
  10.     for j, id in pairs(set['items']) do
  11.         itemSet[id] = i;
  12.     end
  13. end
  14.  
  15. function addline_gametip()
  16.     local itemName,itemLink = GameTooltip:GetItem();
  17.     if not itemLink then return end
  18.    
  19.     local itemId = itemLink:match('item:(%d+)');
  20.     local setIndex = itemSet[tonumber(itemId)];
  21.    
  22.     if setIndex and setName[setIndex] then
  23.         GameTooltip:AddLine("Transmog Set: " .. setName[setIndex]['name']);
  24.     end
  25.  end
  26.  
  27.  
  28. GameTooltip:HookScript("OnTooltipSetItem", addline_gametip);
  Reply With Quote
08-14-15, 07:19 AM   #4
Endzeit
A Deviate Faerie Dragon
Join Date: Aug 2015
Posts: 12
wow this works great. thanks

Next Step i want to add Message, when one of this Items received Loot.

Lua Code:
  1. function AddLootMsg(self, event, message, ...)
  2.     local itemName,itemLink = GetItemInfo(itemID);
  3.     if not itemLink then return end
  4.     local itemId = itemLink:match('item:(%d+)');
  5.     local setIndex = itemSet[tonumber(itemId)];
  6.  
  7.         if setIndex and setName[setIndex] then
  8.         DEFAULT_CHAT_FRAME:AddMessage("Hello, World!");
  9.     end
  10. end
  11.  
  12. ChatFrame_AddMessageEventFilter("CHAT_MSG_LOOT", AddLootMsg);

this is not working..
whats the different between GetItemInfo(itemID); and GameTooltip:GetItem(); ?
Can i use the same lookup table or i need a new one?
Can i use the same locals agains?
  Reply With Quote
08-14-15, 07:45 AM   #5
suicidalkatt
A Rage Talon Dragon Guard
 
suicidalkatt's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2008
Posts: 331
Originally Posted by elcius View Post
lua has no problem with very large tables, just make an itemid to setid lookup table.

~ Snip
While your method would be ideal, it doesn't really do what the author intended.

I believe they want to have the tooltip show every set that contains a particular itemID not just the first one that returns true.

Lua Code:
  1. local setName =  {
  2. [1] = {  name = "Mystic's Regalia (Recolor)", items = {14090, 26008, 14094}, },
  3. -- [2......1778]
  4. [1779] = {  name = "Imperial Plate", items = {31436, 30002, 12424, 12425, 12422, 12427, 12429}, },
  5. }
  6.  
  7. -- make lookup table, this will create a list that looks something like this
  8. --[[
  9. local table = {
  10.     [14090] = {201,560,888} -- Item id = Table of setName[index] values
  11. }
  12. ]]
  13. local itemSet = {}
  14. do
  15.     for i,set in pairs(setName) do -- Looks through all the set
  16.         for j, id in pairs(set['items']) do -- looks though just the items table within
  17.             if not itemSet[id] then itemSet[id] = {} end -- creates a table within itemSet for each id (only once)
  18.             tinsert(itemSet[id], i) -- inserts each set index into the table
  19.         end
  20.     end
  21. end
  22.  
  23. function addline_gametip()
  24.     local itemName,itemLink = GameTooltip:GetItem();
  25.     if not itemLink then return end
  26.    
  27.     local itemId = tonumber(itemLink:match('item:(%d+)'));
  28.     if itemSet[itemId] then -- if a set is found
  29.         for i, setIndex in pairs(itemSet[itemId]) do -- for each index the id has
  30.             GameTooltip:AddLine("Transmog Set: " .. setName[setIndex]['name']); -- add a line to the game tooltip
  31.         end
  32.     end
  33.  end
  34.  
  35.  
  36. GameTooltip:HookScript("OnTooltipSetItem", addline_gametip);

Last edited by suicidalkatt : 08-14-15 at 07:50 AM. Reason: spellcheck
  Reply With Quote
08-14-15, 07:55 PM   #6
Endzeit
A Deviate Faerie Dragon
Join Date: Aug 2015
Posts: 12
thanks suicidalkatt & elcius.

While your method would be ideal, it doesn't really do what the author intended.

I believe they want to have the tooltip show every set that contains a particular itemID not just the first one that returns true.
1 set = 1 itemid. Both variants are correct for me. ItemId 123456 can not be in 2 Sets in my table.


Lua Code:
  1. function AddLootMsg(self, event, message, ...)
  2.      if not string.match(message,'Hbattlepet') then
  3.     local lootid = select(3, string.find(message, "item:(%d+):"))
  4.    
  5.     local itemName,itemLink = GetItemInfo(lootid);
  6.     if not itemLink then return end
  7.    
  8.    
  9.     local itemId = tonumber(itemLink:match('item:(%d+)'));
  10.    
  11.     if itemSet[itemId] then -- if a set is found
  12.         for i, setIndex in pairs(itemSet[itemId]) do -- for each index the id has
  13.         message = message:gsub("\124r.", "\124r (|cff9400D3Transmog Set: " .. setName[setIndex]['name'] .. "|cff00aa00).")
  14.         return false, message, ...
  15.  
  16.     end
  17. end
  18. end
  19. end
  20.  
  21. ChatFrame_AddMessageEventFilter("CHAT_MSG_LOOT", AddLootMsg);

thats my code for chat_msg_loot so far.. in my first tests it works.. have someone also an improvement for this code?

Last edited by Endzeit : 08-14-15 at 08:00 PM.
  Reply With Quote
08-15-15, 12:45 AM   #7
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,326
Since all the code is doing is matching items to set names, the lookup table doesn't need to be so complicated to use. Here's my example. There can be more optimizations depending on how you want the tooltip to look.

Lua Code:
  1. local TransmogSets={
  2.     {
  3.         name="Mystic's Regalia (Recolor)",
  4.         items={14090, 26008, 14094},
  5.     },
  6.     {
  7.         name="Imperial Plate",
  8.         items={31436, 30002, 12424, 12425, 12422, 12427, 12429},
  9.     },
  10. --  And so on ...
  11. };
  12.  
  13. --  Lookup Table
  14. local ItemSetNames={}; do
  15.     for _,set in ipairs(TransmogSets) do--  Scan through all sets
  16.         for _,itemid in ipairs(set.items) do--  Scan through items
  17. --          Add set name to list in lookup table
  18.             if not ItemSetNames[itemid] then ItemSetNames[itemid]={}; end
  19.             table.insert(ItemSetNames[itemid],set.name);
  20.         end
  21.     end
  22.  
  23. --  Sorts set names
  24.     for _,list in pairs(ItemSetNames) do table.sort(list); end
  25. end
  26.  
  27. --  Tooltip Hook
  28. GameTooltip:HookScript("OnTooltipSetItem",function(self)
  29.     local _,link=self:GetItem();
  30.     if not link then return; end--  Exit if we have no item
  31.  
  32.     local id=tonumber(link:match("|Hitem:(%d+)")) or 0;--   Force nil to zero if we have an invalid link (no items exist at index zero)
  33.     if ItemSetNames[id] then
  34.         for i,name in ipairs(ItemSetNames[id]) do
  35. --          Only show our label on the first line
  36.             self:AddDoubleLine(i<=1 and "Transmog Set:" or " ",name);
  37.         end
  38.     end
  39. end);
  40.  
  41. --  Chat Hook
  42. ChatFrame_AddMessageEventFilter("CHAT_MSG_LOOT",function(self,event,msg,...)
  43.     local id=tonumber(msg:match("|Hitem:(%d+)")) or 0;--    Force nil to zero if we have an invalid link (no items exist at index zero)
  44.     if ItemSetNames[id] then return false,msg.." (|cff9400d3Transmog Sets: "..table.concat(ItemSetNames[id],", ").."|r).",...; end
  45. end);

Edit: Replaced string.join() section with more efficient table.concat() call.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)

Last edited by SDPhantom : 08-17-15 at 03:15 PM.
  Reply With Quote
08-15-15, 01:06 PM   #8
Endzeit
A Deviate Faerie Dragon
Join Date: Aug 2015
Posts: 12
Lua Code:
  1. --  Chat Hook
  2. ChatFrame_AddMessageEventFilter("CHAT_MSG_LOOT",function(self,event,msg,...)
  3.     local id=tonumber(msg:match("|Hitem:(%d+)")) or 0;--    Force nil to zero if we have an invalid link (no items exist at index zero)
  4.     if ItemSetNames[id] then return false,msg.." (|cff9400d3Transmog Sets: "..string.join(", ",unpack(ItemSetNames[id])).."|r).",...; end
  5. end);

works.. but it also show loot from other player.. this should not happen. i tried this:
Lua Code:
  1. --  Chat Hook
  2. ChatFrame_AddMessageEventFilter("CHAT_MSG_LOOT",function(self,event,msg,...)
  3.     local id=tonumber(msg:match("|Hitem:(%d+)")) or 0;--    Force nil to zero if we have an invalid link (no items exist at index zero)
  4.     if ItemSetNames[id] and LOOT_ITEM_PUSHED_SELF or LOOT_ITEM_SELF ~= nil then return false,msg.." (|cff9400d3Transmog Sets: "..string.join(", ",unpack(ItemSetNames[id])).."|r).",...; end
  5. end);
this works for myself.. but get lua errors if other player loot items.
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Problems with Big Tables


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off