• Sorting and Generating a Business Menu by Category (Alphabetically)
    2 replies, posted
  • Avatar of LaughingLeader
  • I'm having a bit of trouble getting a table (in [B]Tiramisu[/B]), filled with item data, to sort by it's category (in alphabetical order). I'm still fairly new to LUA and programming in general, so I'm not sure if I'm going about it the right way. The snippet that builds the business menu item data looks like this: [U][B]business.lua[/B][/U] [lua] CAKE.Business = {} --Copies all buyable items on the CAKE.Business table. function CAKE.BuildItemGroups() local tbl = {} for k,v in pairs(CAKE.ItemData) do if !CAKE.Business[v.ItemGroup] then CAKE.Business[v.ItemGroup] = {} end if v.Purchaseable then tbl = {} tbl.Class = v.Class tbl.Model = v.Model tbl.Name = v.Name tbl.Description = v.Description .. "\nPrice: " .. v.Price tbl.Price = v.Price tbl.category = v.category tbl.IconM = v.IconM --Category Sort table.sort(tbl, function(a,b) return a.category > b.category end) --Test the results for k,v in pairs(tbl) do print(k, v) end table.insert(CAKE.Business[v.ItemGroup], tbl) end end end [/lua] I've tried sorting the "tbl" table by category, and even the CAKE.Business menu by category, but both don't seem to sort when I do that. I haven't been getting any errors, but the item order doesn't go alphabetical. I've also double-checked to make sure the category key is working, and it is. It even shows up on the item tooltip via this: [B][U]cl_inventory.lua[/U][/B] [lua] --Sets an item to be used on the inventory slot. The item thing is a table, not a string. Amount defaults to 1. function PANEL:SetItem( item, amount ) self.Item = item if !self.Icon then self.Icon = vgui.Create( "InventorySlot_Icon", self ) self:SetIconSize( self.IconSize ) end -- Item tooltip. Added item.category. if item.Description != "" then self:SetToolTip( "[" .. item.category .. "]" .. "\n" .. item.Name .. "\n" .. item.Description ) else self:SetToolTip( "[" .. item.category .. "]" .. "\n" .. item.Name ) end -- Changes the Icon model to the "IconM" field if valid. if item.IconM == "" then self.Icon:SetModel( item.Model ) else self.Icon:SetModel( item.IconM ) end self:SetAmount( amount or 1 ) self:OnUseItem( item, amount ) end [/lua] The business menu actually builds the icons in this little snippet of code: [U][B]cl_business.lua[/B][/U] [lua] local icontable = {} for k, item in pairs( BusinessTable[buygroup] ) do icontable[k] = vgui.Create( "InventorySlot" ) icontable[k]:SetIconSize( 48 ) icontable[k]:SetItem( item ) icontable[k]:DisableDrag() icontable[k].OnMousePressed = function() icontable[k]:OpenMenu() end icontable[k].OnMouseReleased = function() end icontable[k].OpenMenu = function() local ContextMenu = DermaMenu() ContextMenu:AddOption("Buy", function() LocalPlayer():ConCommand("rp_buyitem " .. icontable[k]:GetItem().Class ) end) ContextMenu:Open() end icontable[k].PaintOver = function() surface.SetTextColor(Color(255,255,255,255)); surface.SetFont("TirimisuTabsFont"); surface.SetTextPos( icontable[k]:GetWide() - 20, icontable[k]:GetTall() - 14); surface.DrawText( icontable[k]:GetItem().Price or "0" ) end grid:AddItem( icontable[k] ) end end end [/lua] So, I'm not sure if I've been going about this the right way, but I figured that sorting the table in the business.lua file would work, as then the code pulls that data and builds everything else. It doesn't seem to be working though, as the print output to the console isn't in alphabetical order (by category). It'll show zipties as first (category: Miscellaneous), then an Alcohol item, then some Weaponry, followed by random mixtures of other items. Also, any changes to how the sorting function compares the a.category and b.category just shifts the items around in a weird way. Any ideas on how to get this to work would be appreciated.
  • [b][url=http://wiki.garrysmod.com/?title=G.SortedPairs]G.SortedPairs [img]http://wiki.garrysmod.com/favicon.ico[/img][/url][/b] Sorts through a table's keys from lowest to highest, starting with numbers. [b][url=http://wiki.garrysmod.com/?title=G.SortedPairsByValue]G.SortedPairsByValue [img]http://wiki.garrysmod.com/favicon.ico[/img][/url][/b] This goes by value of the key. [b][url=http://wiki.garrysmod.com/?title=G.SortedPairsByMemberValue]G.SortedPairsByMemberValue [img]http://wiki.garrysmod.com/favicon.ico[/img][/url][/b] This goes by member of a table. Syntax is SortedPairsByMemberValue(table,member)
  • Avatar of LaughingLeader
  • Unfortunately, that's giving me an error: [lua] for k, v in SortedPairsByMemberValue(tbl, "category") do print(k, v.category) end [/lua] [lua] Hook 'TiramisuBuildItemGroups' Failed: [lua\includes\extensions\table.lua:478] attempt to index local 'v' (a string value)[/lua] Here's the hook (it just calls the CAKE.BuildItemGroups() function I've been messing with): [lua]hook.Add( "InitPostEntity", "TiramisuBuildItemGroups", function() CAKE.BuildItemGroups() end)[/lua] Line 478 of table.lua is v.__key = k in this: [lua] *--------------------------------------------------------- Name: table.ClearKeys( table, bSaveKey ) Desc: Clears the keys, converting to a numbered format ---------------------------------------------------------*/ function table.ClearKeys( Table, bSaveKey ) local OutTable = {} for k, v in pairs( Table ) do if ( bSaveKey ) then v.__key = k end table.insert( OutTable, v ) end return OutTable end [/lua] SortedPairsByMemberValue calls table.ClearKeys: [lua] /*--------------------------------------------------------- A Pairs function Sorted by Member Value (All table entries must be a table!) ---------------------------------------------------------*/ function SortedPairsByMemberValue( pTable, pValueName, Desc ) Desc = Desc or false local pSortedTable = table.ClearKeys( pTable, true ) table.SortByMember( pSortedTable, pValueName, !Desc ) local SortedIndex = {} for k, v in ipairs( pSortedTable ) do table.insert( SortedIndex, v.__key ) end pTable.__SortedIndex = SortedIndex return fnPairsSorted, pTable, nil end [/lua] Maybe I shouldn't bother with trying to organize the table right here, but rather when the function generates the icons?