Reordering inventory items (SOLVED)

  • #1, by klootSaturday, 08. February 2014, 18:21 11 years ago
    Hi. Is it possible to change the order of inventory items? Here's my code where I try to shift the first inventory item to the last position. I need this for custom scrolling.

    function arrangeItems()
      player = getObject("Game.GameCurrentCharacter")
      items = player:getLinks(VCharacterItems)
      table.insert(items, (table.remove(items, 0)))
      player.setValue(VCharacterItems, items)
    end
    


    The Data Structure doc claims that the field CharacterItems is scriptable, but when I feed the table i get back in, I get the following error in messages.log:

    bad argument #1 to 'setValue' (Visionaire.TVisionaireObject expected, got number)
    


    Please help me. If CharacterItems is indeed scriptable, how do I do that?


    EDIT: ARFLme solved this for me. Two small errors. Here's the working code:
    function arrangeItems()
      player = getObject("Game.GameCurrentCharacter")
      items = player:getLinks(VCharacterItems)
      table.insert(items, (table.remove(items, 1)))
      player:setValue(VCharacterItems, items)
    end
    

    Explanation: 1) Typo after player (needs to be colon instead of dot. 2) Table indexes in Lua start at 1, not 0

    Newbie

    14 Posts


  • #2, by afrlmeSaturday, 08. February 2014, 19:11 11 years ago
    what does the "table.insert(items, (table.remove(items, 0)))" do?

    the error sounds like it is referring to the fact that the table returned the id numbers instead of the string name for the items... I could be wrong though.

    local player, items
    tblItems = {}
    
    function arrangeItems()
     player = game:getLink(VGameCurrentCharacter)
     items = player:getLinks(VCharacterItems)
     for i = 1, table.maxn(items) do table.insert(tblItems, items[i]:getName()) end
     player:setValue(VCharacterItems, tblItems)
    end
    


    I'm not sure if the code is correct & I'm not sure if it is possible to reorganize the items in the built in inventory system but I'll get back to you later on wink

    * edit: still not tested the code but have been looking into sorting table entries... you can manually sort out the order yourself or you can use a function to alphabetize them ascending or descending.

    -- here's a bit of code I tested in LuaEdit. (see attachment)
    tbl = {"item1", "item4", "item3", "item2"}
    
    print("-- * before * --")
    
    for i = 1, table.maxn(tbl) do
    print(tbl[i])
    end
    
    local sort_func = function( a,b ) return a < b end
    table.sort( tbl, sort_func )
    
    print("-- * after * --")
    
    for i = 1, table.maxn(tbl) do
    print(tbl[i])
    end
    

    here's my revised code: (again, still don't know if it will actually work)
    local player, items -- blank variables
    tblItems = {} -- empty table
    local sort_func = function( a,b ) return a < b end -- function that sorts alphabetically
    
    function arrangeItems()
     player = game:getLink(VGameCurrentCharacter) -- store current character
     items = player:getLinks(VCharacterItems) -- store items
     -- * add each item into a table; one at a time * --
     for i = table.maxn(items) do table.insert(tblItems, items[i]:getName()) end 
     -- * sort the items alphabetically * --
     table.sort( tblItems, sort_func )
     -- * amend the new item list to the current character * --
     player:setValue(VCharacterItems, tblItems)
    end
    

    Imperator

    7278 Posts

  • #3, by klootMonday, 10. February 2014, 10:35 11 years ago
    Dear ARFLme, thanks so much for your long reply. Unfortunately, it still doesn't accept what I feed in. I'm now doing your name thing:

    function shiftFirstItemDown()
      for i = 1, table.maxn(items) 
        do table.insert(tblItems, items[i]:getName()) 
      end
      player.setValue(VCharacterItems, tblItems)
    end
    


    Strangely, it still returns "got number", when I was expecting we were feeding in a string?

    bad argument #1 to 'setValue' (Visionaire.TVisionaireObject expected, got number)
    


    Even if I just do this, it's wrong:

    function arrangeItems()
      player = getObject("Game.GameCurrentCharacter")
      items = player:getLinks(VCharacterItems)
      player.setValue(VCharacterItems, items)
    end
    


    Maybe one of the engine guys could clarify what VCharacterItems is expecting to be fed?

    Newbie

    14 Posts

  • #4, by afrlmeMonday, 10. February 2014, 16:03 11 years ago

    Strangely, it still returns "got number", when I was expecting we were feeding in a string?
    bad argument #1 to 'setValue' (Visionaire.TVisionaireObject expected, got number)
    



    this error is because you keep typing:
    player.setValue

    instead of:
    player:setValue

    either way it's not important as I'm having issues with trying to get it to sort the items table without using getName(). when I use getName() I can sort the table but then it won't let me add the reordered item list to characteritems. (¡headache!)

    Imperator

    7278 Posts

  • #5, by klootMonday, 10. February 2014, 18:55 11 years ago
    Ah! Thanks so much! Yes, it was indeed the dot instead of the colon. What a mess. So the code works like this and I'm all happy:
    function shiftFirstItemDown()
      table.insert(items, (table.remove(items, 1)))
      player:setValue(VCharacterItems, items)
    end
    


    Solved!

    I guess you want to sort your inventory alphabetically, ARFLme? Here's a thought: Work with the original table and in your sort function, read out the names of the two items you are comparing and return them based on their names?

    Newbie

    14 Posts

  • #6, by afrlmeMonday, 10. February 2014, 20:00 11 years ago
    Not really, I have no intention of using the default inventory system. It's not exactly hard to create a custom one. I was just trying to see if it would be possible to sort out the items alphabetically or however.

    Anyway I finally figured out how to sort items alphabetically.
    --[[
    Organize Items Alphabetically (v1) [10/02/2014]
    By AFRLme
    -- + --
    alternatingfrequencies@hotmail.com | skype @ AFRLme
    --]]
    
    local char, items -- empty variables
    local sort_func = function( a,b ) return a:getName() < b:getName() end -- sort function (ascending A-Z, 1-10 etc)
    
    function arrangeItems()
     char = game:getLink(VGameCurrentCharacter) -- store current character
     items = char:getLinks(VCharacterItems) -- store items
     table.sort(items, sort_func) -- sort the items alphabetically
     char:setValue(VCharacterItems, items) -- amend new item order to the inventory
    end
    

    -- * --

    I'm still not sure what you wanted to reorder the items for? or rather why you wanted to shift the first item or whatever. could you explain please?

    * edit: just tested your code & I see what it does now... it shifts all of the items down by one item position. you do know that that is technically possible with the interface buttons? you can create buttons & set them as "scroll items..." types & in the properties tab for the interface you can define the amount of items to scroll/move by each time you click on one of the arrows.

    Imperator

    7278 Posts

  • #7, by afrlmeTuesday, 11. February 2014, 03:22 11 years ago
    & back again (oh no) razz

    I've written a cycle script that does what your script does but allows you to cycle forwards & backwards through the items by including true or false in the function:

    the main script: [definition script]
    --[[
    Cycle inventory items by ascending or descending order (v1) [11/02/2014]
    Written by AFRLme
    -- + --
    alternatingfrequencies@hotmail.com | skype @ AFRLme
    --]]
    
    -- * local variables * --
    local char, items, item, amt -- empty variables
    
    -- * function for cycling through the inventory items * --
    function cycleItems(asc)
     char = game:getLink(VGameCurrentCharacter) -- store current character
     items = char:getLinks(VCharacterItems) -- store inventory items into a table
     amt = table.maxn(items) -- get index number of last item
     -- if asc is true (ascending) then item = last item, remove last item from table & insert into slot 1 else (descending) item = first item, remove first item & insert into last slot
     if asc then item = items[amt]; table.remove(items, amt); table.insert(items, 1, item) else item = items[1]; table.remove(items, 1); table.insert(items, (table.maxn(items)+1), item) end
     char:setValue(VCharacterItems, items) -- update the inventory
    end
    

    cycle forwards (ascending)
    cycleItems(true)
    

    cycle backwards (descending)
    cycleItems(false)
    

    only for if you are interested; of course.

    Imperator

    7278 Posts

  • #8, by fritozTuesday, 11. February 2014, 08:49 11 years ago
    wow great script, im going to have to use that one!

    crazy how one little typo can crash your whole game!

    Newbie

    16 Posts

  • #9, by afrlmeTuesday, 11. February 2014, 12:52 11 years ago
    wow great script, im going to have to use that one!

    crazy how one little typo can crash your whole game!


    vs 3.7.1 razz
    Next release will be a lot more stable... I've not had any crashing issues in the dev or beta builds; apart from when I tried to run a while loop with lua or maybe it was a repeat until loop - I forget.

    Imperator

    7278 Posts