From d61e9d1438c4f931f3d8a2006d2b1229e85df2c5 Mon Sep 17 00:00:00 2001 From: dscarpac Date: Tue, 17 Feb 2026 23:57:13 -0600 Subject: [PATCH 1/3] borrowed time helper --- .../BorrowedTime3.0db666.json | 8 ++- src/Global/i18nData.ttslua | 13 ++++ src/playercards/cards/BorrowedTime.ttslua | 68 +++++++++++++++++++ xml/playercards/BorrowedTime.xml | 16 +++++ 4 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 src/playercards/cards/BorrowedTime.ttslua create mode 100644 xml/playercards/BorrowedTime.xml diff --git a/objects/AllPlayerCards.15bb07/BorrowedTime3.0db666.json b/objects/AllPlayerCards.15bb07/BorrowedTime3.0db666.json index 7ddc72b78..24a76f1ea 100644 --- a/objects/AllPlayerCards.15bb07/BorrowedTime3.0db666.json +++ b/objects/AllPlayerCards.15bb07/BorrowedTime3.0db666.json @@ -33,7 +33,7 @@ "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": false, - "LuaScript": "", + "LuaScript": "require(\"playercards/cards/BorrowedTime\")", "LuaScriptState": "", "MeasureMovement": false, "Name": "Card", @@ -43,7 +43,9 @@ "Sticky": true, "Tags": [ "Asset", - "PlayerCard" + "PlayerCard", + "CardWithHelper", + "i18n_XML" ], "Tooltip": true, "Transform": { @@ -58,5 +60,5 @@ "scaleZ": 1 }, "Value": 0, - "XmlUI": "" + "XmlUI": "\u003cInclude src=\"playercards/BorrowedTime.xml\"/\u003e" } diff --git a/src/Global/i18nData.ttslua b/src/Global/i18nData.ttslua index 1475efafe..cd68f7c2d 100644 --- a/src/Global/i18nData.ttslua +++ b/src/Global/i18nData.ttslua @@ -67,6 +67,19 @@ I18N_DATA = { ["zh_CN"] = "选项", ["zh_TW"] = "選項", }, + ["CARD_BorrowedTime_remove_text"] = { + ["de"] = "Remove clicks", + ["en"] = "Remove clicks", + ["es"] = "Remove clicks", + ["fr"] = "Remove clicks", + ["it"] = "Remove clicks", + ["ko"] = "Remove clicks", + ["nl"] = "Remove clicks", + ["pt"] = "Remove clicks", + ["ru"] = "Remove clicks", + ["zh_CN"] = "Remove clicks", + ["zh_TW"] = "Remove clicks", + }, ["CARD_DarkHorse_text"] = { ["de"] = "☐ Keine Ressource", ["en"] = "☐ Skip resource", diff --git a/src/playercards/cards/BorrowedTime.ttslua b/src/playercards/cards/BorrowedTime.ttslua new file mode 100644 index 000000000..db51bd26b --- /dev/null +++ b/src/playercards/cards/BorrowedTime.ttslua @@ -0,0 +1,68 @@ +require("playercards/CardsWithHelper") +local SearchLib = require("util/SearchLib") +local TokenManagerApi = require("tokens/TokenManagerApi") + +-- intentionally global +hasXML = true +isHelperEnabled = false + +function updateSave() + self.script_state = JSON.encode({ isHelperEnabled = isHelperEnabled }) +end + +function onLoad(savedData) + if savedData and savedData ~= "" then + local loadedData = JSON.decode(savedData) + isHelperEnabled = loadedData.isHelperEnabled + if isHelperEnabled then updateDisplay() end + end +end + +function searchSelfForTokens() + clickableResourceCounter = nil + local foundTokens = 0 + + for _, obj in ipairs(SearchLib.onObject(self, "isTileOrToken", 0.8)) do + local memo = obj.getMemo() + if memo == "click" or memo == "resource" then + foundTokens = foundTokens + math.abs(obj.getQuantity()) + elseif memo == "resourceCounter" then + foundTokens = obj.getVar("val") + clickableResourceCounter = obj + break + end + end + return foundTokens +end + +function removeClicks(player) + local foundTokens = searchSelfForTokens() + + if clickableResourceCounter then + clickableResourceCounter.call("updateVal", 0) + else + for _, obj in ipairs(SearchLib.onObject(self, "isTileOrToken", 0.8)) do + local memo = obj.getMemo() + if memo == "click" or memo == "resource" then + obj.destruct() + end + end + end + if foundTokens > 0 then + addAction(player, foundTokens) + else + broadcastToColor("No clicks found!", player.color) + end +end + +function addAction(player, foundTokens) + -- only spawn a maximum of 3 action tokens + if foundTokens > 3 then + numTokens = 3 + else + numTokens = foundTokens + end + + TokenManagerApi.spawnTokenGroup(self, "universalActionAbility", numTokens, 1.3, nil, true) + broadcastToColor("Spawning " .. numTokens.." temporary action token(s).", player.color) +end diff --git a/xml/playercards/BorrowedTime.xml b/xml/playercards/BorrowedTime.xml new file mode 100644 index 000000000..dd99550d5 --- /dev/null +++ b/xml/playercards/BorrowedTime.xml @@ -0,0 +1,16 @@ + From 324c109660c53312d84d2cc8f9f2de13e462ebd1 Mon Sep 17 00:00:00 2001 From: dscarpac Date: Wed, 18 Feb 2026 00:04:22 -0600 Subject: [PATCH 2/3] lowered button position --- xml/playercards/BorrowedTime.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xml/playercards/BorrowedTime.xml b/xml/playercards/BorrowedTime.xml index dd99550d5..b370d091f 100644 --- a/xml/playercards/BorrowedTime.xml +++ b/xml/playercards/BorrowedTime.xml @@ -4,7 +4,7 @@ width="1200" rotation="0 0 180" scale="0.1 0.1 1" - position="0 120 -40" + position="0 128 -40" padding="50" onClick="removeClicks" color="#AA1C0080"> From c652ac2bc1706fcfb8a75c32ae7c2894691d7dc6 Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Fri, 27 Feb 2026 15:17:27 +0100 Subject: [PATCH 3/3] update token spawn size / position --- src/Global/Global.ttslua | 8 ++++++ src/playercards/cards/BorrowedTime.ttslua | 35 +++++++++++++++++------ 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/src/Global/Global.ttslua b/src/Global/Global.ttslua index 607a47f8b..20140bded 100644 --- a/src/Global/Global.ttslua +++ b/src/Global/Global.ttslua @@ -5121,6 +5121,14 @@ function addUseName(obj, params) end end +function multiplyScale(obj, mult) + Wait.frames(function() + if obj ~= nil then + obj.setScale(obj.getScale():scale(Vector(mult, 1, mult))) + end + end, 5) +end + --------------------------------------------------------- -- Utility functions --------------------------------------------------------- diff --git a/src/playercards/cards/BorrowedTime.ttslua b/src/playercards/cards/BorrowedTime.ttslua index db51bd26b..7f04ab78b 100644 --- a/src/playercards/cards/BorrowedTime.ttslua +++ b/src/playercards/cards/BorrowedTime.ttslua @@ -19,7 +19,7 @@ function onLoad(savedData) end function searchSelfForTokens() - clickableResourceCounter = nil + local clickableResourceCounter local foundTokens = 0 for _, obj in ipairs(SearchLib.onObject(self, "isTileOrToken", 0.8)) do @@ -32,11 +32,11 @@ function searchSelfForTokens() break end end - return foundTokens + return foundTokens, clickableResourceCounter end function removeClicks(player) - local foundTokens = searchSelfForTokens() + local foundTokens, clickableResourceCounter = searchSelfForTokens() if clickableResourceCounter then clickableResourceCounter.call("updateVal", 0) @@ -48,6 +48,7 @@ function removeClicks(player) end end end + if foundTokens > 0 then addAction(player, foundTokens) else @@ -57,12 +58,28 @@ end function addAction(player, foundTokens) -- only spawn a maximum of 3 action tokens - if foundTokens > 3 then - numTokens = 3 - else - numTokens = foundTokens + local numTokens = math.min(foundTokens, 3) + local positions = getSpawnPositions(numTokens) + + for i = 1, numTokens do + TokenManagerApi.spawnToken(positions[i], "universalActionAbility", self.getRotation(), "multiplyScale", 0.6, nil, "Temporary") + end + + broadcastToColor("Spawning " .. numTokens .. " temporary action token(s).", player.color) +end + +-- work out the token spawn positions +local baseOffset = 0.3 +local offsetList = { -2, -1, 0, 1, 2 } +local countToIndex = { { 3 }, { 2, 4 }, { 1, 3, 5 } } + +function getSpawnPositions(count) + local positions = {} + + for _, index in ipairs(countToIndex[count]) do + local pos = Vector(offsetList[index] * baseOffset, 1, 0.75) + table.insert(positions, self.positionToWorld(pos)) end - TokenManagerApi.spawnTokenGroup(self, "universalActionAbility", numTokens, 1.3, nil, true) - broadcastToColor("Spawning " .. numTokens.." temporary action token(s).", player.color) + return positions end