Results 1 to 21 of 21

Thread: Various questions (latest: scripted counter not working for others)

  1. #1

    Various questions (latest: scripted counter not working for others)

    I'm trying to make a simple script for a button that deals the community cards in a poker game, but I've noticed that takeObject takes from the bottom of the deck instead of the top (unless the deck is flipped over, but then everyone can see the bottom card). Is this how takeObject is intended to work? I expected it to take from the top, just like when you manually do so with the mouse. Is there any way to make it take from the top of the deck instead of the bottom?
    Last edited by Skorpion9x; 03-21-2016 at 07:17 AM.

  2. #2
    Join Date
    Feb 2016
    Location
    Sweden
    Posts
    77
    That's interesting.

    To do it you would have to use dealToColorWithOffset. You then either figure out the offset for where you want the card to be placed, or you use a coroutine to set the position of the card after 65-75ish frames, at least that's what worked for me.

    Here's a snippet for waiting several frames, call it from your coroutine.

    Code:
    function waitFrames(frames)
        for i=1, frames do
            coroutine.yield(0)
        end
    end


  3. #3
    Thank you very much. dealToColorWithOffset works perfectly.

  4. #4
    I had this issue too. The default position used for takeObject should really change to the top card, so it matches what a mouse swipe would do, and conforms with expectations. That means the actual position removed in the underlying array or list should vary according to the flip state of the deck, like it does for a mouse swipe.

    Dealing to a hand is okay if you want hands, but often you don't...

    takeObject should also allow a take-with-offset version. That would make shuffling a breeze.

  5. #5
    Join Date
    Jul 2015
    Posts
    159
    In the next patch, takeObject() for decks defaults to taking from the top of the deck (the side opposite of the table) regardless if the deck is flipped or not. There will also be an optional bool parameter for taking from the top or from the bottom of the deck (regardless which way the deck is facing). So whichever side of the deck is facing up is the top and whichever is facing down is the bottom.

    Quote Originally Posted by Arcuate View Post
    takeObject should also allow a take-with-offset version. That would make shuffling a breeze.
    takeObject() currently has a position and rotation parameter that you can use. If you want to move it to an offset from the player hand, use the getPlayerHandPositionAndRotation( string player_color ) function and use that for your position and rotation + whatever offset you need.

    For example, if you wanted to take a card and move 5 units in front of a player's hand and 4 units to the right (essentially recreating the functionality of dealToColorWithOffset), you would do something like:

    Code:
        local player_hand = getPlayerHandPositionAndRotation('White')
        local position = {}
        position['x'] = player_hand['pos_x'] + player_hand['trigger_forward_x'] * 5 + player_hand['trigger_right_x'] * 4
        position['y'] = player_hand['pos_y']
        position['z'] = player_hand['pos_z'] + player_hand['trigger_forward_z'] * 5 + player_hand['trigger_right_z'] * 4
    
        local params = {}
        params.position = {position.x, position.y, position.z}
        params.rotation = {0, player_hand['rot_y'], deck.getRotation().z}
        local card = deck.takeObject(params)
    Not sure what you mean by making shuffling easier since there's already a shuffle() function for decks.
    Last edited by Dan K; 03-14-2016 at 06:10 PM. Reason: If you don't set the z rotation to the deck's z, it could flip the card.

  6. #6
    Join Date
    Feb 2016
    Location
    Sweden
    Posts
    77
    Quote Originally Posted by Dan K View Post
    Not sure what you mean by making shuffling easier since there's already a shuffle() function for decks.
    Some people started making their own shuffle functions because they felt the shuffle() function was inadequate, something I haven't encountered, but the shuffle algorithm isn't perfect so I wouldn't be surprised if it was an actual issue. Thread here

  7. #7
    Just to clarify... the idea is to pull a card from a random offset within the deck to increase the chances of getting non-sequential cards that seem to be occurring with the current shuffle algorithm. I'll butt out now.

  8. #8
    Yes, sorry, I should have been more explicit. I meant taking a card with an offset within the deck, counting from the top of the deck, as in take the second card, or the third card, or the nth card. I already know that the card can be put anywhere... We were talking about how to get the right card. "Offset" is probably a poor choice of word given that it has a different meaning in the other function mentioned in this thread, dealToColorWithOffset.

    Like some others, I have had doubts about the adequacy of the existing shuffle function. If it were possible to grab the nth card, then shuffling with the default shuffle() function could be supplemented or bypassed, by grabbing a random card.

    Apart from the shuffle function, and not being able to grab reliably from a particular position, there are a number of other issues raised by the current deck API, and after a brief foray into scripting I already have a long list of things I wish scripters could do with decks. I'll post a list of these in another thread.

  9. #9
    I think I'll just use this thread to ask all of my questions instead of making a new thread each time I run into a problem, so here is my current problem. I'm working on a script for Mahjong this time. For some reason, the array "tile_array" is not being populated in the following code, and I have no idea why. I added the line "print (v.getVar())" to the loop, and it does indeed print several lines of "tile" to the chat window. I also tried using single quotes around "tile" in the if statement (I'm not yet entirely sure when to use single and double quotes), but still no luck. If I comment out the if statement, things get very chaotic when I click the button which calls this function, so I'm pretty sure that's where the problem is.

    Code:
    function resetTiles()
    
        tile_array = {} -- clear the tile array
    
        local array = getAllObjects()
    
        for i, v in ipairs (array) do 
    
            print (v.getVar('type'))
            
            if v.getVar('type') == "tile" then
                tile_array[i] = getObjectFromGUID(v.getGUID())
            end
    
        end
    
        for i, v in ipairs (tile_array) do
            print (v)
        end
    
        	local pos = tile_bag.getPosition()
        
        	for i, v in ipairs (tile_array) do
            pos[2] = 4+i
            v.setPositionSmooth(pos)
        end
    
    end

  10. #10
    I think you need a separate index counter for 'tile_array'. As is, your first loop is leaving nil entries in 'tile_array' for every value of 'i' in 'array' that do not equal 'tile' that I'm sure are giving you errors. Code changes below...
    Code:
    function resetTiles()
    
        tile_array = {} -- clear the tile array
    
        local array = getAllObjects()
    
        local indx = 1
        for i, v in ipairs (array) do 
    
            print (v.getVar('type'))
            
            if v.getVar('type') == "tile" then
                tile_array[indx] = getObjectFromGUID(v.getGUID())
                indx = indx + 1
            end
    
        end
    
        for i, v in ipairs (tile_array) do
            print (v)
        end
    
        	local pos = tile_bag.getPosition()
        
        	for i, v in ipairs (tile_array) do
            pos[2] = 4+i
            v.setPositionSmooth(pos)
        end
    
    end

  11. #11
    Oh wow, I totally missed that. Works perfectly now. Thank you so much!

    Back to my poker table, now. I've been having an issue that seems to be script-related, but I don't see how my script could be causing it. When I have a public game, and the script is running, I have been having issues with players who sit down at the table, and then their name disappears from the table, and they do not receive cards when I deal. If I change their color back to that which they selected, it might fix it, but then it happens again after a few seconds, or they stop appearing in the seat altogether. And then their name appears multiple times in the player list. It specifically seems to be happening with the blue and red seats, and I think it may have happened with pink as well. I always end up having to rehost the table with scripts disabled and deal manually ;_;. Here's a copy of the script I wrote: http://pastebin.com/CbREnVWk .

  12. #12
    Join Date
    Jul 2015
    Posts
    159
    Quote Originally Posted by Skorpion9x View Post
    Back to my poker table, now. I've been having an issue that seems to be script-related, but I don't see how my script could be causing it. When I have a public game, and the script is running, I have been having issues with players who sit down at the table, and then their name disappears from the table, and they do not receive cards when I deal. If I change their color back to that which they selected, it might fix it, but then it happens again after a few seconds, or they stop appearing in the seat altogether. And then their name appears multiple times in the player list. It specifically seems to be happening with the blue and red seats, and I think it may have happened with pink as well. I always end up having to rehost the table with scripts disabled and deal manually ;_;. Here's a copy of the script I wrote: http://pastebin.com/CbREnVWk .
    Are you calling getSeatedPlayers() by chance? There is a bug in the live version where calling that can clobber the real in-game player list. It's fixed for the next patch.

    Also, for previous conversation, decks can takeCard with a specified index in the next patch.

  13. #13
    Quote Originally Posted by Dan K View Post
    Are you calling getSeatedPlayers() by chance? There is a bug in the live version where calling that can clobber the real in-game player list. It's fixed for the next patch.

    Also, for previous conversation, decks can takeCard with a specified index in the next patch.
    Yes, I'm calling getSeatedPlayers() every time I deal a new game. I'm glad to hear that it will be fixed in the next patch!

  14. #14
    I'm having a problem with a score-updating function. I call the update function when an object enters or leaves a scripting zone, but it's updating the score to what it was before the object entered or left rather than after. For example, if I put only a 1000 point "tenbo" (score sticks used in mahjong) into the zone, the counter says "0." Then when I take it out, it says "10" (I divide the score by 100 because the counters don't have enough digits for scores above 10000). It's the same when I put into or take out of the zone any combination of tenbo - it always displays the score as it should have before the action occurred rather than after.

    Code:
    function onObjectEnterScriptingZone(zone, object)
        if object.getVar('type') == "tenbo" then
            updateScore(zone)
        end
    end
    
    function onObjectLeaveScriptingZone(zone, object)
        if object.getVar('type') == "tenbo" then
            updateScore(zone)
        end
    end
    
    function updateScore(zone)
    
        local objects = {}
        local score = 0
    
        for i, v in ipairs (tenbo_zones) do 
            if zone == v then
                objects = v.getObjects()
                for j, w in ipairs (objects) do
                    if w.getVar('type') == "tenbo" then
                        score = score + w.getVar('value')
                    end
                end
    			            score = score/100
                counters[i].setValue(score)
                break
            end    
        end
    end

  15. #15
    A thought... you may have to wait for the movement of the tembo to finalize before your tally loop will be able to find it in the right place. I use coroutines with yields for a few frames to handle these situations.

  16. #16
    I thought that might be the case. I have to wait one frame before the object will be counted as one of the objects in the zone. I actually tried doing that before I posted previously, but I was doing it wrong (still new to this). It seems I have to do all the calculations within the coroutine after waiting one frame. But there's one thing I don't like about that: I don't think I can send parameters to a coroutine (correct me if I'm wrong), so I have to do the calculations for all zones instead of just the one that was entered or left, and that just seems really inefficient.

    Code I came up with for that:
    Code:
    function onObjectEnterScriptingZone(zone, object)
        if object.getVar('type') == "tenbo" then
            updateScore()
        end
    end
    
    function onObjectLeaveScriptingZone(zone, object)
        if object.getVar('type') == "tenbo" then
            updateScore()
        end
    end
    
    function updateScore()
    
        startLuaCoroutine(nil, 'updateScoreCoroutine')
    	
    end
    
    function updateScoreCoroutine()
    
        local objects = {}
    
        coroutine.yield()
        
        for i, v in ipairs (tenbo_zones) do
            player_scores[i] = 0
            objects = {}
            objects = v.getObjects()
            for j, w in ipairs (objects) do
                if w.getVar('type') == "tenbo" then
                    player_scores[i] = player_scores[i] + w.getVar('value')
                end
            end
            counters[i].setValue(player_scores[i]/100)
        end
            
        return 1
    
    end
    And then I got the idea to just consider that the object won't be included in getObjects(), and to just manually add or subtract it to the calculation, so I can avoid waiting a frame altogether. Does this sound like a better way to do it?

    Code:
    function onObjectEnterScriptingZone(zone, object)
        if object.getVar('type') == "tenbo" then
            updateScore(zone, object.getVar('value'))
        end
    end
    
    function onObjectLeaveScriptingZone(zone, object)
        if object.getVar('type') == "tenbo" then
            updateScore(zone, -object.getVar('value'))
        end
    end
    
    function updateScore(zone, score)
    
        local objects = {}
        
        for i, v in ipairs (tenbo_zones) do 
            if zone == v then
                objects = v.getObjects()
                for j, w in ipairs (objects) do
                    if w.getVar('type') == "tenbo" then
                        score = score + w.getVar('value')
                    end
                    player_scores[i] = score
                end
                counters[i].setValue(player_scores[i]/100)
                break
            end    
        end
    	    
    end

  17. #17
    I can't think of a reason why you couldn't do the manual add/subtract unless future releases change the scripting zone behaviors (unlikely)

    But you can pass parameters to a coroutine.

    Code:
        -- initialize parameters
        myinfo = {param1 = 'x'. param2 = 'z'}
    
        -- push parameters onto a queue
        Queue.pushright(queuename, myinfo)
    
        -- launch the coroutine
        startLuaCoroutine(nil, coroutinename)
    end
    
    function coroutinename()
        for c = 1, 2 do     -- wait for 2 frames
            coroutine.yield(0)
        end
    
        local info = {}
        info = Queue.popleft(queuename)
    
        -- extract the params from the table
        var1 = info.param1
        var2 = info.param2
    Then you need the functions below somewhere in Global and Queue.new gets called in onload() like...

    Code:
    function onload()
        queuename = Queue.new()
    end
    
    Queue = {}
    function Queue.new ()
        return {first = 0, last = -1}
    end
    
    function Queue.pushright (queue, value)
        local last = queue.last + 1
        queue.last = last
        queue[last] = value
    end
    
    function Queue.popleft (queue)
        local first = queue.first
        if first > queue.last then
            error("queue is empty")
        end
        local value = queue[first]
        queue[first] = nil
        queue.first = first + 1
        return value
    end
    Hope that's understandable...

  18. #18
    Thanks for that explanation, and all the other help. I really appreciate it.

    I invited some friends to test the script last night, and it turned out that they couldn't see the values change on the counters like I could. There was a bug with counters in 6.7, but it was fixed in 6.8. I didn't think to try manually changing the counter to see if they could see that, and if it's just a bug with scripted counters.

    Another thing that happened was that only promoted players could click on Lua buttons. The patch notes mentioned that spectators could no longer click on buttons, but not seated players. This is a welcome change (bug?) for my poker table as I sometimes had trolls join and click the button to deal cards prematurely. But for my mahjong script, I would like all players to be able to click the buttons. Then again, since I play mahjong with close friends rather than random people, it's not really a problem for me to promote them.

  19. #19
    Join Date
    Jul 2015
    Posts
    159
    Quote Originally Posted by Skorpion9x View Post
    I invited some friends to test the script last night, and it turned out that they couldn't see the values change on the counters like I could. There was a bug with counters in 6.7, but it was fixed in 6.8. I didn't think to try manually changing the counter to see if they could see that, and if it's just a bug with scripted counters.
    The setValue() function wasn't synchronizing across the network (increment() and decrement() were though). This is fixed in the next patch. Thanks!

    Quote Originally Posted by Skorpion9x View Post
    Another thing that happened was that only promoted players could click on Lua buttons. The patch notes mentioned that spectators could no longer click on buttons, but not seated players. This is a welcome change (bug?) for my poker table as I sometimes had trolls join and click the button to deal cards prematurely. But for my mahjong script, I would like all players to be able to click the buttons. Then again, since I play mahjong with close friends rather than random people, it's not really a problem for me to promote them.
    This was fixed on the Unity 5 beta in one of the hotfixes (it was incorrectly tied to the digital permission). For the Unity 4 branch try this:

    Quote Originally Posted by Knil View Post
    Enable the permission digital on the host options menu and your buttons will work for non promoted players.

  20. #20
    Quote Originally Posted by Skorpion9x View Post

    I invited some friends to test the script last night, and it turned out that they couldn't see the values change on the counters like I could. There was a bug with counters in 6.7, but it was fixed in 6.8. I didn't think to try manually changing the counter to see if they could see that, and if it's just a bug with scripted counters.
    Quote Originally Posted by Dan K View Post
    The setValue() function wasn't synchronizing across the network (increment() and decrement() were though). This is fixed in the next patch. Thanks!
    You can use this to your advantage. setValue with 1 extra and then decrement and you get the value you want.

    Code:
    		year_counter.Counter.setValue(year+1)
    		year_counter.Counter.decrement()

  21. #21
    I actually tried that the other day - I added an increment and decrement at the end of the function. I didn't expect it to actually work, but it did when I tested it.

Posting Permissions

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