From 6eaf9f13e185c6c4b549d0f5be6d7f5764a79253 Mon Sep 17 00:00:00 2001 From: canonelis <86532940+Canonelis@users.noreply.github.com> Date: Mon, 13 Dec 2021 07:52:53 -0500 Subject: [PATCH 1/9] fix deleting all containers that have objects put into them -in onObjectEnterContainer only delete the container if a codenames card was put in it -use isDestroyed() object property for a cleaner way to see if this has been run already(it returns true if the object is about to be but is not yet destroyed) -created dealCardsDelayed() function which can be called many times per second, but will only run dealCards() once 1.5s have passed without any further calls to dealCardsDelayed() -created onObjectDestroy() which re-deals cards if a game is being played and a codenames card is deleted and no other cards have been deleted in the past 1.5 seconds --- src/Global.-1.ttslua | 41 +++++++++++++++++++++++++++++++++++------ 1 file changed, 35 insertions(+), 6 deletions(-) diff --git a/src/Global.-1.ttslua b/src/Global.-1.ttslua index 65d6c30..4bad925 100644 --- a/src/Global.-1.ttslua +++ b/src/Global.-1.ttslua @@ -730,11 +730,31 @@ function encodeClue(color, clue) end end -function onObjectEnterContainer(deck, card) - -- First to check that we only do this on the first grouping - if #deck.getObjects() == 2 then - deck.destruct() - Wait.frames(function() dealCards() end, 180) +function isCodenamesCard(obj) + if obj.type == "Card" then + vals = obj.getCustomObject() + if vals.face != nil and string.find(vals.face,"codenames")then + return true + end + end + return false +end + +function onObjectEnterContainer(container, object) + -- if the displaced object is a codenames card then delete the container and refresh the cards + if isCodenamesCard(object) then + -- Check whether container is being destroyed so we only do this once for multiple deposited objects + if not container.isDestroyed() then + container.destruct() + dealCardsDelayed() + end + end +end + +function onObjectDestroy(obj) + -- if there is an ongoing game and a card is deleted then refresh the cards + if gameState.status == 1 and isCodenamesCard(obj) then + dealCardsDelayed() end end @@ -997,6 +1017,14 @@ function setupGame() gameState.firstTurn = true end +dealCards_WaitId = nil +function dealCardsDelayed() + if dealCards_WaitId != nil then + Wait.stop(dealCards_WaitId) + end + dealCards_WaitId = Wait.time(dealCards,1.5,1) +end + -- Deals the cards on the board function dealCards() for i = 1, 25, 1 do @@ -2004,4 +2032,5 @@ function api_playerSessionEndCB(responseRaw) analytics.sessions[steamID] = nil end end -end \ No newline at end of file +end + From e4cfa7067513d15dae3d7bd313671b69e16f435b Mon Sep 17 00:00:00 2001 From: canonelis <86532940+Canonelis@users.noreply.github.com> Date: Mon, 13 Dec 2021 09:01:29 -0500 Subject: [PATCH 2/9] update code for deprecated tags property "tag" has been replaced with "type" and contains the same data --- src/Global.-1.ttslua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Global.-1.ttslua b/src/Global.-1.ttslua index 4bad925..fdbe9c9 100644 --- a/src/Global.-1.ttslua +++ b/src/Global.-1.ttslua @@ -1091,7 +1091,7 @@ end function onObjectDrop(color, agent) -- Ensure that the dropped object is an agent card - if gameState.status ~= 1 or agent.tag ~= "Tile" or agents[agent.guid] == nil then + if gameState.status ~= 1 or agent.type ~= "Tile" or agents[agent.guid] == nil then return end @@ -1426,7 +1426,7 @@ end function onObjectPickUp(color, object) -- Clues - if object.tag == "Card" and not object.spawning then + if object.type == "Card" and not object.spawning then for i = 1, 25, 1 do if cards[i].guid == object.guid then object.setVelocity({0, 0, 0}) From d123b66d5cb4a36ea45e0f16f593052714b70055 Mon Sep 17 00:00:00 2001 From: canonelis <86532940+Canonelis@users.noreply.github.com> Date: Mon, 13 Dec 2021 09:31:55 -0500 Subject: [PATCH 3/9] when force-dropping objects make them more still -Wherever we set the position I set the rotation as well(except for when picking up pre-rotated cards) -Wherever we pick up or drop cards, I set the angular velocity to 0 --- src/Global.-1.ttslua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Global.-1.ttslua b/src/Global.-1.ttslua index fdbe9c9..8a2934f 100644 --- a/src/Global.-1.ttslua +++ b/src/Global.-1.ttslua @@ -996,6 +996,7 @@ function setupGame() -- Set the correct double card to red extraCard.setLock(false) + extraCard.setRotation({0, 180, 180}) extraCard.setPositionSmooth(agents[extraCard.guid].position) extraCard.interactable = true agents[extraCard.guid].enabled = true @@ -1099,6 +1100,9 @@ function onObjectDrop(color, agent) local cardIndex = findClosestCard(1.65, agent.getPosition()) if cardIndex == nil or cards[cardIndex].covered then -- Either no close card found, or card is already covered + agent.setAngularVelocity({0, 0, 0}) + agent.setVelocity({0, 0, 0}) + agent.setRotation({0, 180, 180}) agent.setPositionSmooth(agents[agent.guid].position) return end @@ -1107,6 +1111,9 @@ function onObjectDrop(color, agent) local agentColor = agents[agent.guid].color local cardColor = cards[cardIndex].color if cardColor ~= agentColor then + agent.setAngularVelocity({0, 0, 0}) + agent.setVelocity({0, 0, 0}) + agent.setRotation({0, 180, 180}) agent.setPositionSmooth(agents[agent.guid].position) Player[color].broadcast("[a020f0]» [da1918]ERROR: [ffffff]An agent has been placed incorrectly. You placed a " .. agentColor .. " agent on a " .. cardColor .. " card. [a020f0]«") return @@ -1429,6 +1436,7 @@ function onObjectPickUp(color, object) if object.type == "Card" and not object.spawning then for i = 1, 25, 1 do if cards[i].guid == object.guid then + object.setAngularVelocity({0, 0, 0}) object.setVelocity({0, 0, 0}) object.drop() object.setPosition({cards[i].position.x, 1.03, cards[i].position.z}) @@ -1441,8 +1449,10 @@ function onObjectPickUp(color, object) elseif agents[object.guid] ~= nil then -- Prevent picking up of agent tiles from anyone but red or blue if color ~= "Red" and color ~= "Blue" then + object.setAngularVelocity({0, 0, 0}) object.setVelocity({0, 0, 0}) object.drop() + object.setRotation({0, 180, 180}) object.setPosition({agents[object.guid].position.x, 1.01, agents[object.guid].position.z}) end end From 1afe699c9563d759220edd1545a9b7cf0b6a0d8f Mon Sep 17 00:00:00 2001 From: canonelis <86532940+Canonelis@users.noreply.github.com> Date: Mon, 13 Dec 2021 09:32:52 -0500 Subject: [PATCH 4/9] remove unused "rotateclues" function remove unused "rotateclues" function --- src/Global.-1.ttslua | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Global.-1.ttslua b/src/Global.-1.ttslua index 8a2934f..2ab691e 100644 --- a/src/Global.-1.ttslua +++ b/src/Global.-1.ttslua @@ -659,15 +659,6 @@ function getClueDetails(processedClue) end end -function rotateclues() - for cardIndex, cardData in ipairs(cards) do - local card = getObjectFromGUID(cardData.guid) - if card.interactable then - card.setRotation({0, 180, 0}) - end - end -end - function encodeClue(color, clue) local finishedClue local cluePosition From a4e82a9c9795ff6cfd41101bcd37a7a824f5e6c9 Mon Sep 17 00:00:00 2001 From: canonelis <86532940+Canonelis@users.noreply.github.com> Date: Mon, 13 Dec 2021 10:33:25 -0500 Subject: [PATCH 5/9] Migrated onPlayerPickup and onObjectDestroy to onPlayerAction function -to prevent onObjectDestroy from being called due to the script deleting something, use the onPlayerAction function to detect deletions -move onPlayerPickup voting mechanism to onPlayerAction so that the card doesn't move slightly whenever someone votes -when transferring host after a game has ended, the current cards become blank and need to be deleted based on their face image URL when dealing out cards --- src/Global.-1.ttslua | 65 ++++++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 35 deletions(-) diff --git a/src/Global.-1.ttslua b/src/Global.-1.ttslua index 2ab691e..8149630 100644 --- a/src/Global.-1.ttslua +++ b/src/Global.-1.ttslua @@ -742,13 +742,6 @@ function onObjectEnterContainer(container, object) end end -function onObjectDestroy(obj) - -- if there is an ongoing game and a card is deleted then refresh the cards - if gameState.status == 1 and isCodenamesCard(obj) then - dealCardsDelayed() - end -end - function onPlayerConnect(player) -- Send analytics disclaimer player.print(chatDisclaimer, {1, 1, 1}) @@ -1019,6 +1012,12 @@ end -- Deals the cards on the board function dealCards() + -- check all objects to delete unused codenames cards + for _, obj in pairs(getObjects()) do + if isCodenamesCard(obj) and not isCard(obj.guid) then + obj.destruct() + end + end for i = 1, 25, 1 do local cardObject = getObjectFromGUID(cards[i].guid) if cards[i].guid == nil or cardObject == nil then @@ -1422,33 +1421,6 @@ function votePass(color) playerVote(color, 26) end -function onObjectPickUp(color, object) - -- Clues - if object.type == "Card" and not object.spawning then - for i = 1, 25, 1 do - if cards[i].guid == object.guid then - object.setAngularVelocity({0, 0, 0}) - object.setVelocity({0, 0, 0}) - object.drop() - object.setPosition({cards[i].position.x, 1.03, cards[i].position.z}) - if #Player[color].getSelectedObjects() <= 1 then - playerVote(color, i) - end - break - end - end - elseif agents[object.guid] ~= nil then - -- Prevent picking up of agent tiles from anyone but red or blue - if color ~= "Red" and color ~= "Blue" then - object.setAngularVelocity({0, 0, 0}) - object.setVelocity({0, 0, 0}) - object.drop() - object.setRotation({0, 180, 180}) - object.setPosition({agents[object.guid].position.x, 1.01, agents[object.guid].position.z}) - end - end -end - function onPlayerAction(player, action, objects) local processAction = false local actionsToProcess = { @@ -1458,7 +1430,8 @@ function onPlayerAction(player, action, objects) Player.Action.RotateOver, Player.Action.FlipIncrementalLeft, Player.Action.FlipIncrementalRight, - Player.Action.FlipOver + Player.Action.FlipOver, + Player.Action.Delete } for _, handledAction in ipairs(actionsToProcess) do @@ -1471,6 +1444,17 @@ function onPlayerAction(player, action, objects) if not processAction then return end + + if action == Player.Action.Delete then + -- if there is an ongoing game and a card is deleted then refresh the cards + for _, obj in pairs(objects) do + if gameState.status == 1 and isCodenamesCard(obj) then + dealCardsDelayed() + break + end + end + return + end local objectIncludesCard = false local objectIncludesAgent = false @@ -1504,6 +1488,17 @@ function onPlayerAction(player, action, objects) elseif settings.cardTilting and gameState.status == 1 and not gameState.canVote then errorMessage = "[a020f0]» [da1918]ERROR: [ffffff]You can't vote until you've been given a clue! [a020f0]«" end + if #objects == 1 and objects[1].type == "Card" and not objects[1].spawning then + object = objects[1] + for i = 1, 25, 1 do + if cards[i].guid == object.guid then + if #player.getSelectedObjects() <= 1 then + playerVote(player.color, i) + end + return false + end + end + end elseif action == Player.Action.RotateIncrementalLeft or action == Player.Action.RotateIncrementalRight or action == Player.Action.RotateOver then if objectIncludesCard and not isPlayerTurn then errorMessage = "[a020f0]» [da1918]ERROR: [ffffff]You can't tilt cards when it's not your turn! [a020f0]«" From d052236abe180e186233a74fe317b8e962db22d3 Mon Sep 17 00:00:00 2001 From: canonelis <86532940+Canonelis@users.noreply.github.com> Date: Mon, 13 Dec 2021 12:18:26 -0500 Subject: [PATCH 6/9] clean up all clue tiles when resetting game clue tiles are very distinct, so delete them based on their properties when starting a new game. since the list of clue tiles isn't saved when the game is reloaded, this guarantees they are removed upon reset --- src/Global.-1.ttslua | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/src/Global.-1.ttslua b/src/Global.-1.ttslua index 8149630..77138c7 100644 --- a/src/Global.-1.ttslua +++ b/src/Global.-1.ttslua @@ -731,6 +731,16 @@ function isCodenamesCard(obj) return false end +function isCodenamesClue(obj) + if obj.type == "Board" then + butts = obj.getButtons() + if butts != nil and #butts == 2 and butts[1].click_function == "clue" and butts[2].click_function == "nullFunction" then + return true + end + end + return false +end + function onObjectEnterContainer(container, object) -- if the displaced object is a codenames card then delete the container and refresh the cards if isCodenamesCard(object) then @@ -928,12 +938,9 @@ function resetGame() end -- Delete clue tiles - for _, clueList in ipairs({gameState.redClues, gameState.blueClues}) do - for _, clue in ipairs(clueList) do - local clueTile = getObjectFromGUID(clue) - if clueTile then - clueTile.destruct() - end + for _, obj in pairs(getObjects()) do + if isCodenamesClue(obj) then + obj.destruct() end end @@ -1449,11 +1456,18 @@ function onPlayerAction(player, action, objects) -- if there is an ongoing game and a card is deleted then refresh the cards for _, obj in pairs(objects) do if gameState.status == 1 and isCodenamesCard(obj) then + -- Delete word cards and refresh them dealCardsDelayed() - break + obj.destruct() + elseif agents[obj.guid] ~= nil then + -- Do not delete any agents + else + -- Delete any other objects in the action + obj.destruct() end end - return + -- Prevent deletion of selected objects as we have already delete only what was allowed + return false end local objectIncludesCard = false From aae2ba865d90692d9df99fa203bc2e5d7e5e50a3 Mon Sep 17 00:00:00 2001 From: canonelis <86532940+Canonelis@users.noreply.github.com> Date: Mon, 13 Dec 2021 13:11:45 -0500 Subject: [PATCH 7/9] do not allow picking up word cards at all do not allow picking up word cards at all --- src/Global.-1.ttslua | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Global.-1.ttslua b/src/Global.-1.ttslua index 77138c7..8a328ed 100644 --- a/src/Global.-1.ttslua +++ b/src/Global.-1.ttslua @@ -1513,6 +1513,16 @@ function onPlayerAction(player, action, objects) end end end + local hasCards = false + for _, obj in pairs(objects) do + if isCard(obj.guid) then + obj.removeFromPlayerSelection(player.color) + hasCards = true + end + end + if hasCards then + return false + end elseif action == Player.Action.RotateIncrementalLeft or action == Player.Action.RotateIncrementalRight or action == Player.Action.RotateOver then if objectIncludesCard and not isPlayerTurn then errorMessage = "[a020f0]» [da1918]ERROR: [ffffff]You can't tilt cards when it's not your turn! [a020f0]«" From d8d5cc3807dd627b89ea12fba79eac3ac01a3b28 Mon Sep 17 00:00:00 2001 From: canonelis <86532940+Canonelis@users.noreply.github.com> Date: Tue, 25 Jan 2022 15:11:07 -0500 Subject: [PATCH 8/9] Change detection of clue Change detection of clue --- src/Global.-1.ttslua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Global.-1.ttslua b/src/Global.-1.ttslua index 8a328ed..62752d1 100644 --- a/src/Global.-1.ttslua +++ b/src/Global.-1.ttslua @@ -734,7 +734,7 @@ end function isCodenamesClue(obj) if obj.type == "Board" then butts = obj.getButtons() - if butts != nil and #butts == 2 and butts[1].click_function == "clue" and butts[2].click_function == "nullFunction" then + if butts != nil and (#butts == 1 and butts[1].click_function == "nullFunction" or #butts == 2 and butts[1].click_function == "clue") and butts[1].scale == Vector(2, 2, 1.3333) and butts[1].position == Vector(0,0.2,0) then return true end end From aba0370451f5a6a5b3c3377c8fb53308f4a55aea Mon Sep 17 00:00:00 2001 From: canonelis <86532940+Canonelis@users.noreply.github.com> Date: Mon, 31 Jan 2022 02:04:38 -0500 Subject: [PATCH 9/9] add longer delay for deck respawning add longer delay for deck respawning --- src/Global.-1.ttslua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Global.-1.ttslua b/src/Global.-1.ttslua index 62752d1..f625359 100644 --- a/src/Global.-1.ttslua +++ b/src/Global.-1.ttslua @@ -1013,8 +1013,9 @@ dealCards_WaitId = nil function dealCardsDelayed() if dealCards_WaitId != nil then Wait.stop(dealCards_WaitId) + dealCards_WaitId = nil end - dealCards_WaitId = Wait.time(dealCards,1.5,1) + dealCards_WaitId = Wait.time(dealCards,2.5,1) end -- Deals the cards on the board