Merge branch 'helpers' into playermats

This commit is contained in:
Chr1Z93 2024-06-26 12:54:03 +02:00
commit b668146ba4
19 changed files with 344 additions and 362 deletions

View File

@ -33,7 +33,7 @@
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": false,
"LuaScript": "require(\"playercards/cards/TheChthonianStone3\")",
"LuaScript": "require(\"playercards/cards/TheChthonianStone\")",
"LuaScriptState": "",
"MeasureMovement": false,
"Name": "Card",

View File

@ -1 +1 @@
{"acknowledgedUpgradeVersions":[],"chaosTokensGUID":[],"optionPanel":{"cardLanguage":"en","changePlayAreaImage":false,"playAreaConnectionColor":{"a":1,"b":0.4,"g":0.4,"r":0.4},"playAreaConnections":true,"playAreaSnapTags":true,"showAttachmentHelper":false,"showCleanUpHelper":false,"showCYOA":false,"showDisplacementTool":false,"showDrawButton":false,"showHandHelper":false,"showSearchAssistant":false,"showTitleSplash":true,"useClassTexture":true,"useClueClickers":false,"useResourceCounters":"disabled","useSnapTags":true}}
{"acknowledgedUpgradeVersions":[],"chaosTokensGUID":[],"optionPanel":{"cardLanguage":"en","changePlayAreaImage":false,"enableCardHelpers":false,"playAreaConnectionColor":{"a":1,"b":0.4,"g":0.4,"r":0.4},"playAreaConnections":true,"playAreaSnapTags":true,"showAttachmentHelper":false,"showCleanUpHelper":false,"showCYOA":false,"showDisplacementTool":false,"showDrawButton":false,"showHandHelper":false,"showSearchAssistant":false,"showTitleSplash":true,"useClassTexture":true,"useClueClickers":false,"useResourceCounters":"disabled","useSnapTags":true}}

View File

@ -61,17 +61,18 @@ do
-- are drawn or replaced a TTS bug can cause those tokens to vanish. Any functions which change the
-- contents of the bag should check this method before doing so.
-- This method will broadcast a message to all players if the bag is being searched.
---@return any canTouch True if the bag is manipulated, false if it should be blocked.
---@return any: True if the bag is manipulated, false if it should be blocked.
ChaosBagApi.canTouchChaosTokens = function()
return Global.call("canTouchChaosTokens")
end
-- called by playermats (by the "Draw chaos token" button)
-- draws a chaos token to a playermat
---@param mat tts__Object Playermat that triggered this
---@param drawAdditional boolean Controls whether additional tokens should be drawn
---@param tokenType? string Name of token (e.g. "Bless") to be drawn from the bag
---@param guidToBeResolved? string GUID of the sealed token to be resolved instead of drawing a token from the bag
---@param takeParameters? table Position and rotation of the location where the new token should be drawn to, usually to replace a returned token
---@return tts__Object: Object reference to the token that was drawn
ChaosBagApi.drawChaosToken = function(mat, drawAdditional, tokenType, guidToBeResolved, takeParameters)
return Global.call("drawChaosToken", {
mat = mat,

View File

@ -155,6 +155,7 @@ function onLoad(savedData)
end, 1)
end
-- provides a random seed (from 1 to 999) to be used by "linked" objects like the action tokens
function getRandomSeed()
return math.random(999)
end
@ -255,6 +256,7 @@ function findChaosBag()
printToAll("Chaos bag couldn't be found.", "Red")
end
-- returns all chaos tokens to the bag
function returnChaosTokens()
local chaosBag = findChaosBag()
for _, token in pairs(chaosTokens) do
@ -267,15 +269,15 @@ end
-- returns a single chaos token to the bag and calls respective functions
function returnChaosTokenToBag(token)
local name = token.getName()
local guid = token.getGUID()
local chaosBag = findChaosBag()
chaosBag.putObject(token)
tokenArrangerApi.layout()
if name == "Bless" or name == "Curse" then
blessCurseManagerApi.releasedToken(name, guid, true)
blessCurseManagerApi.releasedToken(name, token.getGUID(), true)
end
end
-- returns the index of a token in the chaosTokens table
function getTokenIndex(token)
for i, obj in ipairs(chaosTokens) do
if obj == token then
@ -284,12 +286,10 @@ function getTokenIndex(token)
end
end
function activeRedrawEffect(originParams)
redrawData = originParams
makeButtonsToRedraw()
end
-- starts a redraw effect and displays buttons for a choice if needed
function activeRedrawEffect(params)
redrawData = params
function makeButtonsToRedraw()
if isTokenXMLActive == true then
broadcastToAll("Clear already active buttons first, then try again", "Red")
return
@ -300,38 +300,38 @@ function makeButtonsToRedraw()
return
end
local matchingTokensInPlay = {}
-- nil handling
redrawData.VALID_TOKENS = redrawData.VALID_TOKENS or {}
redrawData.INVALID_TOKENS = redrawData.INVALID_TOKENS or {}
-- determine if only some tokens are able to be returned to the bag
local matchingTokensInPlay = {}
for _, token in ipairs(chaosTokens) do
local tokenName = getReadableTokenName(token.getName())
-- allow valid tokens or not invalid tokens, also allow any token if both lists empty
if (redrawData.VALID_TOKENS[tokenName] ~= nil and isTableEmpty(redrawData.INVALID_TOKENS)) or (isTableEmpty(redrawData.VALID_TOKENS) and not redrawData.INVALID_TOKENS[tokenName]) or
if (redrawData.VALID_TOKENS[tokenName] ~= nil and isTableEmpty(redrawData.INVALID_TOKENS)) or
(isTableEmpty(redrawData.VALID_TOKENS) and not redrawData.INVALID_TOKENS[tokenName]) or
(isTableEmpty(redrawData.VALID_TOKENS) and isTableEmpty(redrawData.INVALID_TOKENS)) then
table.insert(matchingTokensInPlay, token)
end
end
-- proceed according to number of matching tokens
if #matchingTokensInPlay == 0 then
broadcastToAll("No eligible token found in play area", "Red")
return
end
if #matchingTokensInPlay > 1 then
elseif #matchingTokensInPlay == 1 then
returnAndRedraw(_, matchingTokensInPlay[1].getGUID())
else
-- draw XML to allow choosing the token to return to bag
isTokenXMLActive = true
for _, token in ipairs(matchingTokensInPlay) do
-- draw XML to return token to bag
token.UI.setXmlTable({
{
tag = "VerticalLayout",
attributes = {
height = 275,
width = 275,
spacing = 0,
padding = "0 0 20 25",
scale = "0.4 0.4 1",
rotation = "0 0 180",
@ -362,43 +362,51 @@ function makeButtonsToRedraw()
}
})
end
isTokenXMLActive = true
-- no need to make buttons if there is only one eligible token to return and redraw
else
returnAndRedraw(_, matchingTokensInPlay[1].getGUID())
end
end
-- returns a chaos token to the chaos bag and redraws another, always called by an XML button through makeButtonsToRedraw() above
-- returns a chaos token to the chaos bag and redraws another
function returnAndRedraw(_, tokenGUID)
local takeParameters = {}
local returnedToken = getObjectFromGUID(tokenGUID)
local tokenName = returnedToken.getName()
local indexOfReturnedToken = getTokenIndex(returnedToken)
local matColor = playermatApi.getMatColorByPosition(returnedToken.getPosition())
local mat = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat")
isTokenXMLActive = false
trackChaosToken(returnedToken.getName(), mat.getGUID(), true)
local indexOfReturnedToken = getTokenIndex(returnedToken)
takeParameters.position = returnedToken.getPosition()
local takeParameters = {
position = returnedToken.getPosition(),
rotation = returnedToken.getRotation()
}
if #chaosTokens > indexOfReturnedToken then
takeParameters.rotation = mat.getRotation() + Vector(0, 0, -8)
else
takeParameters.rotation = returnedToken.getRotation()
takeParameters.rotation = takeParameters.rotation + Vector(0, 0, -8)
end
-- perform the actual token replacing
trackChaosToken(tokenName, mat.getGUID(), true)
returnChaosTokenToBag(returnedToken)
local params = { mat = mat, drawAdditional = true, takeParameters = takeParameters }
if redrawData.redrawnTokenType ~= "random" then
params.tokenType = redrawData.redrawnTokenType
end
chaosTokens[indexOfReturnedToken] = drawChaosToken(params)
if redrawData.triggeringCard == "FalseCovenant" then
blessCurseManagerApi.removeToken("Curse")
chaosTokens[indexOfReturnedToken] = drawChaosToken({
mat = mat,
drawAdditional = true,
tokenType = redrawData.DRAW_SPECIFIC_TOKEN, -- currently only used for Nkosi Mabati
takeParameters = takeParameters
})
-- remove these tokens from the bag
if redrawData.RETURN_TO_POOL then
-- let the bless/curse manager handle these
if tokenName == "Bless" or tokenName == "Curse" then
blessCurseManagerApi.removeToken(tokenName)
else
local invertedTable = createChaosTokenNameLookupTable()
removeChaosToken(invertedTable[tokenName])
end
end
-- remove XML from tokens in play
for _, token in ipairs(getChaosTokensinPlay()) do
isTokenXMLActive = false
for _, token in ipairs(chaosTokens) do
token.UI.setXml("")
end
@ -440,7 +448,6 @@ end
function drawChaosToken(params)
if not canTouchChaosTokens() then return end
local tokenOffset = { -1.55, 0.25, -0.58 }
local matGUID = params.mat.getGUID()
-- return token(s) on other playermat first
@ -458,30 +465,23 @@ function drawChaosToken(params)
if #chaosBag.getObjects() == 0 then return end
chaosBag.shuffle()
local takeParameters = {}
-- add the token to the list, compute new position based on list length
if params.takeParameters then
takeParameters.position = params.takeParameters.position
takeParameters.rotation = params.takeParameters.rotation
else
tokenOffset[1] = tokenOffset[1] + (0.17 * #chaosTokens)
takeParameters.position = params.mat.positionToWorld(tokenOffset)
takeParameters.rotation = params.mat.getRotation()
end
local tokenOffset = Vector(-1.55 + 0.17 * #chaosTokens, 0.25, -0.58)
local takeParameters = params.takeParameters or {}
takeParameters.position = takeParameters.position or params.mat.positionToWorld(tokenOffset)
takeParameters.rotation = takeParameters.rotation or params.mat.getRotation()
local token
if params.guidToBeResolved then
-- resolve a sealed token from a card
token = getObjectFromGUID(params.guidToBeResolved)
token.setPositionSmooth(takeParameters.position)
local guid = token.getGUID()
local tokenType = token.getName()
if tokenType == "Bless" or tokenType == "Curse" then
blessCurseManagerApi.releasedToken(tokenType, guid)
end
tokenArrangerApi.layout()
local tokenName = token.getName()
if tokenName == "Bless" or tokenName == "Curse" then
blessCurseManagerApi.releasedToken(tokenName, token.getGUID())
end
else
-- take a token from the bag, either specified or random
if params.tokenType then
@ -501,12 +501,10 @@ function drawChaosToken(params)
token.setDescription(specificData.description or "")
trackChaosToken(name, matGUID)
if params.takeParameters then
return token
else
if not params.takeParameters then
table.insert(chaosTokens, token)
return token
end
return token
else
returnChaosTokens()
end
@ -533,8 +531,7 @@ function trackChaosToken(tokenName, matGUID, subtract)
-- increase stats by 1 (or decrease if token is returned)
local modifier = (subtract and -1 or 1)
local tokenName = getReadableTokenName(tokenName)
tokenName = getReadableTokenName(tokenName)
tokenDrawingStats["Overall"][tokenName] = (tokenDrawingStats["Overall"][tokenName] or 0) + modifier
tokenDrawingStats[matGUID][tokenName] = (tokenDrawingStats[matGUID][tokenName] or 0) + modifier
end
@ -555,7 +552,6 @@ function handleStatTrackerClick(_, _, isRightClick)
playerColor = "White"
playerName = "Overall"
else
-- get mat color
local matColor = playermatApi.getMatColorByPosition(getObjectFromGUID(key).getPosition())
playerColor = playermatApi.getPlayerColor(matColor)
playerName = Player[playerColor].steam_name or playerColor
@ -750,7 +746,7 @@ function getChaosTokensinPlay()
return chaosTokens
end
-- returns a Table List of chaos token ids in the current chaos bag
-- returns a table of chaos token ids in the current chaos bag
---@api ChaosBag / ChaosBagApi
function getChaosBagState()
local tokens = {}
@ -1491,9 +1487,10 @@ function playermatRemovalSelected(player, selectedIndex, id)
if mat then
-- confirmation dialog about deletion
player.pingTable(mat.getPosition())
player.showConfirmDialog(
"Do you really want to remove " .. matColor .. "'s playermat and related objects? This can't be reversed.",
function() removePlayermat(matColor) end)
player.showConfirmDialog("Do you really want to remove " .. matColor .. "'s playermat and related objects? This can't be reversed.",
function()
removePlayermat(matColor)
end)
else
-- info dialog that it is already deleted
player.showInfoDialog(matColor .. "'s playermat has already been removed.")
@ -1568,6 +1565,9 @@ function applyOptionPanelChange(id, state)
local counter = guidReferenceApi.getObjectByOwnerAndType("Mythos", "MasterClueCounter")
counter.setVar("useClickableCounters", state)
elseif id == "enableCardHelpers" then
toggleCardHelpers(state)
-- option: Play area connection drawing
elseif id == "playAreaConnections" then
playAreaApi.setConnectionDrawState(state)
@ -1692,6 +1692,7 @@ function onClick_defaultSettings()
optionPanel = {
cardLanguage = "en",
changePlayAreaImage = false,
enableCardHelpers = false,
playAreaConnectionColor = { a = 1, b = 0.4, g = 0.4, r = 0.4 },
playAreaConnections = true,
playAreaSnapTags = true,
@ -1741,6 +1742,13 @@ function titleSplash(scenarioName)
end
end
-- instructs all card helpers to update their visibility
function toggleCardHelpers(state)
for _, obj in ipairs(getObjectsWithTag("CardWithHelper")) do
obj.call("setHelperState", state)
end
end
---------------------------------------------------------
-- Update notification related functionality
---------------------------------------------------------
@ -1813,6 +1821,7 @@ end
-- Utility functions
---------------------------------------------------------
-- removes a value from a table
function removeValueFromTable(t, val)
for i, v in ipairs(t) do
if v == val then
@ -1822,6 +1831,7 @@ function removeValueFromTable(t, val)
end
end
-- checks if a table is empty
function isTableEmpty(tbl)
if next(tbl) == nil then
return true

View File

@ -3,30 +3,27 @@ This file is used to add an XML button to a card, turned on via context menu.
Valid options modify the appearance of the XML button, as well as the
behavior of the return and redraw function. Set options before requiring this file.
originParams{} --@type table
- includes parameters for the return and redraw functions. Typically set VALID_TOKENS
or INVALID_TOKENS, not both. If there are no restrictions on which tokens can be redrawn
(e.g. Wendy Adams), do not include either parameter.
* VALID_TOKENS --@type table
- keyed table which lists all tokens that can be redrawn by the card
- example usage: "False Covenant"
> VALID_TOKENS = {
> ["Curse"] = true
> }
* INVALID_TOKENS --@type table
- keyed table which lists all tokens that cannot be redrawn by the card
- example usage: "Custom Ammunition"
> INVALID_TOKENS = {
> ["Auto-fail"] = true
> }
Parameters for the return and redraw functions. Typically set VALID_TOKENS or INVALID_TOKENS, not both.
If there are no restrictions on which tokens can be redrawn (e.g. Wendy Adams), keep both empty.
* VALID_TOKENS --@type table
- keyed table which lists all tokens that can be redrawn by the card
- example usage: "False Covenant"
> VALID_TOKENS = {
> ["Curse"] = true
> }
* redrawnTokenType --@type string ("random" or name of token)
- determines which kind of token is drawn from the bag. Typically "random"
but could be a set token name (e.g. Nkosi Mabati)
* INVALID_TOKENS --@type table
- keyed table which lists all tokens that cannot be redrawn by the card
- example usage: "Custom Ammunition"
> INVALID_TOKENS = {
> ["Auto-fail"] = true
> }
* triggeringCard --@type string (name of card button is on)
- allows for the name of the card to be passed onto Global for any special handling
* DRAW_SPECIFIC_TOKEN --@type string (name of token or nil)
- if set, will attempt to draw that specific token
* RETURN_TO_POOL --@type string
- allows for the name of the card to be passed onto Global for any special handling
The following parameters modify the appearence of the XML button and are not listed as part of a table.
- buttonHeight (default is 450)
@ -34,7 +31,7 @@ The following parameters modify the appearence of the XML button and are not lis
- buttonPosition (default is "0 -55 -22")
- buttonFontSize (default is 250)
- buttonRotation (change if button is placed on an investigator cards)
- buttonValue (to change the label of the button, default is "Redraw Token")
- buttonLabel (default is "Redraw Token")
- buttonIcon (to add an icon to the right)
- buttonColor (default is "#77674DE6")
@ -47,70 +44,70 @@ As a nice reminder the XML button takes on the Frost color and icon with the tex
> buttonColor = "#404450E6"
> buttonFontSize = 300
> originParams = {
> triggeringCard = "ClaypoolsFurs",
> redrawnTokenType = "random",
> VALID_TOKENS = {
> ["Frost"] = true
> }
> VALID_TOKENS = {
> ["Frost"] = true
> }
>
> require...
----------------------------------------------------------]]
local turnOnHelper
function onSave()
return JSON.encode(turnOnHelper)
local isHelperEnabled = false
function updateSave()
self.script_state = JSON.encode({ isHelperEnabled = isHelperEnabled })
end
function onLoad(savedData)
self.addContextMenuItem("Enable Helper", makeXMLButton)
self.addTag("CardWithHelper")
if savedData and savedData ~= "" then
turnOnHelper = JSON.decode(savedData)
if turnOnHelper == true then
makeXMLButton()
end
local loadedData = JSON.decode(savedData)
isHelperEnabled = loadedData.isHelperEnabled
end
checkOptionPanel()
createHelperXML()
updateDisplay()
end
function makeXMLButton()
turnOnHelper = true
self.clearContextMenu()
self.addContextMenuItem("Clear Helper", deleteButton)
local xmlTable = {{
tag = "Button",
attributes = {
height = buttonHeight or 450,
width = buttonWidth or 1400,
rotation = buttonRotation or "0 0 180",
scale = "0.1 0.1 1",
position = buttonPosition or "0 -55 -22",
padding = "50 50 50 50",
font = "font_teutonic-arkham",
fontSize = buttonFontSize or 250,
onClick = "triggerXMLTokenLabelCreation()",
color = buttonColor or "#77674DE6",
textColor = "White"
},
value = buttonValue or "Redraw Token"
}}
function createHelperXML()
local xmlTable = { {
tag = "Button",
attributes = {
active = "false",
id = "Helper",
height = buttonHeight or 450,
width = buttonWidth or 1400,
rotation = buttonRotation or "0 0 180",
scale = "0.1 0.1 1",
position = buttonPosition or "0 -55 -22",
padding = "50 50 50 50",
font = "font_teutonic-arkham",
fontSize = buttonFontSize or 250,
onClick = "triggerXMLTokenLabelCreation",
color = buttonColor or "#77674DE6",
textColor = "White"
},
value = buttonLabel or "Redraw Token"
} }
if buttonIcon then
xmlTable[1].attributes.iconWidth = "400"
xmlTable[1].attributes.iconAlignment = "Right"
xmlTable[1].attributes.icon = buttonIcon
xmlTable[1].attributes.iconWidth = "400"
xmlTable[1].attributes.iconAlignment = "Right"
xmlTable[1].attributes.icon = buttonIcon
end
self.UI.setXmlTable(xmlTable)
end
function triggerXMLTokenLabelCreation()
-- needs to be its own function in order to pass originParams as a table
Global.call("activeRedrawEffect", originParams)
function shutOff()
self.UI.hide("Helper")
end
-- Delete button
function deleteButton()
self.clearContextMenu()
self.addContextMenuItem("Enable Helper", makeXMLButton)
self.UI.setXml("")
turnOnHelper = false
end
function initialize()
self.UI.show("Helper")
end
function triggerXMLTokenLabelCreation()
Global.call("activeRedrawEffect", {
VALID_TOKENS = VALID_TOKENS,
INVALID_TOKENS = INVALID_TOKENS,
RETURN_TO_POOL = RETURN_TO_POOL
})
end

View File

@ -0,0 +1,40 @@
local optionPanelApi = require("core/OptionPanelApi")
-- if the respective option is enabled in onLoad(), enable the helper
function checkOptionPanel()
local options = optionPanelApi.getOptions()
if options.enableCardHelpers then
setHelperState(true)
end
end
-- forces a new state
function setHelperState(newState)
isHelperEnabled = newState
updateSave()
updateDisplay()
end
-- toggles the current state
function toggleHelper()
isHelperEnabled = not isHelperEnabled
updateSave()
updateDisplay()
end
-- updates the visibility and calls events (after a small delay to allow XML being set)
function updateDisplay()
Wait.frames(actualDisplayUpdate, 5)
end
function actualDisplayUpdate()
if isHelperEnabled then
self.clearContextMenu()
self.addContextMenuItem("Disable Helper", toggleHelper)
if initialize then initialize() end
else
self.clearContextMenu()
self.addContextMenuItem("Enable Helper", toggleHelper)
if shutOff then shutOff() end
end
end

View File

@ -1,35 +1,42 @@
require("playercards/CardsWithHelper")
local chaosBagApi = require("chaosbag/ChaosBagApi")
local guidReferenceApi = require("core/GUIDReferenceApi")
local playermatApi = require("playermat/PlayermatApi")
function onLoad(savedData)
self.addContextMenuItem("Enable Helper", createButtons)
if savedData ~= "" then
local loadedData = JSON.decode(savedData)
if loadedData.loopId then
createButtons()
end
end
local isHelperEnabled = false
local loopId
function updateSave()
self.script_state = JSON.encode({
isHelperEnabled = isHelperEnabled,
loopId = loopId
})
end
function deleteButtons()
self.clearContextMenu()
self.addContextMenuItem("Enable Helper", createButtons)
self.UI.setAttribute("inactives", "active", false)
self.UI.setAttribute("actives", "active", false)
function onLoad(savedData)
self.addTag("CardWithHelper")
if savedData and savedData ~= "" then
local loadedData = JSON.decode(savedData)
isHelperEnabled = loadedData.isHelperEnabled
loopId = loadedData.loopId
end
checkOptionPanel()
updateDisplay()
end
-- hide buttons and stop monitoring
function shutOff()
self.UI.hide("Helper")
if loopId then Wait.stop(loopId) end
loopId = nil
self.script_state = JSON.encode({ loopId = loopId })
updateSave()
end
-- create buttons and begin monitoring chaos bag for curse and bless tokens
function createButtons()
self.clearContextMenu()
self.addContextMenuItem("Clear Helper", deleteButtons)
self.UI.setAttribute("inactives", "active", true)
self.UI.setAttribute("actives", "active", true)
-- show buttons and begin monitoring chaos bag for curse and bless tokens
function initialize()
self.UI.show("Helper")
loopId = Wait.time(maybeUpdateButtonState, 1, -1)
self.script_state = JSON.encode({ loopId = loopId })
updateSave()
end
function resolveToken(player, _, tokenType)

View File

@ -1,14 +1,11 @@
buttonValue = "Cancel"
buttonLabel = "Cancel"
buttonIcon = "token-frost"
buttonColor = "#404450E6"
buttonFontSize = 300
originParams = {
triggeringCard = "ClaypoolsFurs",
redrawnTokenType = "random",
VALID_TOKENS = {
["Frost"] = true
}
VALID_TOKENS = {
["Frost"] = true
}
require("playercards/CardsThatRedrawTokens")
require("playercards/CardsWithHelper")
require("playercards/CardsThatRedrawTokens")

View File

@ -1,10 +1,6 @@
originParams = {
triggeringCard = "CustomModifications",
redrawnTokenType = "random",
VALID_TOKENS = {},
INVALID_TOKENS = {
["Auto-fail"] = true
}
INVALID_TOKENS = {
["Auto-fail"] = true
}
require("playercards/CardsThatRedrawTokens")
require("playercards/CardsWithHelper")
require("playercards/CardsThatRedrawTokens")

View File

@ -1,7 +1,5 @@
-- this helper creates buttons to help the user track which hypothesis has been chosen each round
-- (if user forgot to choose one at round start, the old one stays active)
require("playercards/CardsWithHelper")
local playermatApi = require("playermat/PlayermatApi")
local upgradeSheetLibrary = require("playercards/customizable/UpgradeSheetLibrary")
-- common button parameters
local buttonParameters = {}
@ -21,7 +19,7 @@ initialButtonPosition = buttonParameters.position.z
local verticalOffset = 0.325
-- list of customizable labels
local customizableList = {
local customizableList = {
'Run out of cards in hand',
'Take damage/horror',
'Discard treachery/enemy',
@ -29,24 +27,41 @@ local customizableList = {
}
-- index of the currently selected button (0-indexed from the top)
local activeButtonIndex
local activeButtonIndex = -1
local isHelperEnabled = false
local hypothesisList = {}
function onSave()
return JSON.encode(activeButtonIndex)
function updateSave()
self.script_state = JSON.encode({
isHelperEnabled = isHelperEnabled,
activeButtonIndex = activeButtonIndex
})
end
function onLoad(savedData)
self.addContextMenuItem("Enable Helper", createButtons)
self.addContextMenuItem("Clear Helper", deleteButtons)
activeButtonIndex = JSON.decode(savedData)
if activeButtonIndex and activeButtonIndex ~= "" then
local tempButtonIndex = activeButtonIndex
createButtons()
if tempButtonIndex >= 0 then
selectButton(tempButtonIndex)
end
self.addTag("CardWithHelper")
if savedData and savedData ~= "" then
local loadedData = JSON.decode(savedData)
isHelperEnabled = loadedData.isHelperEnabled
activeButtonIndex = loadedData.activeButtonIndex
end
checkOptionPanel()
updateDisplay()
if activeButtonIndex > 0 then
selectButton(activeButtonIndex)
end
end
function initialize()
createButtons()
end
function shutOff()
self.clearButtons()
-- reset the z position
buttonParameters.position.z = initialButtonPosition
end
-- marks a button as active
@ -54,32 +69,19 @@ end
function selectButton(index)
local lastindex = #hypothesisList - 1
for i = 0, lastindex do
local color = Color.Black
local buttonColor = Color.Black
if i == index then
color = Color.Red
buttonColor = Color.Red
activeButtonIndex = i
end
self.editButton({ index = i, color = color })
self.editButton({ index = i, color = buttonColor })
end
end
function deleteButtons()
self.clearButtons()
self.clearContextMenu()
self.addContextMenuItem("Enable Helper", createButtons)
buttonParameters.position.z = initialButtonPosition -- reset the z position
end
-- Create buttons based on the button parameters
function createButtons()
self.clearContextMenu()
self.addContextMenuItem("Clear Helper", deleteButtons)
-- reset the list in case of addition of checkboxes or Refine
hypothesisList = {
'Succeed by 3 or more',
'Fail by 2 or more'
}
hypothesisList = { 'Succeed by 3 or more', 'Fail by 2 or more' }
-- set activeButtonIndex to restore state onLoad ("-1" -> nothing selected)
activeButtonIndex = -1
@ -95,9 +97,9 @@ function createButtons()
end
for i, label in ipairs(hypothesisList) do
buttonParameters.label = label
buttonParameters.click_function = "selectButton" .. i
self.setVar(buttonParameters.click_function, function() selectButton(i - 1) end)
buttonParameters.label = label
self.createButton(buttonParameters)
buttonParameters.position.z = buttonParameters.position.z + verticalOffset
end
@ -105,7 +107,7 @@ end
function findUpgradeSheet()
local matColor = playermatApi.getMatColorByPosition(self.getPosition())
local result = playermatApi.searchAroundPlayermat(matColor, "isCard")
local result = playermatApi.searchAroundPlaymat(matColor, "isCard")
for j, card in ipairs(result) do
local metadata = JSON.decode(card.getGMNotes()) or {}
if metadata.id == "09041-c" then

View File

@ -1,14 +1,12 @@
buttonValue = "Cancel"
buttonLabel = "Cancel"
buttonIcon = "token-curse"
buttonColor = "#633A84E6"
buttonFontSize = 300
originParams = {
triggeringCard = "FalseCovenant",
redrawnTokenType = "random",
VALID_TOKENS = {
["Curse"] = true
}
RETURN_TO_POOL = true
VALID_TOKENS = {
["Curse"] = true
}
require("playercards/CardsThatRedrawTokens")
require("playercards/CardsWithHelper")
require("playercards/CardsThatRedrawTokens")

View File

@ -1,17 +1,14 @@
originParams = {
triggeringCard = "HeavyFurs",
redrawnTokenType = "random",
VALID_TOKENS = {
["Skull"] = true,
["Tablet"] = true,
["Elder Thing"] = true,
["Cultist"] = true,
["Frost"] = true,
["Custom Token"] = true,
["Elder Sign"] = true,
["Bless"] = true,
["Curse"] = true
},
VALID_TOKENS = {
["Skull"] = true,
["Tablet"] = true,
["Elder Thing"] = true,
["Cultist"] = true,
["Frost"] = true,
["Custom Token"] = true,
["Elder Sign"] = true,
["Bless"] = true,
["Curse"] = true
}
require("playercards/CardsThatRedrawTokens")
require("playercards/CardsWithHelper")
require("playercards/CardsThatRedrawTokens")

View File

@ -1,9 +1,8 @@
local chaosBagApi = require("chaosbag/ChaosBagApi")
local guidReferenceApi = require("core/GUIDReferenceApi")
local playermatApi = require("playermat/PlayermatApi")
require("playercards/CardsWithHelper")
local chaosBagApi = require("chaosbag/ChaosBagApi")
-- XML background color for each token
local tokenColor = {
local tokenColor = {
["Skull"] = "#4A0400E6",
["Cultist"] = "#173B0BE6",
["Tablet"] = "#1D2238E6",
@ -89,11 +88,8 @@ function deleteButtons()
end
function resolveSigil()
local tokensInPlay = chaosBagApi.getTokensInPlay()
local chaosbag = chaosBagApi.findChaosBag()
local match = false
for _, obj in ipairs(chaosbag.getObjects()) do
for _, obj in ipairs(chaosBagApi.findChaosBag().getObjects()) do
-- if there are any sigils in the bag
if obj.nickname == sigil then
match = true
@ -106,77 +102,12 @@ function resolveSigil()
return
end
local matchingSymbolsInPlay = {}
for _, token in ipairs(tokensInPlay) do
if (token.getName() == "Cultist"
or token.getName() == "Tablet"
or token.getName() == "Elder Thing")
and token.getName() ~= sigil then
matchingSymbolsInPlay[#matchingSymbolsInPlay + 1] = token
end
end
if #matchingSymbolsInPlay == 0 then
broadcastToAll("No eligible symbol token found in play area", "Red")
return
elseif #matchingSymbolsInPlay > 1 then
for _, token in ipairs(matchingSymbolsInPlay) do
-- draw XML to return token to bag
token.UI.setXmlTable({
{
tag = "VerticalLayout",
attributes = {
height = 275,
width = 275,
spacing = 0,
padding = "0 0 20 25",
scale = "0.4 0.4 1",
rotation = "0 0 180",
position = "0 0 -15",
color = "rgba(0,0,0,0.7)",
onClick = self.getGUID() .. "/drawSigil(" .. token.getGUID() .. ")"
},
children = {
{
tag = "Text",
attributes = {
fontSize = "100",
font = "font_teutonic-arkham",
color = "#ffffff",
text = "Nkosi"
}
},
{
tag = "Text",
attributes = {
fontSize = "125",
font = "font_arkhamicons",
color = "#ffffff",
text = "u"
}
}
}
}
})
end
else
drawSigil(_, matchingSymbolsInPlay[1].getGUID())
end
end
function drawSigil(player, tokenGUID)
local returnedToken = getObjectFromGUID(tokenGUID)
local matColor = playermatApi.getMatColorByPosition(returnedToken.getPosition())
local mat = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat")
chaosBagApi.drawChaosToken(mat, true, sigil, _, returnedToken)
-- remove XML from tokens in play
for _, token in ipairs(chaosBagApi.getTokensInPlay()) do
if token.getName() == "Cultist"
or token.getName() == "Tablet"
or token.getName() == "Elder Thing" then
token.UI.setXml("")
end
end
Global.call("activeRedrawEffect", {
DRAW_SPECIFIC_TOKEN = sigil,
VALID_TOKENS = {
["Tablet"] = true,
["Elder Thing"] = true,
["Cultist"] = true
}
})
end

View File

@ -1,8 +0,0 @@
VALID_TOKENS = {
["Skull"] = true,
["Cultist"] = true,
["Tablet"] = true,
["Elder Thing"] = true,
}
require("playercards/CardsThatSealTokens")

View File

@ -1,10 +1,8 @@
-- this script is shared between both the level 0 and the upgraded level 3 version of the card
require("playercards/CardsWithHelper")
local playermatApi = require("playermat/PlayermatApi")
local modValue, loopId
local buttonParameters = {
click_function = "toggleCounter",
tooltip = "disable counter",
click_function = "shutOff",
function_owner = self,
position = { 0.88, 0.5, -1.33 },
font_size = 150,
@ -12,7 +10,14 @@ local buttonParameters = {
height = 175
}
function onSave() return JSON.encode({ loopId = loopId }) end
local modValue, loopId
function updateSave()
self.script_state = JSON.encode({
isHelperEnabled = isHelperEnabled,
loopId = loopId
})
end
function onLoad(savedData)
-- use metadata to detect level and adjust modValue accordingly
@ -22,30 +27,31 @@ function onLoad(savedData)
modValue = 4
end
if savedData ~= "" then
self.addTag("CardWithHelper")
if savedData and savedData ~= "" then
local loadedData = JSON.decode(savedData)
if loadedData.loopId then
self.createButton(buttonParameters)
loopId = Wait.time(updateDisplay, 2, -1)
end
isHelperEnabled = loadedData.isHelperEnabled
loopId = loadedData.loopId
end
self.addContextMenuItem("Toggle Counter", toggleCounter)
checkOptionPanel()
updateDisplay()
end
function toggleCounter()
if loopId ~= nil then
function initialize()
self.createButton(buttonParameters)
updateButton()
loopId = Wait.time(updateButton, 2, -1)
end
function shutOff()
if loopId then
Wait.stop(loopId)
loopId = nil
self.clearButtons()
else
self.createButton(buttonParameters)
updateDisplay()
loopId = Wait.time(updateDisplay, 2, -1)
end
self.clearButtons()
end
function updateDisplay()
function updateButton()
local matColor = playermatApi.getMatColorByPosition(self.getPosition())
local resources = playermatApi.getCounterValue(matColor, "ResourceCounter")
local count = tostring(math.floor(resources / modValue))

View File

@ -4,9 +4,5 @@ buttonPosition = "70 -70 -22"
buttonFontSize = 200
buttonRotation = "0 0 90"
originParams = {
triggeringCard = "Wendy",
redrawnTokenType = "random",
}
require("playercards/CardsWithHelper")
require("playercards/CardsThatRedrawTokens")

View File

@ -256,11 +256,11 @@ function discardListOfObjects(objList)
deckLib.placeOrMergeIntoDeck(obj, ENCOUNTER_DISCARD_POSITION, { x = 0, y = -90, z = 0 })
end
-- put chaos tokens back into bag (e.g. Unrelenting)
-- put chaos tokens back into bag (e.g. Unrelenting)
elseif tokenChecker.isChaosToken(obj) then
chaosBagApi.returnChaosTokenToBag(obj)
-- don't touch locked objects (like the table etc.) or specific objects (like key tokens)
-- don't touch locked objects (like the table etc.) or specific objects (like key tokens)
elseif not obj.getLock() and not obj.hasTag("DontDiscard") then
ownedObjects.Trash.putObject(obj)
end

View File

@ -161,6 +161,21 @@
</Cell>
</Row>
<!-- Option: Enable all card helpers -->
<Row class="option-text"
tooltip="Enable all card helpers (usually enabled via context menu entries).&#xA;Examples: False Covenant and Book of Living Myths">
<Cell class="option-text">
<Panel class="singleColumn-wrapper">
<Text class="option-header">Enable all card helpers</Text>
</Panel>
</Cell>
<Cell class="option-button">
<Button class="optionToggle"
id="enableCardHelpers"
onClick="onClick_toggleOption"/>
</Cell>
</Row>
<!-- Group: play area settings -->
<Row class="group-header">
<Cell class="group-header">

View File

@ -13,18 +13,18 @@
onClick="resolveToken"
textColor="white"
active="false"/>
<Panel position="0 -55 -22"
<TableLayout position="0 -55 -22"
rotation="0 0 180"
height="900"
width="1400"
scale="0.1 0.1 1"/>
<TableLayout active="false"
scale="0.1 0.1 1"
cellSpacing="80"
cellBackgroundColor="rgba(1,1,1,0)"/>
</Defaults>
<Panel>
<TableLayout id="actives">
<Panel id="Helper"
active="false">
<TableLayout>
<Row>
<Cell>
<Button id="Bless"
@ -42,10 +42,7 @@
</Cell>
</Row>
</TableLayout>
</Panel>
<Panel>
<TableLayout id="inactives">
<TableLayout>
<Row>
<Cell>
<Button id="inactiveBless"