Results 1 to 11 of 11

Thread: Creating a deck that has both constant and random components

  1. #1

    Creating a deck that has both constant and random components

    Hey Everyone!

    I am having some difficulties getting my onLoad script to work the way I want it to, though I realize I could be trying to do something that can't be done. In my game I have a deck of 9 cards of which a different six will be used each game. Of those six, 2 are always the same and four need to be random. Basically I'm trying to script "Find x and y card and set aside. Shuffle the remaining cards and deal four face down. Add x and y to the four cards just dealt, shuffle them together, and place them on the gameboard."

    What I've done is created a piles of cards, one that has 7 cards that the four random cards will be pulled from, and another of just the two that are constant. In my script, I create object references to those decks: digitalAssets refers to the deck of 7 and startingDigitalAssets refers to the deck of 2. Later in my script I then draw four cards from digitalAssets using the x, y, and z coordinates of startingDigitalAssets as the destination of the drawn card.

    This successfully creates the deck of six cards that I need, but in the process it changes the GUID of the deck so my startingDigitalAssets variable no longer points to anything, so I have no way of then taking those six cards and moving them to the correct locations on my game board.

    I had a thought about using a scripting zone around the deck of 2 and then using the getObjects function to get a reference to all of the cards in the zone, which I could hopefully then use to shuffle the cards and deal them to their spots on the game board. However, this doesn't seem to be working. I'm guessing that is because I'm not understanding how the getObjects function works and/or I'm trying to use it in a way that isn't valid.

    Is what I am trying to accomplish even possible, or am I just going to have to create the deck and add them to the game board manually at the start of each game? If it is possible, what would be the best way to accomplish what I am trying to do? Any help that can be provided would be greatly appreciated.

    Raymond

  2. #2
    yes it is possible and you are on the right track.. the changing GUID thing is an issue that we all had to get our heads around...

    My Stump has some code that works well for this I have pasted into the "Script Examplesp" thread on this forum..

    Code:
    function getType(z, ...)
        local foundTypes, tagList = {}, {...}
        local zone = getObjectFromGUID(z)
        for _, object in ipairs(zone.getObjects()) do
            for _, tag in ipairs(tagList) do
                if object.tag == tag then
                    table.insert(foundTypes, object)
                    break
                end
            end
        end
        return foundTypes
    end
    This function will test a zone and return a table of objects that match the types you choose. It returns a list of objects so you can use it a few ways, the most basic would be like this...

    Code:
    local inZoneList = getType(zoneGuid, 'Card', 'Deck')
    then you can do test on them and then do stuff.

    Code:
    function deal(num,player,hand,GUID)
        for _, deck in ipairs('zoneGuid', 'Deck', 'Card')) do
            if deck.tag == 'Deck' or deck.tag == 'Card' then
                local prams = {p={0.15, 3.03, -5.67},r={0.00, 180.00, 0.00}}
                deck.setPositionSmooth(prams.p)
                deck.setRotationSmooth(prams.r)
            end
        end
    end
    or something like that... (untested so this may not exactly work.. but probably dose)

    Quote Originally Posted by gamesbyray View Post
    I had a thought about using a scripting zone around the deck of 2 and then using the getObjects function to get a reference to all of the cards in the zone, which I could hopefully then use to shuffle the cards and deal them to their spots on the game board. However, this doesn't seem to be working. I'm guessing that is because I'm not understanding how the getObjects function works and/or I'm trying to use it in a way that isn't valid
    getObjects returns a table of tables.... if gets slightly different data based on if you test a Bag or Deck. getObject on a zone gets the objects themselves.. so all the data for an object is accessible, get Deck though you only have certain things you can access.

    So for example...

    Code:
    local stuff = getObjects(zone)
    returns the obejcs and puts them in the list stuff... so... stuff[1], stuff[2], stuff[3], stuff[4]... etc are all individual objects it finds in that zone...

    Code:
    name = stuff[1].getName()
    guid = stuff[1].getGuid()
    stuff[1].shuffle()
    stuff[1].setPosition(x,x,x)
    etc etc...

    Even if you only have 1 object in the list it will still be in a list called stuff (in this case)

    so you can loop though that list to acess everything in it and run tests to do what you want..

    Code:
     for _, obj in ipairs(stuff) do
         do stuff in here
    end
    in this loop... every object is obj.. so stuff[1] would be obj.. then you cna do tests like if obj.tag == "Card" then do stuff end
    Last edited by Tragic; 03-01-2018 at 08:05 PM.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  3. #3
    Quote Originally Posted by Tragic View Post
    yes it is possible and you are on the right track.. the changing GUID thing is an issue that we all had to get our heads around...

    My Stump has some code that works well for this I have pasted into the "[url=http://www.berserk-games.com/forums/showthread.php?1990-Scripting-Examples&p=19760#post19760]Script Examplesp/url]" thread on this forum..

    Code:
    function getType(z, ...)
        local foundTypes, tagList = {}, {...}
        local zone = getObjectFromGUID(z)
        for _, object in ipairs(zone.getObjects()) do
            for _, tag in ipairs(tagList) do
                if object.tag == tag then
                    table.insert(foundTypes, object)
                    break
                end
            end
        end
        return foundTypes
    end
    This function will test a zone and return a table of objects that match the types you choose. It returns a list of objects so you can use it a few ways, the most basic would be like this...

    Code:
    local inZoneList = getType(zoneGuid, 'Card', 'Deck')
    then you can do test on them and then do stuff.

    Code:
    function deal(num,player,hand,GUID)
        for _, deck in ipairs('zoneGuid', 'Deck', 'Card')) do
            if deck.tag == 'Deck' or deck.tag == 'Card' then
                local prams = {p={0.15, 3.03, -5.67},r={0.00, 180.00, 0.00}}
                deck.setPositionSmooth(prams.p)
                deck.setRotationSmooth(prams.r)
            end
        end
    end
    or something like that... (untested so this may not exactly work.. but probably dose)
    Thanks for this - it seems to be working well. I've now run into a new issue - I have successfully created the deck of 6 cards (the 2 that are always there and 4 random ones) and have used the getType function to identify that the object in the zone is a deck of cards. The issue is that for some reason it is only recognizing the original two cards in the deck even though when I hover over the deck it shows a deck of 6 cards. I've been running into this for a little while now, but can usually get it to work again by playing with the y positioning and y scale values, but it is just a lot of guess work until it works again. I'm never 100% sure why it starts working again and want to understand better what is happening. It appears that it may be related to the scripting zone not completely covering the deck in all three directions, but when the deck size never changes why would it stop working?

    Any help you can provide would be greatly appreciated. If you need any additional information, just let me know.

    Raymond

  4. #4
    I do not exactly understand what you are saying.. YOu have a 2 card deck, you deal x cards to the deck position... but even though it now shows in the moose over as a 6 card deck, you can only access the data of the original 2 card deck? is that right?

    Maybe post the save file to drop box or something so I can have a look at it.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  5. #5
    Yes that is exactly what is happening. The save file can be downloaded from http://thehackersguildboardgame.com/...S_Save_15.json

  6. #6
    sorry.. there is so much going on I do not know what to look at.. I sorta meant a file that just has the problem in it.. but anyway... if you explain EXACTLY what you want I could make a code snip you can copy paste if you like,
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  7. #7
    Thanks so much for your help so far, and sorry it has taken so long to get back to you. I've created a fresh setup with only a deck of cards and have managed to replicate the issue. Just for kicks I also verified that it doesn't matter how big the deck is to start with, the code only ever recognizes the original deck size. Replaced the previous save file with the new one.

  8. #8
    I'lltry and get a look at it before the weekend.
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  9. #9
    Perhaps the problem is that when you build the deck TTS doesn't assign unique GUIDS to the cards until they are pulled out of the deck. MrStump wrote a tool to fix decks like this, search for "duplicate deck" (without quotes) in the workshop.

  10. #10
    Ok... so the code you have is actually working as expected....

    In your script you put everything in Global ONLOAD so it run everytime you load the game... this could be a problem as if you need to ever use the "back arrow" keys to "undo" that is basically a "load" so this code will repeat.. you could simply move it to a button. This is why most mods have a "setup" button you click when ready.

    So you code has hard-coded the draw deck GUID and then has a Scripting Zone for where the cards are to be dealt. It then loops 4 times and deals 4 cards... As the mod starts with 6 cards on the table.. this ends up with a 10 card deck in the script zone. 4 Cards that were already there and then 4 other cards are dealt on the BOTTOM of them as you are using the positional data form the script zone to define the deal position.

    Then you count the cards in the deck but are only getting "6". This problem is as the code executes faster than it "moves" stuff about. So the count is occurring before the new cards are added.

    Code:
    function onload()
        makeButtons()
    end
    
    function SetUp_Button()
        function AutoLoadDeckofCards_core()
            deckOfCards = getObjectFromGUID("197bf3")
            newDeckofCardsZone = getObjectFromGUID("1f0810")
    
            deckOfCards.shuffle()
    
            local Y = 2
            for i=1, 4 do
                local params = {}
                params.position={newDeckofCardsZone.getPosition().x, Y, newDeckofCardsZone.getPosition().z}
                params.flipped = false
                deckOfCards.takeObject(params)
                Y = Y + 0.4
            end
    
            wait(1.2)
    
            for _, newDeckofCards in ipairs(getType(newDeckofCardsZone,'Deck')) do
                print(newDeckofCards.getQuantity())
            end
        return 1
        end
        startLuaCoroutine(self, 'AutoLoadDeckofCards_core')
    end
    
    function wait(time)
        local start = os.time()
        repeat coroutine.yield(0) until os.time() > start + time
    end
    
    function getType(zone, ...)
        local foundTypes, tagList = {}, {...}
    
        for _, object in ipairs(zone.getObjects()) do
            for _, tag in ipairs(tagList) do
                if object.tag == tag then
                    table.insert(foundTypes, object)
                    break
                end
            end
        end
    
        return foundTypes
    end
    
    function makeButtons(set)
        local buttons = {}
    
     -- DEFAULT START BUTTONS
        if set == nil then
            button_Name = {
                    click_function = 'SetUp_Button',
                    function_owner = self,
                    label = 'SetUp',
                    position = {0, 0.5, -0.8},
                    rotation = {0, 180, 0},
                    width = 1300,
                    height = 350,
                    font_size = 200}
            table.insert(buttons, button_Name)
        end
    
     -- Create Buttons
        for _, button in ipairs(buttons) do
            self.createButton(button)
        end
    end
    Here is a working version of your code.. I have changed this to a "button" for the reasons mentioned above.. but you can easily mod it to add it into your global if you would still like to.

    It works like this.. 1st, go to custom objects and drag out a single GO piece. Then right click on it and select LUA and copy all this code into the objects code. Reload and there should be a button and now it works.

    onLoad() - This is loading a function at the bottom of the script with button code to add a button to an object. The button code just sets values for how it looks, but the important one is the "click_function = 'SetUp_Button'," this is the function that triggers when ever you press the button.

    wait() - If you look down the code you see a function called "wait".... this is the wait code. Anytime you want to add a wait .. just put wait(3) and the code will kinda pause for whatever time you put in there .. so wait(5) will wait 5 seconds, wait(0.1) will wait 0.1 of a second.

    SetUp_Button() - This has been converted into a CORE ROUTINE. Core routines work a little differently but one of the cool things is that they allow you to use wait timers. You can not call the "wait()" function unless it is a core routine. So basically it is a function within a function... It basically looks like this...

    Code:
    function functionName()
        function functionName_CORE()
            --All your code in here, including wait(#) and other core functions
        return 1 -- You have to ALWAYS add this to break out of the cour reoutine.
        end
        startLuaCoroutine(self, 'functionName_CORE')
    end
    So.. all the normal function code goes into that nested function... of "SetUp_Button()".

    The code is nearly identical, but for two small changes. First there is a new local variable I have called "Y" set to a value of 2.. and now the positional data of where you are drawing the cards is only taking X and Z from the ScriptZone you are dealing to. The "Y" is replacing the vertical position.

    Code:
    params.position={newDeckofCardsZone.getPosition().x, Y, newDeckofCardsZone.getPosition().z}
    Now, every time it loops the number of specified times to draw a card it also increments the Y position...

    Code:
    Y = Y + 0.4
    What this dose is now the cards are dealt in order to the top of the original deck in a nice "moment" creating a small stacked pile with each card higher than the last, which then fall onto the original deck. As the 1st card is dealt to position 2 and each other card is always 0.4 higher than the last card dealt.

    Finally there is the wait(1.2) thing... before your print out. This is just a small pause in the scripting to make sure the counting code is not done befor all the cards settle into the deck.

    Your problem originally was 1), that the cards were being dealt "under" the original deck.. 2) the counter was trying to count before the deck was actually formed so at the time it counted it was still the original 6 card deck size.

    Many setup scripts also self destruct as well... you could add a wait (to make sure everything finishes) then do "self.destruct" to automatically delete the setup button object. Also you can add code to shuffle the new deck as well and stuff.

    EXAMPLE : https://screencast-o-matic.com/watch/cFe2hgD30r

    Hope this helps!
    My Boardgame uTube chan - Tragic's Table Top
    BGG Guild of BoardGame uTubers - Tube Tables

  11. #11
    Awesome - thanks for your help. Definitely makes sense and I learned something new as well which is always a good thing . I had run into issues with the rewinding time as you mentioned, so moving everything to a button makes a lot of sense so thanks for that as well. It is great to be a part of an awesome community like this one.

Similar Threads

  1. TTS Random DeviantArt Deck Creator
    By Mark in forum Original Content
    Replies: 11
    Last Post: 02-28-2018, 04:49 PM
  2. [SOLVED] Creating a Custom Deck
    By DaTuck in forum Technical Support
    Replies: 2
    Last Post: 06-24-2017, 06:04 AM
  3. [SUPPORT] Problem with creating custom deck
    By tungsten3200 in forum Technical Support
    Replies: 2
    Last Post: 01-14-2017, 10:00 AM
  4. Replies: 2
    Last Post: 07-07-2016, 05:15 PM
  5. Replies: 3
    Last Post: 06-02-2015, 07:57 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
  •