From f98cf3ca3932ce3b5a26c01fbace474af026432c Mon Sep 17 00:00:00 2001 From: dscarpac Date: Thu, 18 Apr 2024 05:13:44 -0500 Subject: [PATCH 01/28] version 1 --- .../KhakuNarukami.54eaa7.json | 2 +- src/playercards/cards/KhakuNarukami.ttslua | 64 +++++++++++++++++++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/playercards/cards/KhakuNarukami.ttslua diff --git a/objects/AllPlayerCards.15bb07/KhakuNarukami.54eaa7.json b/objects/AllPlayerCards.15bb07/KhakuNarukami.54eaa7.json index 7c317a95..e73ac888 100644 --- a/objects/AllPlayerCards.15bb07/KhakuNarukami.54eaa7.json +++ b/objects/AllPlayerCards.15bb07/KhakuNarukami.54eaa7.json @@ -33,7 +33,7 @@ "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": false, - "LuaScript": "", + "LuaScript": "require(\"playercards/cards/KhakuNarukami\")", "LuaScriptState": "", "MeasureMovement": false, "Name": "Card", diff --git a/src/playercards/cards/KhakuNarukami.ttslua b/src/playercards/cards/KhakuNarukami.ttslua new file mode 100644 index 00000000..1c4acfde --- /dev/null +++ b/src/playercards/cards/KhakuNarukami.ttslua @@ -0,0 +1,64 @@ +function onSave() + return JSON.encode() +end + +function onLoad(savedData) + self.addContextMenuItem("Enable Helper", createButtons) + sigil = JSON.decode(savedData) + if sigil and sigil ~= nil then + makeXMLButton(sigil) + self.clearContextMenu() + self.addContextMenuItem("Clear Helper", deleteButtons) + end +end + +function makeXMLButton(chosenToken) + self.UI.setXmlTable({ + { + tag="Button", + attributes={ + height=450, + width=1400, + rotation="0 0 180", + scale="0.1 0.1 1", + position="0 -55 -22", + padding="50 50 50 50", + font="font_teutonic-arkham", + fontSize=300, + iconWidth=400, + iconAlignment="Right", + onClick="remove", + id=sigil, + icon=dataForToken[sigil].icon, + color=dataForToken[sigil].color, + textColor="White", + }, + value="Resolve", + } + } +) +end + +-- Create dialog window to choose sigil and create sigil-drawing button +function chooseSigil(playerColor) + self.clearContextMenu() + self.addContextMenuItem("Clear Helper", deleteButtons) + Player[playerColor].showOptionsDialog("Choose Sigil", tokenNames, 1, + function(chosenToken) + if chosenToken == "Custom Token" then + sigil = "" + else + sigil = chosenToken + end + makeXMLButton(sigil) + end + ) +end + +-- Delete button and remove sigil +function deleteButtons() + self.clearContextMenu() + self.addContextMenuItem("Enable Helper", chooseSigil) + self.UI.setXml("") + sigil = nil +end \ No newline at end of file From ee0600f8e49d97ab9b761151b9e028cd64dd60d9 Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Fri, 28 Jun 2024 14:02:41 +0200 Subject: [PATCH 02/28] Added object unselection to context menus --- src/accessories/PhaseTracker.ttslua | 5 ++-- src/accessories/UnderworldMarketHelper.ttslua | 7 +++-- src/core/MythosArea.ttslua | 4 +-- src/core/UniversalActionAbilityToken.ttslua | 3 +++ src/core/token/TokenManager.ttslua | 26 +++++++------------ src/core/token/TokenSpawnTracker.ttslua | 6 ++--- src/core/token/TokenSpawnTrackerApi.ttslua | 4 +-- src/playercards/Tarotcard.ttslua | 7 ++--- .../cards/FamilyInheritance.ttslua | 25 +++++++++++------- src/playercards/cards/NkosiMabati3.ttslua | 4 ++- src/playercards/cards/ScrollofSecrets.ttslua | 1 + src/playercards/cards/ShortSupply.ttslua | 11 ++++---- src/playercards/cards/Tekeli-li.ttslua | 4 ++- src/playermat/Playermat.ttslua | 7 ++--- 14 files changed, 63 insertions(+), 51 deletions(-) diff --git a/src/accessories/PhaseTracker.ttslua b/src/accessories/PhaseTracker.ttslua index e646a004..19af8ff9 100644 --- a/src/accessories/PhaseTracker.ttslua +++ b/src/accessories/PhaseTracker.ttslua @@ -42,10 +42,11 @@ function onLoad(savedData) color = { r = 0, g = 0, b = 0, a = 0 } }) - self.addContextMenuItem("toggle broadcasting", updateBroadcast) + self.addContextMenuItem("Toggle Broadcasting", updateBroadcast) end -function updateBroadcast() +function updateBroadcast(playerColor) + Player[playerColor].clearSelectedObjects() for _, tracker in ipairs(getObjectsWithTag("LinkedPhaseTracker")) do tracker.setVar("broadcastChange", not broadcastChange) end diff --git a/src/accessories/UnderworldMarketHelper.ttslua b/src/accessories/UnderworldMarketHelper.ttslua index 0373efbb..b24c7962 100644 --- a/src/accessories/UnderworldMarketHelper.ttslua +++ b/src/accessories/UnderworldMarketHelper.ttslua @@ -32,7 +32,7 @@ function onload(savedData) isSetup = false movingCards = false - self.addContextMenuItem('Reset helper', resetHelper) + self.addContextMenuItem('Reset Helper', resetHelper) if savedData and savedData ~= '' then local loaded_data = JSON.decode(savedData) @@ -242,7 +242,8 @@ function finish() 0.75) end -function resetHelper() +function resetHelper(playerColor) + Player[playerColor].clearSelectedObjects() for i, card in ipairs(self.getObjects()) do self.takeObject({ index = 0, @@ -269,7 +270,5 @@ function resetHelper() isSetup = false movingCards = false - self.reset() - print('Underworld Market Helper: Helper has been reset.') end diff --git a/src/core/MythosArea.ttslua b/src/core/MythosArea.ttslua index 9ce728d3..a40d6813 100644 --- a/src/core/MythosArea.ttslua +++ b/src/core/MythosArea.ttslua @@ -78,7 +78,7 @@ function onCollisionEnter(collisionInfo) local localPos = self.positionToLocal(object.getPosition()) if inArea(localPos, ENCOUNTER_DECK_AREA) or inArea(localPos, ENCOUNTER_DISCARD_AREA) then - Wait.frames(function() tokenSpawnTrackerApi.resetTokensSpawned(object.getGUID()) end, 1) + Wait.frames(function() tokenSpawnTrackerApi.resetTokensSpawned(object) end, 1) removeTokensFromObject(object) end end @@ -100,7 +100,7 @@ end function onObjectEnterContainer(container, object) local localPos = self.positionToLocal(container.getPosition()) if inArea(localPos, ENCOUNTER_DECK_AREA) or inArea(localPos, ENCOUNTER_DISCARD_AREA) then - tokenSpawnTrackerApi.resetTokensSpawned(object.getGUID()) + tokenSpawnTrackerApi.resetTokensSpawned(object) removeTokensFromObject(object) end end diff --git a/src/core/UniversalActionAbilityToken.ttslua b/src/core/UniversalActionAbilityToken.ttslua index b991697f..de55b40d 100644 --- a/src/core/UniversalActionAbilityToken.ttslua +++ b/src/core/UniversalActionAbilityToken.ttslua @@ -202,6 +202,7 @@ end function addContextMenu() self.addContextMenuItem("Change color", function(playerColor) + Player[playerColor].clearSelectedObjects() local currentClassDisplayName = listOfClassDisplayNames[getIndexOfValue(listOfClasses, class)] Player[playerColor].showOptionsDialog("Choose color", listOfClassDisplayNames, currentClassDisplayName, function(_, selectedIndex) @@ -210,6 +211,7 @@ function addContextMenu() end) self.addContextMenuItem("Change 1st symbol", function(playerColor) + Player[playerColor].clearSelectedObjects() local symbolList = getSymbolList() Player[playerColor].showOptionsDialog("Choose symbol", listOfSymbols, symbolList[1], function(newSymbol) if newSymbol == "None" then @@ -229,6 +231,7 @@ function addContextMenu() end) self.addContextMenuItem("Change 2nd symbol", function(playerColor) + Player[playerColor].clearSelectedObjects() local symbolList = getSymbolList() Player[playerColor].showOptionsDialog("Choose 2nd symbol", listOfSymbols, symbolList[2] or symbolList[1], function(newSymbol) diff --git a/src/core/token/TokenManager.ttslua b/src/core/token/TokenManager.ttslua index 0f208129..afc89c32 100644 --- a/src/core/token/TokenManager.ttslua +++ b/src/core/token/TokenManager.ttslua @@ -211,10 +211,11 @@ do if tokenType == "clue" then offsets = internal.buildClueOffsets(card, tokenCount) else - -- only up to 12 offset tables defined (TODO: stack more than 12 tokens and generate offsets dynamically) + -- only up to 12 offset tables defined if tokenCount > 12 then - printToAll("Spawning maximum of 12 tokens.") - tokenCount = 12 + printToAll("Attempting to spawn " .. tokenCount .. " tokens. Spawning clickable counter instead.") + TokenManager.spawnResourceCounterToken(card, tokenCount) + return end for i = 1, tokenCount do offsets[i] = card.positionToWorld(PLAYER_CARD_TOKEN_OFFSETS[tokenCount][i]) @@ -297,20 +298,13 @@ do -- Checks a card for metadata to maybe replenish it ---@param card tts__Object Card object to be replenished ---@param uses table The already decoded metadata.uses (to avoid decoding again) - ---@param mat tts__Object The playermat the card is placed on (for rotation and casting) - TokenManager.maybeReplenishCard = function(card, uses, mat) + TokenManager.maybeReplenishCard = function(card, uses) -- TODO: support for cards with multiple uses AND replenish (as of yet, no official card needs that) if uses[1].count and uses[1].replenish then - internal.replenishTokens(card, uses, mat) + internal.replenishTokens(card, uses) end end - -- Delegate function to the token spawn tracker. Exists to avoid circular dependencies in some callers - ---@param card tts__Object Card object to reset the tokens for - TokenManager.resetTokensSpawned = function(card) - tokenSpawnTrackerApi.resetTokensSpawned(card.getGUID()) - end - -- Pushes new player card data into the local copy of the Data Helper player data. ---@param dataTable table Key/Value pairs following the DataHelper style TokenManager.addPlayerCardData = function(dataTable) @@ -483,16 +477,16 @@ do ---@param card tts__Object Card object to be replenished ---@param uses table The already decoded metadata.uses (to avoid decoding again) - ---@param mat tts__Object The playermat the card is placed on (for rotation and casting) - internal.replenishTokens = function(card, uses, mat) - -- get current amount of resource tokens on the card + internal.replenishTokens = function(card, uses) + -- get current amount of matching resource tokens on the card local clickableResourceCounter = nil local foundTokens = 0 + local searchType = string.lower(uses[1].type) for _, obj in ipairs(searchLib.onObject(card, "isTileOrToken")) do local memo = obj.getMemo() - if (stateTable[memo] or 0) > 0 then + if searchType == memo then foundTokens = foundTokens + math.abs(obj.getQuantity()) obj.destruct() elseif memo == "resourceCounter" then diff --git a/src/core/token/TokenSpawnTracker.ttslua b/src/core/token/TokenSpawnTracker.ttslua index 0340ae91..1061197f 100644 --- a/src/core/token/TokenSpawnTracker.ttslua +++ b/src/core/token/TokenSpawnTracker.ttslua @@ -22,8 +22,8 @@ function markTokensSpawned(cardGuid) spawnedCardGuids[cardGuid] = true end -function resetTokensSpawned(cardGuid) - spawnedCardGuids[cardGuid] = nil +function resetTokensSpawned(card) + spawnedCardGuids[card.getGUID()] = nil end function resetAll() spawnedCardGuids = {} end @@ -52,6 +52,6 @@ end -- Listener to reset card token spawns when they enter a hand. function onObjectEnterZone(zone, enterObject) if zone.type == "Hand" and enterObject.type == "Card" then - resetTokensSpawned(enterObject.getGUID()) + resetTokensSpawned(enterObject) end end diff --git a/src/core/token/TokenSpawnTrackerApi.ttslua b/src/core/token/TokenSpawnTrackerApi.ttslua index 1ba4c261..e8176296 100644 --- a/src/core/token/TokenSpawnTrackerApi.ttslua +++ b/src/core/token/TokenSpawnTrackerApi.ttslua @@ -14,8 +14,8 @@ do return getSpawnTracker().call("markTokensSpawned", cardGuid) end - TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getSpawnTracker().call("resetTokensSpawned", cardGuid) + TokenSpawnTracker.resetTokensSpawned = function(card) + return getSpawnTracker().call("resetTokensSpawned", card) end TokenSpawnTracker.resetAllAssetAndEvents = function() diff --git a/src/playercards/Tarotcard.ttslua b/src/playercards/Tarotcard.ttslua index d1c1bbbc..e9abd0d0 100644 --- a/src/playercards/Tarotcard.ttslua +++ b/src/playercards/Tarotcard.ttslua @@ -5,7 +5,8 @@ function onLoad() end -- rotates the alt_view_angle -function rotatePreview() +function rotatePreview(playerColor) + Player[playerColor].clearSelectedObjects() local angle = self.alt_view_angle if angle.y == 0 then angle.y = 180 @@ -16,7 +17,7 @@ function rotatePreview() end -- rotates this card and the preview -function rotateSelfAndPreview() +function rotateSelfAndPreview(playerColor) self.setRotationSmooth(self.getRotation() + Vector(0, 180, 0)) - rotatePreview() + rotatePreview(playerColor) end diff --git a/src/playercards/cards/FamilyInheritance.ttslua b/src/playercards/cards/FamilyInheritance.ttslua index 19ea08cc..e5b71240 100644 --- a/src/playercards/cards/FamilyInheritance.ttslua +++ b/src/playercards/cards/FamilyInheritance.ttslua @@ -6,9 +6,21 @@ local clickableResourceCounter = nil local foundTokens = 0 function onLoad() - self.addContextMenuItem("Add 4 resources", function(playerColor) add4(playerColor) end) - self.addContextMenuItem("Take all resources", function(playerColor) takeAll(playerColor) end) - self.addContextMenuItem("Discard all resources", function(playerColor) loseAll(playerColor) end) + self.addContextMenuItem("Add 4 resources", + function(playerColor) + Player[playerColor].clearSelectedObjects() + add4(playerColor) + end) + self.addContextMenuItem("Take all resources", + function(playerColor) + Player[playerColor].clearSelectedObjects() + takeAll(playerColor) + end) + self.addContextMenuItem("Discard all resources", + function(playerColor) + Player[playerColor].clearSelectedObjects() + loseAll(playerColor) + end) end function searchSelf() @@ -35,12 +47,7 @@ function add4(playerColor) if clickableResourceCounter then clickableResourceCounter.call("updateVal", newCount) else - if newCount > 12 then - printToColor("Count increased to " .. newCount .. " resources. Spawning clickable counter instead.", playerColor) - tokenManager.spawnResourceCounterToken(self, newCount) - else - tokenManager.spawnTokenGroup(self, "resource", newCount) - end + tokenManager.spawnTokenGroup(self, "resource", newCount) end end diff --git a/src/playercards/cards/NkosiMabati3.ttslua b/src/playercards/cards/NkosiMabati3.ttslua index 187d302c..83d2e6b9 100644 --- a/src/playercards/cards/NkosiMabati3.ttslua +++ b/src/playercards/cards/NkosiMabati3.ttslua @@ -61,6 +61,7 @@ end -- Create dialog window to choose sigil and create sigil-drawing button function chooseSigil(playerColor) + Player[playerColor].clearSelectedObjects() self.clearContextMenu() self.addContextMenuItem("Clear Helper", deleteButtons) @@ -80,7 +81,8 @@ function chooseSigil(playerColor) end -- Delete button and remove sigil -function deleteButtons() +function deleteButtons(playerColor) + Player[playerColor].clearSelectedObjects() self.clearContextMenu() self.addContextMenuItem("Enable Helper", chooseSigil) self.UI.setXml("") diff --git a/src/playercards/cards/ScrollofSecrets.ttslua b/src/playercards/cards/ScrollofSecrets.ttslua index 39c0a97e..544ef2c8 100644 --- a/src/playercards/cards/ScrollofSecrets.ttslua +++ b/src/playercards/cards/ScrollofSecrets.ttslua @@ -17,6 +17,7 @@ function onLoad() end function contextFunc(playerColor, amount) + Player[playerColor].clearSelectedObjects() deckData = {} local options = {} diff --git a/src/playercards/cards/ShortSupply.ttslua b/src/playercards/cards/ShortSupply.ttslua index 8074211b..cdca89b6 100644 --- a/src/playercards/cards/ShortSupply.ttslua +++ b/src/playercards/cards/ShortSupply.ttslua @@ -5,7 +5,8 @@ function onLoad() end -- called by context menu entry -function shortSupply(color) +function shortSupply(playerColor) + Player[playerColor].clearSelectedObjects() local matColor = playermatApi.getMatColorByPosition(self.getPosition()) -- get draw deck and discard position @@ -15,20 +16,20 @@ function shortSupply(color) -- error handling if discardPos == nil then - broadcastToColor("Couldn't retrieve discard position from playermat!", color, "Red") + broadcastToColor("Couldn't retrieve discard position from playermat!", playerColor, "Red") return end if drawDeck == nil then - broadcastToColor("Deck not found!", color, "Yellow") + broadcastToColor("Deck not found!", playerColor, "Yellow") return elseif drawDeck.type ~= "Deck" then - broadcastToColor("Deck only contains a single card!", color, "Yellow") + broadcastToColor("Deck only contains a single card!", playerColor, "Yellow") return end -- discard cards, waiting 0.7 seconds between each discard to give players visiblity of the cards - broadcastToColor("Discarding top 10 cards for player color '" .. matColor .. "'.", color, "White") + broadcastToColor("Discarding top 10 cards for player color '" .. matColor .. "'.", playerColor, "White") for i = 1, 10 do Wait.time(function() drawDeck.takeObject({ flip = true, position = { discardPos.x, 2 + 0.075 * i, discardPos.z } }) end, .7 * (i - 1)) end diff --git a/src/playercards/cards/Tekeli-li.ttslua b/src/playercards/cards/Tekeli-li.ttslua index acf90fae..6a54d793 100644 --- a/src/playercards/cards/Tekeli-li.ttslua +++ b/src/playercards/cards/Tekeli-li.ttslua @@ -7,7 +7,8 @@ function onLoad() end -- uses the tekeli-li helper to place this card at the bottom of the deck -function returnSelf() +function returnSelf(playerColor) + Player[playerColor].clearSelectedObjects() local helper = getTekeliliHelper() if helper == nil then printToAll("Couldn't find Tekeli-li Helper!") @@ -18,6 +19,7 @@ end -- places this card below the deck of the player that triggered it function placeBelowDeck(playerColor) + Player[playerColor].clearSelectedObjects() local matColor = playermatApi.getMatColor(playerColor) local deckPos = playermatApi.getDrawPosition(matColor) local deckRot = playermatApi.returnRotation(matColor) diff --git a/src/playermat/Playermat.ttslua b/src/playermat/Playermat.ttslua index ebb7ecad..e82c52f8 100644 --- a/src/playermat/Playermat.ttslua +++ b/src/playermat/Playermat.ttslua @@ -6,6 +6,7 @@ local navigationOverlayApi = require("core/NavigationOverlayApi") local searchLib = require("util/SearchLib") local tokenChecker = require("core/token/TokenChecker") local tokenManager = require("core/token/TokenManager") +local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") -- we use this to turn off collision handling until onLoad() is complete local collisionEnabled = false @@ -344,7 +345,7 @@ function doUpkeep(_, clickedByColor, isRightClick) end -- maybe replenish uses on certain cards (don't continue for cards on the deck (Norman) or in the discard pile) - if cardMetadata.uses ~= nil and self.positionToLocal(obj.getPosition()).x < -1 then + if cardMetadata.uses ~= nil and self.positionToLocal(obj.getPosition()).x > -1 then tokenManager.maybeReplenishCard(obj, cardMetadata.uses, self) end elseif obj.type == "Deck" and forcedLearning == false then @@ -823,7 +824,7 @@ function onCollisionEnter(collisionInfo) local localCardPos = self.positionToLocal(object.getPosition()) if inArea(localCardPos, DECK_DISCARD_AREA) then - tokenManager.resetTokensSpawned(object) + tokenSpawnTrackerApi.resetTokensSpawned(object) removeTokensFromObject(object) elseif shouldSpawnTokens(object) then spawnTokensFor(object) @@ -867,7 +868,7 @@ function onObjectEnterContainer(container, object) local localCardPos = self.positionToLocal(object.getPosition()) if inArea(localCardPos, DECK_DISCARD_AREA) then - tokenManager.resetTokensSpawned(object) + tokenSpawnTrackerApi.resetTokensSpawned(object) removeTokensFromObject(object) end end From c27fcb5b2574c7f234a6fef4f96f22bf439eee88 Mon Sep 17 00:00:00 2001 From: dscarpac Date: Fri, 28 Jun 2024 11:41:19 -0500 Subject: [PATCH 03/28] first pass --- modsettings/CustomUIAssets.json | 5 + .../KhakuNarukami.54eaa7.json | 4 +- src/playercards/cards/KhakuNarukami.ttslua | 64 ---------- src/playercards/cards/KohakuNarukami.ttslua | 120 ++++++++++++++++++ src/playermat/Playermat.ttslua | 4 +- xml/playercards/KohakuNarukami.xml | 98 ++++++++++++++ 6 files changed, 228 insertions(+), 67 deletions(-) delete mode 100644 src/playercards/cards/KhakuNarukami.ttslua create mode 100644 src/playercards/cards/KohakuNarukami.ttslua create mode 100644 xml/playercards/KohakuNarukami.xml diff --git a/modsettings/CustomUIAssets.json b/modsettings/CustomUIAssets.json index 37fe7bd3..00501220 100644 --- a/modsettings/CustomUIAssets.json +++ b/modsettings/CustomUIAssets.json @@ -244,6 +244,11 @@ "Type": 0, "URL": "http://cloud-3.steamusercontent.com/ugc/2510267932886739653/CB7AA2D73777EF5938A6E6CD664B2ABA52B6E20A/" }, + { + "Name": "token-eldersign", + "Type": 0, + "URL": "http://cloud-3.steamusercontent.com/ugc/2540675016035917168/C0D6F531A85FD94C2F54825DFC50781B5B499A1D/" + }, { "Name": "token-custom-token", "Type": 0, diff --git a/objects/AllPlayerCards.15bb07/KhakuNarukami.54eaa7.json b/objects/AllPlayerCards.15bb07/KhakuNarukami.54eaa7.json index e73ac888..3cc17a73 100644 --- a/objects/AllPlayerCards.15bb07/KhakuNarukami.54eaa7.json +++ b/objects/AllPlayerCards.15bb07/KhakuNarukami.54eaa7.json @@ -33,7 +33,7 @@ "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": false, - "LuaScript": "require(\"playercards/cards/KhakuNarukami\")", + "LuaScript": "require(\"playercards/cards/KohakuNarukami\")", "LuaScriptState": "", "MeasureMovement": false, "Name": "Card", @@ -58,5 +58,5 @@ "scaleZ": 1.15 }, "Value": 0, - "XmlUI": "" + "XmlUI": "\u003cInclude src=\"playercards/KohakuNarukami.xml\"/\u003e" } diff --git a/src/playercards/cards/KhakuNarukami.ttslua b/src/playercards/cards/KhakuNarukami.ttslua deleted file mode 100644 index 1c4acfde..00000000 --- a/src/playercards/cards/KhakuNarukami.ttslua +++ /dev/null @@ -1,64 +0,0 @@ -function onSave() - return JSON.encode() -end - -function onLoad(savedData) - self.addContextMenuItem("Enable Helper", createButtons) - sigil = JSON.decode(savedData) - if sigil and sigil ~= nil then - makeXMLButton(sigil) - self.clearContextMenu() - self.addContextMenuItem("Clear Helper", deleteButtons) - end -end - -function makeXMLButton(chosenToken) - self.UI.setXmlTable({ - { - tag="Button", - attributes={ - height=450, - width=1400, - rotation="0 0 180", - scale="0.1 0.1 1", - position="0 -55 -22", - padding="50 50 50 50", - font="font_teutonic-arkham", - fontSize=300, - iconWidth=400, - iconAlignment="Right", - onClick="remove", - id=sigil, - icon=dataForToken[sigil].icon, - color=dataForToken[sigil].color, - textColor="White", - }, - value="Resolve", - } - } -) -end - --- Create dialog window to choose sigil and create sigil-drawing button -function chooseSigil(playerColor) - self.clearContextMenu() - self.addContextMenuItem("Clear Helper", deleteButtons) - Player[playerColor].showOptionsDialog("Choose Sigil", tokenNames, 1, - function(chosenToken) - if chosenToken == "Custom Token" then - sigil = "" - else - sigil = chosenToken - end - makeXMLButton(sigil) - end - ) -end - --- Delete button and remove sigil -function deleteButtons() - self.clearContextMenu() - self.addContextMenuItem("Enable Helper", chooseSigil) - self.UI.setXml("") - sigil = nil -end \ No newline at end of file diff --git a/src/playercards/cards/KohakuNarukami.ttslua b/src/playercards/cards/KohakuNarukami.ttslua new file mode 100644 index 00000000..b8b8771e --- /dev/null +++ b/src/playercards/cards/KohakuNarukami.ttslua @@ -0,0 +1,120 @@ +require("playercards/CardsWithHelper") +local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi") +local chaosBagApi = require("chaosbag/ChaosBagApi") +local guidReferenceApi = require("core/GUIDReferenceApi") +local playermatApi = require("playermat/PlayermatApi") +local tokenManager = require("core/token/TokenManager") + +function updateSave() + self.script_state = JSON.encode({ isHelperEnabled = isHelperEnabled }) +end + +function onLoad(savedData) + self.addTag("CardWithHelper") + if savedData and savedData ~= "" then + local loadedData = JSON.decode(savedData) + isHelperEnabled = loadedData.isHelperEnabled + end + checkOptionPanel() + updateDisplay() +end + +-- hide buttons and stop monitoring +function shutOff() + self.UI.hide("Helper") + Wait.stopAll() + updateSave() +end + +-- show buttons and begin monitoring chaos bag for curse and bless tokens +function initialize() + self.UI.show("Helper") + maybeUpdateButtonState() + Wait.time(maybeUpdateButtonState, 1, -1) + updateSave() +end + +function addTokenToBag(_, _, tokenType) + blessCurseManagerApi.addToken(tokenType) +end + +function removeAndExtraAction() + blessCurseManagerApi.removeToken("Bless") + blessCurseManagerApi.removeToken("Bless") + blessCurseManagerApi.removeToken("Curse") + blessCurseManagerApi.removeToken("Curse") + + local position = self.getPosition() + local matColor = playermatApi.getMatColorByPosition(position) + local mat = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") + local rotation = mat.getRotation() + + -- spawn extra action token in the middle of investigator card with Temporary tag + callback = function(spawned) spawned.call("updateClassAndSymbol", { class = "Mystic", symbol = "Mystic" }) spawned.addTag("Temporary") end + tokenManager.spawnToken(position + Vector(0, 0.2, 0), "universalActionAbility", rotation, callback) +end + +function elderSignAbility() + blessCurseManagerApi.addToken("Bless") + blessCurseManagerApi.addToken("Curse") +end + +-- count tokens in the bag and show appropriate buttons +function maybeUpdateButtonState() + local numInBag = getBlessCurseInBag() + local state = { Bless = false, Curse = false, Action = false, ElderSign = false } + + if numInBag.Bless <= numInBag.Curse and numInBag.Bless < 10 then + state.Bless = true + end + + if numInBag.Curse <= numInBag.Bless and numInBag.Curse < 10 then + state.Curse = true + end + + if numInBag.Curse >= 2 and numInBag.Bless >= 2 then + state.Action = true + end + + state.ElderSign = true + + setUiState(state) +end + +function getBlessCurseInBag() + local numInBag = { Bless = 0, Curse = 0 } + local chaosBag = chaosBagApi.findChaosBag() + + for _, v in ipairs(chaosBag.getObjects()) do + if v.name == "Bless" or v.name == "Curse" then + numInBag[v.name] = numInBag[v.name] + 1 + end + end + + return numInBag +end + +function setUiState(params) + for _, tokenName in ipairs({ "Bless", "Curse", "Action", "ElderSign" }) do + if params[tokenName] then + self.UI.show(tokenName) + self.UI.hide("inactive" .. tokenName) + else + self.UI.show("inactive" .. tokenName) + self.UI.hide(tokenName) + end + end +end + +function errorMessage(_, _, triggeringButton) + local numInBag = getBlessCurseInBag() + if triggeringButton == "inactiveAction" then + broadcastToAll("There are not enough Blesses and/or Curses in the chaos bag.", "Red") + elseif numInBag.Bless == 10 and numInBag.Curse == 10 then + broadcastToAll("No more tokens can be added to the chaos bag.", "Red") + elseif numInBag.Bless < numInBag.Curse then + broadcastToAll("There are more Bless tokens than Curse tokens in the chaos bag.", "Red") + else + broadcastToAll("There are more Curse tokens than Bless tokens in the chaos bag.", "Red") + end +end \ No newline at end of file diff --git a/src/playermat/Playermat.ttslua b/src/playermat/Playermat.ttslua index f4208b93..1021458c 100644 --- a/src/playermat/Playermat.ttslua +++ b/src/playermat/Playermat.ttslua @@ -314,7 +314,9 @@ function doUpkeep(_, clickedByColor, isRightClick) local forcedLearning = false local rot = self.getRotation() for _, obj in ipairs(searchAroundSelf()) do - if obj.hasTag("UniversalToken") == true and obj.is_face_down then + if obj.hasTag("Temporary") == true then + discardListOfObjects({obj}) + elseif obj.hasTag("UniversalToken") == true and obj.is_face_down then obj.flip() elseif obj.type == "Card" and not inArea(self.positionToLocal(obj.getPosition()), INVESTIGATOR_AREA) then local cardMetadata = JSON.decode(obj.getGMNotes()) or {} diff --git a/xml/playercards/KohakuNarukami.xml b/xml/playercards/KohakuNarukami.xml new file mode 100644 index 00000000..d39c467b --- /dev/null +++ b/xml/playercards/KohakuNarukami.xml @@ -0,0 +1,98 @@ + +