Results 1 to 23 of 23

Thread: Searching for a card in deck by string.find(desc, "") possible?

  1. #1

    Searching for a card in deck by string.find(desc, "") possible?

    I have tagged a bunch of cards that I'd like to make a menu system for grabbing every card based on the "tag category" and insert them into a table so I can lay them out by position with {x + #cardTable * 1, y, z} as an example. Is it possible to find by description and then take by guid?

  2. #2
    Join Date
    May 2016
    Posts
    1,072
    This is a basic example of the concept. It goes through each card in a deck and looks for if it has the description of "Some description". If it finds it, it takes it out of the deck. You could also use position/rotation/etc with takeObject like normal, see the Knowledge Base "object" page for the parameters takeObject can work with in addition to guid

    Code:
    for _, card in ipairs(deck.getObjects()) do
        local desc = card.description
        if desc = "Some description" then
            deck.takeObject({guid=card.guid})
        end
    end
    But you want to get cards in a table. How you do this depends on how you formatted your table. There's a few ways.

    In this method, your table has keys equal to your card descriptions with an arbitrary value set to them.

    Code:
    ref_desc = {
        ["Card 1"] = true,
        ["Card 2"] = true,
        ["Card 3"] = true,
        ["Card 4"] = true,
        ["Card 5"] = true,
        ["You get the idea"] = true,
    }
    
    for _, card in ipairs(deck.getObjects()) do
        local desc = card.description
        if ref_desc[desc] ~= nil then
            deck.takeObject({guid=card.guid})
        end
    end
    Or you could have just strings in a table, in which case you'd need to loop over that table for each card.

    Code:
    ref_desc = {
        "Card 1", "Card 2", "Card 3", "Card 4", "Etc etc"
    }
    
    for _, card in ipairs(deck.getObjects()) do
        local desc = card.description
        if tableContains(ref_desc, desc) then
            deck.takeObject({guid=card.guid})
        end
    end
    
    function tableContains(t, s)
        for _, v in pairs(t) do
            if v == s then
                return true
                break
            end
        end
        return false
    end
    I didn't test any of this code, so this is just to give you a general idea of the concepts. The code might be sound but it wouldn't be the first (or 1000'th) mistake I've made

  3. #3
    Ok thanks, I think my mistake was I was trying to do

    Code:
    local deck = getObjectFromGUID('guid')
    for _, card in ipairs(cardsInDeck.getObjects()) do
    local desc = card.getDescription()
    print(desc)
    end
    I was just testing to see if it was getting the description but I would error for nil value on that line.

    I plan to just fill a table like this (example of how I have done it elsewhere)

    Code:
    menuTable = {}
    
    function createMenuWeapons(object, player_color)
      broadcastToColor("Selected Weapon will update Dice Roller Stats", player_color, {1,1,1})
      clearMenuButtons()
          table.insert(menuTable, self.createButton({click_function = "fistTooth", function_owner = self, label = "Fist & Tooth",
          position={0, 0.2, -9.5 + #menuTable * 1.2}, scale = {0.5, 0.5, 0.5}, width = 6000, height = 1000,
          color = {0,0,0}, font_color = {0.118, 0.53, 1}, font_size = 750}))
    
      for _, object in ipairs(zone.getObjects()) do
        local desc = object.getDescription()
        if string.find(desc, 'weapon') then
          self.setVar("equipWeapon_" .. object.getName(), function () weaponEquiped(object.getGUID(), object, player_color) end)
          table.insert(menuTable, self.createButton({click_function = "equipWeapon_" .. object.getName(), function_owner = self, label = object.getName(),
          position={0, 0.2, -9.5 + #menuTable * 1.2}, scale = {0.5, 0.5, 0.5}, width = 6000, height = 1000,
          color = {0,0,0}, font_color = {0.118, 0.53, 1}, font_size = 750}))
        end
      end
      self.createButton({click_function = "mainMenu", function_owner = self, label = "Main Menu",
      position = {-0.3, 0.1, -10.7}, scale = {0.5, 0.5, 0.5}, width = 6000, height = 1100, color = {0,0,0}, font_color = {0.118, 0.53, 1}, font_size = 850})
    end
    So this is what it looks like



    The menu dynamically changes as you move through it. So pick a category, all buttons are removed, new menu opens with the names of the cards found in the zone within that category. Then each new button has a function based on the card effects. Main Menu takes you back.

    I plan to do similar for the cards in the deck. They could be searched by expansion pack, or weapon type ("swords" for example) or weapon ability, and so on.

    So pulling the cards out of the deck, I would choose a starting position, then shift on x-axis an amount equal to posX + #menuTable * value. I'll probably make a row of 10, then have it shift up to make another row of 10 and so on. The cards auto clone onObjectLeave container so pulling the cards out will all be new copies with the clones going back onto the deck they were pulled from. And then, I'll have each selection of the new category destroy all current cards on the table as it generates the new selected category.

    Lastly here is an example card description and why I need to do string.find

    Code:
    gear, weapon, blacksmith, 2spd, 6acc, 4str, melee, spear, axe, two-handed, finesse, metal, reach2, sharp, earlyIron, green_down, copy
    Last edited by maximo1984@ymail.com; 10-08-2017 at 03:26 AM.

  4. #4
    Ok here is the code. It is working beautifully. Every press of the button deletes anything already in the table, so if you go to a new category, the cards from the previous are deleted. And every click to add cards clones the originals back to the master deck.

    Code:
    function red_up()
      if next(gear_Table) ~= nil then
        for k, v in pairs(gear_Table) do
          v.destroy()
        end
      end
      gear_Table = {}
      for _, card in ipairs(gearDeck.getObjects()) do
        local desc = card.description
        if string.find(card.description, "red_up") then
            table.insert(gear_Table, gearDeck.takeObject({guid=card.guid,
            position = {pos.x - 12.64 + #gear_Table * 3.16, pos.y, pos.z + 9.48},
            callback="flipCard", callback_owner=Global}))
        end
      end
    end
    Now I need to add the position shift for when the row is filled and I want to start a new row.

    Here is Eskander's code for the clone on leave container

    Code:
    function onObjectLeaveContainer(container, object)
    		local desc = object.getDescription()
    		if string.find(desc, 'archive') then
    			if container then
    				local params = {}
    				local destination = {}
    				if string.find(desc, 'gear') or string.find(desc, 'story') then
    					destination = container.getPosition()
    					destination.y = destination.y + 2
                                    end
                           end
                     end
    
              params.position = destination
    	  local clone = object.clone(params)
    	  desc = string.gsub(desc, 'archive', 'copy')
    	  object.setDescription(desc)
    end

  5. #5
    I am having trouble trying to set a new row, can I get a little help please?

    Code:
    offset = 3.16
    offsetZ = 9.48
    offsetX = 12.64
    
    function red_up()
    
      if next(gear_Table) ~= nil then
        for k, v in pairs(gear_Table) do
          v.destroy()
        end
      end
    
      gear_Table = {}
      count = 0
      for _, card in ipairs(gearDeck.getObjects()) do
        local desc = card.description
        if string.find(desc, "red_up") then
          count = count + 1
    
          for count=1, 9 do
            table.insert(gear_Table, gearDeck.takeObject({guid=card.guid,
            position = {pos.x - offsetX + #gear_Table * offset, pos.y, pos.z + offsetZ},
            callback="flipCard", callback_owner=Global}))
          end
    
          for count=10, 18 do
            table.insert(gear_Table, gearDeck.takeObject({guid=card.guid,
            position = {pos.x - offsetX + #gear_Table * offset, pos.y, pos.z + offsetZ * offset},
            callback="flipCard", callback_owner=Global}))
          end
        end
      end
    
      print(count .. " cards found with Red Up Affinity")
    end

  6. #6
    Join Date
    May 2016
    Posts
    1,072
    I haven't familiarized myself with all the code but when you want a new line, adding SOMENUMBER to offsetZ aught to accomplish it, I would imagine. I'm not sure what is being looped over and in what order to say more.

  7. #7
    I want cards 1-9 to fill row 1
    10-18 to fill row 2
    19-27 row3

    and so on

    This is based on the number of cards found with the keyword I'm looking for.

  8. #8
    Simple example
    Code:
    -- How much space should be between cards
    local spacing = {x = 3, z = 2}
    -- How many cards in a row
    local rowNum = 9
    -- Initial position
    local initPos = {0, 1, 0}
    
    -- Get the position of Nth card, starting at 1
    function CardPosition(num)
        local row = math.floor((num-1)/rowNum)
        local col = (num-1)%rowNum
        return { initPos[1] + spacing.x*col, initPos[2], initPos[3] + spacing.z*row }
    end

  9. #9
    Ok thank you, I have it working with this but

    Code:
    -- Get the position of Nth card, starting at 1
    function CardPosition(num)
      local spacing = {x = 3.16, z = 3.16}
      local rowNum = 9
      local initPos = {46.61, 4.19, -23.79}
      local num = 1
    
        local row = math.floor((num-1)/rowNum)
        local col = (num-1)%rowNum
        return { initPos[1] + spacing.x*col, initPos[2], initPos[3] + spacing.z*row }
    end
    in the table.insert portion

    Code:
      for _, card in ipairs(gearDeck.getObjects()) do
      local desc = card.description
    
        if string.find(desc, "red_up") then
    
            table.insert(gear_Table, gearDeck.takeObject({guid=card.guid,
            position = CardPosition(num),
            callback="flipCard", callback_owner=Global}))
    
        end -- end if string.find
      end -- end for loop
    It spawns all the cards to the starting position, I had to add local num = 1 cause else it was nil value

  10. #10
    Join Date
    May 2016
    Posts
    1,072
    This is the relevant bit here;

    Code:
    for count=1, 9 do
        table.insert(gear_Table, gearDeck.takeObject({guid=card.guid,
        position = {pos.x - offsetX + #gear_Table * offset, pos.y, pos.z + offsetZ},
        callback="flipCard", callback_owner=Global}))
    end
    
    for count=10, 18 do
        table.insert(gear_Table, gearDeck.takeObject({guid=card.guid,
        position = {pos.x - offsetX + #gear_Table * offset, pos.y, pos.z + offsetZ * offset},
        callback="flipCard", callback_owner=Global}))
    end
    In the second for loop, that is your next row. Presumably adding offset to z is lowering the row down would accomplish your goal here. The math there in setting position does not make a ton of sense to me though. Here's how I typically do it as an alternative;

    Code:
    --Assume that pos is the position of the first card in the first row
    local pos = {x=0,y=0,z=0}
    --Distance side-to-side for card placement
    local offset_x = 1.5
    --Distance top to bottom for card placement
    local offset_z = 2.5
    
    --Count our number of rows
    local rows = 0
    --We want to place 27 cards, so this loops runs 27 times
    for i=0, 26 do
        --i%7 is modulo. 7 is how many cards are in the row.
        --This will offset the cards left-right and reset at the end of a row
        local x = pos.x + (i % 7) * offset_x
        local z = pos.z + rows * offset_z
        --Adds another row once the previous one gets its 7th card
        if i%7 == 6 then rows = rows + 1 end
        local card = gearDeck.takeObject({
            guid=card.guid,
            position = {x, pos.y, z},
            callback="flipCard",
            callback_owner=Global,
        })
        table.insert(gear_Table, card)
    end

  11. #11
    @Maximo
    In that snippet you posted, you added a "local num = 1" which overwrites the parameter you pass. Also, there's no need to have other locals inside, they can be before this function like in my example

  12. #12
    Yes that makes sense, however I get error attempt to perform arithmetic on nil value for line

    >> local x = pos.x + (i % 9) * offset_x

    Code:
      for _, card in ipairs(gearDeck.getObjects()) do
      local desc = card.description
    
        if string.find(desc, "red_up") then
          count = count + 1
    
          for i=0, count do
            local x = pos.x + (i % 9) * offset_x
            local z = pos.z + rows * offset_z
            --Adds another row once the previous one gets its 7th card
            if i%9 == 8 then rows = rows + 1 end
    
            local card = gearDeck.takeObject({
              guid=card.guid,
              position = {x, pos.y, z},
              callback="flipCard", callback_owner=Global})
    
            table.insert(gear_Table, card)
          end
        end
      end
    @ dzikakulka _ I'll try it again

  13. #13
    Yeah, same problem , nil value on this line, I assumed cause num was not set to anything.

    >> local row = math.floor((num-1)/rowNum)

  14. #14
    Can you paste the whole thing, the version with the function that has this line with nil value? It should be easy to pinpoint.

  15. #15
    Code:
    function red_up()
    
      if next(gear_Table) ~= nil then
        for k, v in pairs(gear_Table) do
          v.destroy()
        end
      end
    
      gear_Table = {}
      local count = 0
    
      for _, card in ipairs(gearDeck.getObjects()) do
      local desc = card.description
    
        if string.find(desc, "red_up") then
          count = count + 1
    
          local card = gearDeck.takeObject({
            guid=card.guid,
            position = CardPosition(num),
            callback="flipCard", callback_owner=Global})
    
            table.insert(gear_Table, card)
          end
        end
    
      print(count .. " cards found with Red Up Affinity")
    end -- end function
    
      -- How much space should be between cards
      local spacing = {x = 3.16, z = 3.16}
      -- How many cards in a row
      local rowNum = 9
      -- Initial position
      local initPos = {46.61, 4.19, -23.79}
    
      -- Get the position of Nth card, starting at 1
      function CardPosition(num)
          local row = math.floor((num-1)/rowNum)
          local col = (num-1)%rowNum
          return { initPos[1] + spacing.x*col, initPos[2], initPos[3] + spacing.z*row }
      end

  16. #16
    Well you call it with "num" as the parameter (which is nil) instead of "count" which is what you wanted most likely

  17. #17
    Say what now?

  18. #18
    Code:
    position = CardPosition(count)

  19. #19
    Ok, I see now, thanks a bunch, I agonized over this for 4 hours.

  20. #20
    so new problem I need to pull the cards out of the table as they leave the zone that i set for where they spawn, so they don't get destroyed. I know the .index part is wrong. HOw should it be?

    Code:
    function onObjectLeaveScriptingZone(zone, leave_object)
      if zone == getObjectFromGUID(Global.getTable('zones').zoneGearStation.guid) then
          leave_object = table.remove(gear_Table, leave_object.index)
      end
    end

  21. #21
    Code:
    for k,obj in pairs(gear_Table) do
        if obj == leave_object then
            table.remove(gear_Table, k)
            break
        end
    end

  22. #22
    YOu're awesome man, thanks, and thanks also @MrStump

  23. #23
    I finally got it done, just wanted to drop a video demonstration. Thanks again for the help

    https://www.youtube.com/watch?v=KkZLFHI1oJA

Similar Threads

  1. Replies: 5
    Last Post: 08-09-2017, 11:32 PM
  2. Replies: 5
    Last Post: 08-09-2017, 11:32 PM
  3. Replies: 1
    Last Post: 06-07-2017, 12:50 AM
  4. Garbage in "Steam authentication" string
    By customKarma in forum Bug Reports
    Replies: 0
    Last Post: 07-25-2016, 01:46 AM
  5. Replies: 1
    Last Post: 04-28-2016, 05:48 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •