Merge pull request #667 from argonui/slot-display

Slot symbol editing
This commit is contained in:
BootleggerFinn 2024-04-27 18:08:15 -05:00 committed by GitHub
commit 7ad53e2192
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 655 additions and 553 deletions

View File

@ -1,34 +1,9 @@
[
{
"Name": "refresh",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/1695031152736214852/EC3BBEF1A1788381A8F4C5ACB7FB27770CAF03C5/"
},
{
"Name": "close",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/1695031152736214756/2EEB07E453A7ECF4BE5A1030A253185B37A7CDAB/"
},
{
"Name": "cthulhu",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/1782854877010107768/BC6A97F193385D01C1A9149B68923F55A284CB2D/"
},
{
"Name": "dark-cult",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/1782854877010108105/08594607341D6537C28A08A34CE82159025AB8DB/"
},
{
"Name": "yog-sothoth",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/1782854877010107124/D8042D1A1B08CFB7E76488B09216B4611D85A2B9/"
},
{
"Name": "elder-sign",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/1782854877010107442/43BC029410751208A90AE7FDEBCB587A0E9403D7/"
},
{
"Name": "devourer",
"Type": 0,
@ -55,40 +30,15 @@
"URL": "http://cloud-3.steamusercontent.com/ugc/2026086584372569912/5CB461AEAE2E59D3064D90A776EB86C46081EC78/"
},
{
"Name": "font_arkhamslim",
"Name": "font_arkhamicons",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2510267299454546112/8CDF773519FEC8C488569072280AC848BCC293D5/"
},
{
"Name": "font_birmingham",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118466443497/3CF9BB9AF968D245961494CC9A151774EB9BA638/"
},
{
"Name": "font_columbus",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118466515872/F473E4ACC75ACB6CE07457C45290B4912E0B3286/"
},
{
"Name": "font_oldremington",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118466515932/AFCE53F1E1D9580D166F53AD9EB0D77A331D4A26/"
"URL": "http://cloud-3.steamusercontent.com/ugc/2462982115649258367/C20CC4C299A6FE5F1ECAB968E15BE590337CC019/"
},
{
"Name": "font_teutonic-arkham",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118467703445/89328E273B4C5180BF491516CE998DE3C604E162/"
},
{
"Name": "font_uglyqua",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118466516005/113C19D37CFFA9E554394FD5B11B32967F846A62/"
},
{
"Name": "font_chinese_fzlibian",
"Type": 1,
"URL": "http://cloud-3.steamusercontent.com/ugc/2028355502896482829/8DAB311590B97586309E66D795AC2C43D4913188/"
},
{
"Name": "header_cover",
"Type": 0,
@ -124,11 +74,6 @@
"Type": 0,
"URL": "https://i.imgur.com/6MReiEO.png"
},
{
"Name": "Inv-Roland",
"Type": 0,
"URL": "https://i.imgur.com/lx6unDY.png"
},
{
"Name": "NextArrow",
"Type": 0,
@ -139,6 +84,11 @@
"Type": 0,
"URL": "https://i.imgur.com/8qmTXwt.png"
},
{
"Name": "Inv-Roland",
"Type": 0,
"URL": "https://i.imgur.com/lx6unDY.png"
},
{
"Name": "Inv-Mandy",
"Type": 0,
@ -285,7 +235,7 @@
"URL": "http://cloud-3.steamusercontent.com/ugc/2510267932886739653/CB7AA2D73777EF5938A6E6CD664B2ABA52B6E20A/"
},
{
"Name": "token-custom",
"Name": "token-custom-token",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/2380784374792650571/E4C2B2B69282A4EE15FE290FF6B08BEFC8FCA65C/"
}

View File

@ -57,9 +57,9 @@
},
{
"Position": {
"x": -0.631,
"x": 1.758,
"y": 0.1,
"z": 0.551
"z": 0.04
},
"Tags": [
"Asset"
@ -67,39 +67,9 @@
},
{
"Position": {
"x": -0.616,
"y": 0.102,
"z": 0.024
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.177,
"y": 0.101,
"z": 0.032
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.174,
"y": 0.099,
"z": 0.551
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.212,
"x": 1.371,
"y": 0.1,
"z": 0.559
"z": 0.038
},
"Tags": [
"Asset"
@ -107,7 +77,7 @@
},
{
"Position": {
"x": 0.217,
"x": 0.98,
"y": 0.1,
"z": 0.035
},
@ -127,28 +97,8 @@
},
{
"Position": {
"x": 0.605,
"x": 0.217,
"y": 0.1,
"z": 0.555
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.977,
"y": 0.099,
"z": 0.556
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.98,
"y": 0.099,
"z": 0.035
},
"Tags": [
@ -157,9 +107,9 @@
},
{
"Position": {
"x": 1.371,
"x": -0.177,
"y": 0.1,
"z": 0.038
"z": 0.032
},
"Tags": [
"Asset"
@ -167,9 +117,9 @@
},
{
"Position": {
"x": 1.371,
"y": 0.099,
"z": 0.558
"x": -0.616,
"y": 0.1,
"z": 0.024
},
"Tags": [
"Asset"
@ -187,9 +137,59 @@
},
{
"Position": {
"x": 1.758,
"y": 0.101,
"z": 0.04
"x": 1.371,
"y": 0.1,
"z": 0.558
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.977,
"y": 0.1,
"z": 0.556
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.605,
"y": 0.1,
"z": 0.555
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.212,
"y": 0.1,
"z": 0.559
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.174,
"y": 0.1,
"z": 0.551
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.631,
"y": 0.1,
"z": 0.551
},
"Tags": [
"Asset"
@ -329,7 +329,7 @@
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/2037357630681963618/E7271737B19CE0BFAAA382BEEEF497FE3E06ECC1/",
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/2462982115659543571/5D778EA4BC682DAE97E8F59A991BCF8CB3979B04/",
"WidthScale": 0
},
"Description": "",

View File

@ -1 +1 @@
{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"White"}
{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"White","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}

View File

@ -57,9 +57,9 @@
},
{
"Position": {
"x": -0.631,
"x": 1.758,
"y": 0.1,
"z": 0.551
"z": 0.04
},
"Tags": [
"Asset"
@ -67,39 +67,9 @@
},
{
"Position": {
"x": -0.616,
"y": 0.102,
"z": 0.024
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.177,
"y": 0.101,
"z": 0.032
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.174,
"y": 0.099,
"z": 0.551
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.212,
"x": 1.371,
"y": 0.1,
"z": 0.559
"z": 0.038
},
"Tags": [
"Asset"
@ -107,7 +77,7 @@
},
{
"Position": {
"x": 0.217,
"x": 0.98,
"y": 0.1,
"z": 0.035
},
@ -127,28 +97,8 @@
},
{
"Position": {
"x": 0.605,
"x": 0.217,
"y": 0.1,
"z": 0.555
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.977,
"y": 0.099,
"z": 0.556
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.98,
"y": 0.099,
"z": 0.035
},
"Tags": [
@ -157,9 +107,9 @@
},
{
"Position": {
"x": 1.371,
"x": -0.177,
"y": 0.1,
"z": 0.038
"z": 0.032
},
"Tags": [
"Asset"
@ -167,9 +117,9 @@
},
{
"Position": {
"x": 1.371,
"y": 0.099,
"z": 0.558
"x": -0.616,
"y": 0.1,
"z": 0.024
},
"Tags": [
"Asset"
@ -187,9 +137,59 @@
},
{
"Position": {
"x": 1.758,
"y": 0.101,
"z": 0.04
"x": 1.371,
"y": 0.1,
"z": 0.558
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.977,
"y": 0.1,
"z": 0.556
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.605,
"y": 0.1,
"z": 0.555
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.212,
"y": 0.1,
"z": 0.559
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.174,
"y": 0.1,
"z": 0.551
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.631,
"y": 0.1,
"z": 0.551
},
"Tags": [
"Asset"
@ -329,7 +329,7 @@
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/2037357630681963618/E7271737B19CE0BFAAA382BEEEF497FE3E06ECC1/",
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/2462982115659543571/5D778EA4BC682DAE97E8F59A991BCF8CB3979B04/",
"WidthScale": 0
},
"Description": "",

View File

@ -1 +1 @@
{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Orange"}
{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Orange","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}

View File

@ -57,9 +57,9 @@
},
{
"Position": {
"x": -0.631,
"x": 1.758,
"y": 0.1,
"z": 0.551
"z": 0.04
},
"Tags": [
"Asset"
@ -67,39 +67,9 @@
},
{
"Position": {
"x": -0.616,
"y": 0.102,
"z": 0.024
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.177,
"y": 0.101,
"z": 0.032
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.174,
"y": 0.099,
"z": 0.551
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.212,
"x": 1.371,
"y": 0.1,
"z": 0.559
"z": 0.038
},
"Tags": [
"Asset"
@ -107,7 +77,7 @@
},
{
"Position": {
"x": 0.217,
"x": 0.98,
"y": 0.1,
"z": 0.035
},
@ -127,28 +97,8 @@
},
{
"Position": {
"x": 0.605,
"x": 0.217,
"y": 0.1,
"z": 0.555
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.977,
"y": 0.099,
"z": 0.556
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.98,
"y": 0.099,
"z": 0.035
},
"Tags": [
@ -157,9 +107,9 @@
},
{
"Position": {
"x": 1.371,
"x": -0.177,
"y": 0.1,
"z": 0.038
"z": 0.032
},
"Tags": [
"Asset"
@ -167,9 +117,9 @@
},
{
"Position": {
"x": 1.371,
"y": 0.099,
"z": 0.558
"x": -0.616,
"y": 0.1,
"z": 0.024
},
"Tags": [
"Asset"
@ -187,9 +137,59 @@
},
{
"Position": {
"x": 1.758,
"y": 0.101,
"z": 0.04
"x": 1.371,
"y": 0.1,
"z": 0.558
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.977,
"y": 0.1,
"z": 0.556
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.605,
"y": 0.1,
"z": 0.555
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.212,
"y": 0.1,
"z": 0.559
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.174,
"y": 0.1,
"z": 0.551
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.631,
"y": 0.1,
"z": 0.551
},
"Tags": [
"Asset"
@ -329,7 +329,7 @@
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/2037357630681963618/E7271737B19CE0BFAAA382BEEEF497FE3E06ECC1/",
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/2462982115659543571/5D778EA4BC682DAE97E8F59A991BCF8CB3979B04/",
"WidthScale": 0
},
"Description": "",

View File

@ -1 +1 @@
{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Green"}
{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Green","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}

View File

@ -57,9 +57,9 @@
},
{
"Position": {
"x": -0.631,
"x": 1.758,
"y": 0.1,
"z": 0.551
"z": 0.04
},
"Tags": [
"Asset"
@ -67,39 +67,9 @@
},
{
"Position": {
"x": -0.616,
"y": 0.102,
"z": 0.024
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.177,
"y": 0.101,
"z": 0.032
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.174,
"y": 0.099,
"z": 0.551
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.212,
"x": 1.371,
"y": 0.1,
"z": 0.559
"z": 0.038
},
"Tags": [
"Asset"
@ -107,7 +77,7 @@
},
{
"Position": {
"x": 0.217,
"x": 0.98,
"y": 0.1,
"z": 0.035
},
@ -127,28 +97,8 @@
},
{
"Position": {
"x": 0.605,
"x": 0.217,
"y": 0.1,
"z": 0.555
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.977,
"y": 0.099,
"z": 0.556
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.98,
"y": 0.099,
"z": 0.035
},
"Tags": [
@ -157,9 +107,9 @@
},
{
"Position": {
"x": 1.371,
"x": -0.177,
"y": 0.1,
"z": 0.038
"z": 0.032
},
"Tags": [
"Asset"
@ -167,9 +117,9 @@
},
{
"Position": {
"x": 1.371,
"y": 0.099,
"z": 0.558
"x": -0.616,
"y": 0.1,
"z": 0.024
},
"Tags": [
"Asset"
@ -187,9 +137,59 @@
},
{
"Position": {
"x": 1.758,
"y": 0.101,
"z": 0.04
"x": 1.371,
"y": 0.1,
"z": 0.558
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.977,
"y": 0.1,
"z": 0.556
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.605,
"y": 0.1,
"z": 0.555
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": 0.212,
"y": 0.1,
"z": 0.559
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.174,
"y": 0.1,
"z": 0.551
},
"Tags": [
"Asset"
]
},
{
"Position": {
"x": -0.631,
"y": 0.1,
"z": 0.551
},
"Tags": [
"Asset"
@ -329,7 +329,7 @@
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/2037357630681963618/E7271737B19CE0BFAAA382BEEEF497FE3E06ECC1/",
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/2462982115659543571/5D778EA4BC682DAE97E8F59A991BCF8CB3979B04/",
"WidthScale": 0
},
"Description": "",
@ -344,7 +344,7 @@
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/Playmat\")",
"LuaScriptState": "{\"activeInvestigatorId\":\"00000\",\"isDrawButtonVisible\":false,\"playerColor\":\"Red\"}",
"LuaScriptState_path": "Playermat4Red.0840d5.luascriptstate",
"MeasureMovement": false,
"Memo": "Red",
"Name": "Custom_Tile",

View File

@ -0,0 +1 @@
{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Red","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}

View File

@ -37,7 +37,7 @@ function triggerUpkeep(playerColor)
end
-- triggers the "Upkeep" function of the calling player's playmat AND
-- for all playmats that don't have a seated player, but a investigator card
-- for all playmats that don't have a seated player, but an investigator card
function triggerUpkeepMultihanded(playerColor)
if playerColor ~= "Black" then
triggerUpkeep(playerColor)

View File

@ -2,28 +2,17 @@ local chaosBagApi = require("chaosbag/ChaosBagApi")
local guidReferenceApi = require("core/GUIDReferenceApi")
local playmatApi = require("playermat/PlaymatApi")
local tokenNames = {
"Skull",
"Cultist",
"Tablet",
"Elder Thing",
"Auto-fail",
"Bless",
"Curse",
"Frost",
"Custom Token"
}
local dataForToken = {
["Skull"] = { color = "#4A0400E6", icon = "token-skull" },
["Cultist"] = { color = "#173B0BE6", icon = "token-cultist" },
["Tablet"] = { color = "#1D2238E6", icon = "token-tablet" },
["Elder Thing"] = { color = "#4D2331E6", icon = "token-elder-thing" },
["Auto-fail"] = { color = "#9B0004E6", icon = "token-auto-fail" },
["Bless"] = { color = "#9D702CE6", icon = "token-bless" },
["Curse"] = { color = "#633A84E6", icon = "token-curse" },
["Frost"] = { color = "#404450E6", icon = "token-frost" },
[""] = { color = "#77674DE6", icon = "token-custom" }
-- XML background color for each token
local tokenColor = {
["Skull"] = "#4A0400E6",
["Cultist"] = "#173B0BE6",
["Tablet"] = "#1D2238E6",
["Elder Thing"] = "#4D2331E6",
["Auto-fail"] = "#9B0004E6",
["Bless"] = "#9D702CE6",
["Curse"] = "#633A84E6",
["Frost"] = "#404450E6",
[""] = "#77674DE6"
}
local sigil
@ -36,13 +25,18 @@ function onLoad(savedData)
self.addContextMenuItem("Enable Helper", chooseSigil)
sigil = JSON.decode(savedData)
if sigil and sigil ~= nil then
makeXMLButton(sigil)
makeXMLButton()
self.clearContextMenu()
self.addContextMenuItem("Clear Helper", deleteButtons)
end
end
function makeXMLButton(chosenToken)
function makeXMLButton()
-- get name of the icon for the sigil ("token" + lowercase name without space characters)
local sigilName = Global.call("getReadableTokenName", sigil)
local iconName = "token-" .. string.lower(sigilName)
iconName = iconName:gsub("%s", "-")
self.UI.setXmlTable({
{
tag = "Button",
@ -55,15 +49,15 @@ function makeXMLButton(chosenToken)
padding = "50 50 50 50",
font = "font_teutonic-arkham",
fontSize = 300,
iconWidth = 400,
iconWidth = "400",
iconAlignment = "Right",
onClick = "resolveSigil",
id = sigil,
icon = dataForToken[sigil].icon,
color = dataForToken[sigil].color,
textColor = "White",
icon = iconName,
color = tokenColor[sigil],
textColor = "White"
},
value = "Resolve",
value = "Resolve"
}
}
)
@ -73,10 +67,18 @@ end
function chooseSigil(playerColor)
self.clearContextMenu()
self.addContextMenuItem("Clear Helper", deleteButtons)
Player[playerColor].showOptionsDialog("Choose Sigil", tokenNames, 1,
-- get list of readable names
local readableNames = {}
for token, _ in pairs(tokenColor) do
table.insert(readableNames, Global.call("getReadableTokenName", token))
end
-- prompt player to choose sigil
Player[playerColor].showOptionsDialog("Choose Sigil", readableNames, 1,
function(chosenToken)
sigil = Global.call("getChaosTokenName", chosenToken)
makeXMLButton(sigil)
makeXMLButton()
end
)
end
@ -92,14 +94,16 @@ end
function resolveSigil()
local tokensInPlay = chaosBagApi.getTokensInPlay()
local chaosbag = chaosBagApi.findChaosBag()
local match = false
for i, obj in ipairs(chaosbag.getObjects()) do
for _, obj in ipairs(chaosbag.getObjects()) do
-- if there are any sigils in the bag
if obj.nickname == sigil then
match = true
break
end
end
if not match then
broadcastToAll(Global.call("getReadableTokenName", sigil) .. " not found in chaos bag", "Red")
return
@ -107,8 +111,11 @@ function resolveSigil()
local matchingSymbolsInPlay = {}
for j, token in ipairs(tokensInPlay) do
if (token.getName() == "Cultist" or token.getName() == "Elder Thing" or token.getName() == "Tablet") and token.getName() ~= sigil then
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
@ -117,7 +124,7 @@ function resolveSigil()
broadcastToAll("No eligible symbol token found in play area", "Red")
return
elseif #matchingSymbolsInPlay > 1 then
for j, token in ipairs(matchingSymbolsInPlay) do
for _, token in ipairs(matchingSymbolsInPlay) do
-- draw XML to return token to bag
token.UI.setXmlTable({
{
@ -131,7 +138,7 @@ function resolveSigil()
rotation = "0 0 180",
position = "0 0 -15",
color = "rgba(0,0,0,0.7)",
onClick = self.getGUID() .. "/drawSigil(" .. token.getGUID() .. ")",
onClick = self.getGUID() .. "/drawSigil(" .. token.getGUID() .. ")"
},
children = {
{
@ -140,18 +147,18 @@ function resolveSigil()
fontSize = "100",
font = "font_teutonic-arkham",
color = "#ffffff",
text = "Nkosi",
},
text = "Nkosi"
}
},
{
tag = "Text",
attributes = {
fontSize = "125",
font = "font_arkhamslim",
font = "font_arkhamicons",
color = "#ffffff",
text = "U",
},
},
text = "u"
}
}
}
}
})
@ -162,15 +169,17 @@ function resolveSigil()
end
function drawSigil(player, tokenGUID)
returnedToken = getObjectFromGUID(tokenGUID)
local returnedToken = getObjectFromGUID(tokenGUID)
local matColor = playmatApi.getMatColorByPosition(returnedToken.getPosition())
local mat = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat")
chaosBagApi.drawChaosToken(mat, true, sigil, _, returnedToken)
local tokensInPlay = chaosBagApi.getTokensInPlay()
for j, returnedToken in ipairs(tokensInPlay) do
if returnedToken.getName() == "Cultist" or returnedToken.getName() == "Elder Thing" or returnedToken.getName() == "Tablet" then
returnedToken.UI.setXml("")
-- 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
end

View File

@ -1,106 +1,113 @@
local chaosBagApi = require("chaosbag/ChaosBagApi")
local deckLib = require("util/DeckLib")
local guidReferenceApi = require("core/GUIDReferenceApi")
local mythosAreaApi = require("core/MythosAreaApi")
local navigationOverlayApi = require("core/NavigationOverlayApi")
local searchLib = require("util/SearchLib")
local tokenChecker = require("core/token/TokenChecker")
local tokenManager = require("core/token/TokenManager")
local chaosBagApi = require("chaosbag/ChaosBagApi")
local deckLib = require("util/DeckLib")
local guidReferenceApi = require("core/GUIDReferenceApi")
local mythosAreaApi = require("core/MythosAreaApi")
local navigationOverlayApi = require("core/NavigationOverlayApi")
local searchLib = require("util/SearchLib")
local tokenChecker = require("core/token/TokenChecker")
local tokenManager = require("core/token/TokenManager")
-- we use this to turn off collision handling until onLoad() is complete
local collisionEnabled = false
local collisionEnabled = false
local currentlyEditingSlots = false
-- x-Values for discard buttons
local DISCARD_BUTTON_OFFSETS = {-1.365, -0.91, -0.455, 0, 0.455, 0.91}
local DISCARD_BUTTON_X_START = -1.365
local DISCARD_BUTTON_X_OFFSET = 0.455
local SEARCH_AROUND_SELF_X_BUFFER = 8
-- defined areas for object searching
local MAIN_PLAY_AREA = {
upperLeft = {
x = 1.98,
z = 0.736
},
lowerRight = {
x = -0.79,
z = -0.39
}
local MAIN_PLAY_AREA = {
upperLeft = { x = 1.98, z = 0.736 },
lowerRight = { x = -0.79, z = -0.39 }
}
local INVESTIGATOR_AREA = {
upperLeft = {
x = -1.084,
z = 0.06517
},
lowerRight = {
x = -1.258,
z = -0.0805
}
local INVESTIGATOR_AREA = {
upperLeft = { x = -1.084, z = 0.06517 },
lowerRight = { x = -1.258, z = -0.0805 }
}
local THREAT_AREA = {
upperLeft = {
x = 1.53,
z = -0.34
},
lowerRight = {
x = -1.13,
z = -0.92
}
local THREAT_AREA = {
upperLeft = { x = 1.53, z = -0.34 },
lowerRight = { x = -1.13, z = -0.92 }
}
local DECK_DISCARD_AREA = {
upperLeft = {
x = -1.62,
z = 0.855
},
lowerRight = {
x = -2.02,
z = -0.245
},
center = {
x = -1.82,
y = 0.5,
z = 0.305
},
size = {
x = 0.4,
y = 3,
z = 1.1
}
local DECK_DISCARD_AREA = {
upperLeft = { x = -1.62, z = 0.855 },
lowerRight = { x = -2.02, z = -0.245 },
center = { x = -1.82, y = 0.5, z = 0.305 },
size = { x = 0.4, y = 3, z = 1.1 }
}
-- local position of draw and discard pile
local DRAW_DECK_POSITION = { x = -1.82, y = 0.1, z = 0 }
local DISCARD_PILE_POSITION = { x = -1.82, y = 0.1, z = 0.61 }
local DRAW_DECK_POSITION = { x = -1.82, y = 0.1, z = 0 }
local DISCARD_PILE_POSITION = { x = -1.82, y = 0.1, z = 0.61 }
-- global position of encounter discard pile
local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38}
local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38 }
-- used for the buttons on the right side of the playmat
-- starts off with the data for the "Upkeep" button and will then be changed
local buttonParameters = {
label = "Upkeep",
click_function = "doUpkeep",
tooltip = "Right-click to change color",
function_owner = self,
position = { x = 1.82, y = 0.1, z = -0.45 },
scale = { 0.12, 0.12, 0.12 },
width = 1000,
height = 280,
font_size = 180
}
-- translation table for slot names to characters for special font
local slotNameToChar = {
["any"] = "",
["Accessory"] = "C",
["Ally"] = "E",
["Arcane"] = "G",
["Body"] = "K",
["Hand (right)"] = "M",
["Hand (left)"] = "M",
["Hand x2"] = "N",
["Tarot"] = "A"
}
-- slot symbol for the respective slot (from top left to bottom right)
local slotData = {}
local defaultSlotData = {
-- 1st row
"any", "any", "any", "Tarot", "Hand (left)", "Hand (right)", "Ally",
-- 2nd row
"any", "any", "any", "Accessory", "Arcane", "Arcane", "Body"
}
-- global variable so it can be reset by the Clean Up Helper
activeInvestigatorId = "00000"
-- table of type-object reference pairs of all owned objects
local ownedObjects = {}
local matColor = self.getMemo()
-- variable to track the status of the "Show Draw Button" option
local isDrawButtonVisible = false
activeInvestigatorId = "00000"
local isDrawButtonVisible = false
-- global variable to report "Dream-Enhancing Serum" status
isDES = false
isDES = false
-- table of type-object reference pairs of all owned objects
local ownedObjects = {}
local matColor = self.getMemo()
function onSave()
return JSON.encode({
playerColor = playerColor,
activeInvestigatorId = activeInvestigatorId,
isDrawButtonVisible = isDrawButtonVisible
isDrawButtonVisible = isDrawButtonVisible,
slotData = slotData
})
end
function onLoad(savedData)
if savedData and savedData ~= "" then
local loadedData = JSON.decode(savedData)
playerColor = loadedData.playerColor
local loadedData = JSON.decode(savedData)
playerColor = loadedData.playerColor
activeInvestigatorId = loadedData.activeInvestigatorId
isDrawButtonVisible = loadedData.isDrawButtonVisible
isDrawButtonVisible = loadedData.isDrawButtonVisible
slotData = loadedData.slotData
end
self.interactable = false
@ -108,16 +115,16 @@ function onLoad(savedData)
-- get object references to owned objects
ownedObjects = guidReferenceApi.getObjectsByOwner(matColor)
-- button creation
-- discard button creation
for i = 1, 6 do
makeDiscardButton(DISCARD_BUTTON_OFFSETS[i], i)
makeDiscardButton(i)
end
self.createButton({
click_function = "drawEncounterCard",
function_owner = self,
position = {-1.84, 0, -0.65},
rotation = {0, 80, 0},
position = { -1.84, 0, -0.65 },
rotation = { 0, 80, 0 },
width = 265,
height = 190
})
@ -125,24 +132,24 @@ function onLoad(savedData)
self.createButton({
click_function = "drawChaosTokenButton",
function_owner = self,
position = {1.85, 0, -0.74},
rotation = {0, -45, 0},
position = { 1.85, 0, -0.74 },
rotation = { 0, -45, 0 },
width = 135,
height = 135
})
self.createButton({
label = "Upkeep",
click_function = "doUpkeep",
function_owner = self,
position = {1.84, 0.1, -0.44},
scale = {0.12, 0.12, 0.12},
width = 800,
height = 280,
font_size = 180
})
-- Upkeep button: can use the default parameters for this
self.createButton(buttonParameters)
-- Slot editing button: modified default data
buttonParameters.label = "Edit Slots"
buttonParameters.click_function = "toggleSlotEditing"
buttonParameters.tooltip = "Right-click to reset slot symbols"
buttonParameters.position.z = 0.92
self.createButton(buttonParameters)
showDrawButton(isDrawButtonVisible)
redrawSlotSymbols()
math.randomseed(os.time())
Wait.time(function() collisionEnabled = true end, 0.1)
end
@ -178,24 +185,39 @@ function searchDeckAndDiscardArea(filter)
local scale = self.getScale()
local size = {
x = DECK_DISCARD_AREA.size.x * scale.x,
y = DECK_DISCARD_AREA.size.y,
y = DECK_DISCARD_AREA.size.y,
z = DECK_DISCARD_AREA.size.z * scale.z
}
return searchArea(pos, size, filter)
end
function doNotReady(card)
return card.getVar("do_not_ready") or false
end
-- rounds a number to the specified amount of decimal places
---@param num number Initial value
---@param numDecimalPlaces number Amount of decimal places
---@return number: rounded number
function round(num, numDecimalPlaces)
local mult = 10^(numDecimalPlaces or 0)
local mult = 10 ^ (numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
end
-- edits the label of a button
---@param oldLabel string Old label of the button
---@param newLabel string New label of the button
function editButtonLabel(oldLabel, newLabel)
local buttons = self.getButtons()
for i = 1, #buttons do
if buttons[i].label == oldLabel then
self.editButton({ index = buttons[i].index, label = newLabel })
end
end
end
-- updates the internal "messageColor" which is used for print/broadcast statements if no player is seated
---@param clickedByColor string Colorstring of player who clicked a button
function updateMessageColor(clickedByColor)
messageColor = Player[playerColor].seated and playerColor or clickedByColor
end
---------------------------------------------------------
-- Discard buttons
---------------------------------------------------------
@ -208,25 +230,29 @@ function discardListOfObjects(objList)
if obj.hasTag("PlayerCard") then
deckLib.placeOrMergeIntoDeck(obj, returnGlobalDiscardPosition(), self.getRotation())
else
deckLib.placeOrMergeIntoDeck(obj, ENCOUNTER_DISCARD_POSITION, {x = 0, y = -90, z = 0})
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
end
end
-- build a discard button to discard from searchPosition (number must be unique)
function makeDiscardButton(xValue, number)
local position = { xValue, 0.1, -0.94}
local searchPosition = {-position[1], position[2], position[3] + 0.32}
local handlerName = 'handler' .. number
-- build a discard button to discard from searchPosition
---@param id number Index of the discard button (from left to right, must be unique)
function makeDiscardButton(id)
local xValue = DISCARD_BUTTON_X_START + (id - 1) * DISCARD_BUTTON_X_OFFSET
local position = { xValue, 0.1, -0.94 }
local searchPosition = { -position[1], position[2], position[3] + 0.32 }
local handlerName = 'handler' .. id
self.setVar(handlerName, function()
local cardSizeSearch = {2, 1, 3.2}
local cardSizeSearch = { 2, 1, 3.2 }
local globalSearchPosition = self.positionToWorld(searchPosition)
local searchResult = searchArea(globalSearchPosition, cardSizeSearch)
return discardListOfObjects(searchResult)
@ -236,7 +262,7 @@ function makeDiscardButton(xValue, number)
click_function = handlerName,
function_owner = self,
position = position,
scale = {0.12, 0.12, 0.12},
scale = { 0.12, 0.12, 0.12 },
width = 900,
height = 350,
font_size = 220
@ -248,8 +274,8 @@ end
---------------------------------------------------------
-- calls the Upkeep function with correct parameter
function doUpkeepFromHotkey(color)
doUpkeep(_, color)
function doUpkeepFromHotkey(clickedByColor)
doUpkeep(_, clickedByColor)
end
function doUpkeep(_, clickedByColor, isRightClick)
@ -258,8 +284,7 @@ function doUpkeep(_, clickedByColor, isRightClick)
return
end
-- send messages to player who clicked button if no seated player found
messageColor = Player[playerColor].seated and playerColor or clickedByColor
updateMessageColor(clickedByColor)
-- unexhaust cards in play zone, flip action tokens and find forcedLearning
local forcedLearning = false
@ -269,7 +294,7 @@ function doUpkeep(_, clickedByColor, isRightClick)
obj.flip()
elseif obj.type == "Card" and not inArea(self.positionToLocal(obj.getPosition()), INVESTIGATOR_AREA) then
local cardMetadata = JSON.decode(obj.getGMNotes()) or {}
if not doNotReady(obj) then
if not (obj.getVar("do_not_ready") or false) then
local cardRotation = round(obj.getRotation().y, 0) - rot.y
local yRotDiff = 0
@ -286,16 +311,20 @@ function doUpkeep(_, clickedByColor, isRightClick)
-- set correct rotation for face-down cards
rot.z = obj.is_face_down and 180 or 0
obj.setRotation({rot.x, rot.y + yRotDiff, rot.z})
obj.setRotation({ rot.x, rot.y + yRotDiff, rot.z })
end
-- detect forced learning to handle card drawing accordingly
if cardMetadata.id == "08031" then
forcedLearning = true
end
-- maybe replenish uses on certain cards
if cardMetadata.uses ~= nil then
tokenManager.maybeReplenishCard(obj, cardMetadata.uses, self)
end
-- check decks for forced learning
elseif obj.type == "Deck" and forcedLearning == false then
-- check decks for forced learning
for _, deepObj in ipairs(obj.getObjects()) do
local cardMetadata = JSON.decode(deepObj.gm_notes) or {}
if cardMetadata.id == "08031" then
@ -319,16 +348,17 @@ function doUpkeep(_, clickedByColor, isRightClick)
-- gain a resource (or two if playing Jenny Barnes)
if string.match(activeInvestigatorId, "%d%d%d%d%d") == "02003" then
updateCounter({type = "ResourceCounter", modifier = 2})
updateCounter({ type = "ResourceCounter", modifier = 2 })
printToColor("Gaining 2 resources (Jenny)", messageColor)
else
updateCounter({type = "ResourceCounter", modifier = 1})
updateCounter({ type = "ResourceCounter", modifier = 1 })
end
-- draw a card (with handling for Patrice and Forced Learning)
if activeInvestigatorId == "06005" then
if forcedLearning then
printToColor("Wow, did you really take 'Versatile' to play Patrice with 'Forced Learning'? Choose which draw replacement effect takes priority and draw cards accordingly.", messageColor)
printToColor("Wow, did you really take 'Versatile' to play Patrice with 'Forced Learning'?"
.. " Choose which draw replacement effect takes priority and draw cards accordingly.", messageColor)
else
local handSize = #Player[playerColor].getHandObjects()
if handSize < 5 then
@ -348,14 +378,14 @@ function doUpkeep(_, clickedByColor, isRightClick)
end
end
-- function for "draw 1 button" (that can be added via option panel)
function doDrawOne(_, color)
-- send messages to player who clicked button if no seated player found
messageColor = Player[playerColor].seated and playerColor or color
-- click function for "draw 1 button" (that can be added via option panel)
function doDrawOne(_, clickedByColor)
updateMessageColor(clickedByColor)
drawCardsWithReshuffle(1)
end
-- draw X cards (shuffle discards if necessary)
-- draws the specified amount of cards (and shuffles the discard if necessary)
---@param numCards number Number of cards to draw
function drawCardsWithReshuffle(numCards)
local deckAreaObjects = getDeckAreaObjects()
@ -416,12 +446,13 @@ function drawCardsWithReshuffle(numCards)
end
-- get the draw deck and discard pile objects and returns the references
---@return table: string-indexed table with references to the found objects
function getDeckAreaObjects()
local deckAreaObjects = {}
for _, object in ipairs(searchDeckAndDiscardArea("isCardOrDeck")) do
if self.positionToLocal(object.getPosition()).z > 0.5 then
deckAreaObjects.discard = object
-- Norman Withers handling
-- Norman Withers handling
elseif object.type == "Card" and not object.is_face_down then
deckAreaObjects.topCard = object
else
@ -431,6 +462,8 @@ function getDeckAreaObjects()
return deckAreaObjects
end
-- draws the specified number of cards (reshuffling of discard pile is handled separately)
---@param numCards number Number of cards to draw
function drawCards(numCards)
local deckAreaObjects = getDeckAreaObjects()
if deckAreaObjects.draw then
@ -469,7 +502,7 @@ end
function doDiscardOne()
local hand = Player[playerColor].getHandObjects()
if #hand == 0 then
broadcastToAll("Cannot discard from empty hand!", "Red")
broadcastToColor("Cannot discard from empty hand!", messageColor, "Red")
else
local choices = {}
for i = 1, #hand do
@ -484,7 +517,7 @@ function doDiscardOne()
end
if #choices == 0 then
broadcastToAll("Hidden cards can't be randomly discarded.", "Orange")
broadcastToColor("Hidden cards can't be randomly discarded.", messageColor, "Orange")
return
end
@ -497,29 +530,146 @@ function doDiscardOne()
end
end
---------------------------------------------------------
-- slot symbol displaying
---------------------------------------------------------
-- this will redraw the XML for the slot symbols based on the slotData table
function redrawSlotSymbols()
local xml = {}
local snapId = 0
-- use the snap point positions in the main play area for positions
for _, snap in ipairs(self.getSnapPoints()) do
if inArea(snap.position, MAIN_PLAY_AREA) then
snapId = snapId + 1
local slotName = slotData[snapId]
-- conversion from regular coordinates to XML
local x = snap.position.x * 100
local y = snap.position.z * 100
-- XML for a single slot (panel with text in the special font)
local slotXML = {
tag = "Panel",
attributes = {
id = "slotPanel" .. snapId,
scale = "0.1 0.1 1",
width = "175",
height = "175",
position = x .. " " .. y .. " -11"
},
children = {
{
tag = "Text",
attributes = {
id = "slot" .. snapId,
rotation = getSlotRotation(slotName),
fontSize = "145",
font = "font_arkhamicons",
color = "#414141CB",
text = slotNameToChar[slotName]
}
}
}
}
table.insert(xml, slotXML)
end
end
self.UI.setXmlTable(xml)
end
-- toggle the "slot editing mode"
function toggleSlotEditing(_, clickedByColor, isRightClick)
if isRightClick then
resetSlotSymbols()
return
end
updateMessageColor(clickedByColor)
-- toggle internal variable
currentlyEditingSlots = not currentlyEditingSlots
if currentlyEditingSlots then
editButtonLabel("Edit Slots", "Stop editing")
broadcastToColor("Click on a slot symbol (or an empty slot) to edit it.", messageColor, "Orange")
addClickFunctionToSlots()
else
editButtonLabel("Stop editing", "Edit Slots")
redrawSlotSymbols()
end
end
-- click function for slot symbols during the "slot editing mode"
function slotClickfunction(player, _, id)
local slotIndex = id:gsub("slotPanel", "")
slotIndex = tonumber(slotIndex)
-- make a list of the table keys as options for the dialog box
local slotNames = {}
for slotName, _ in pairs(slotNameToChar) do
table.insert(slotNames, slotName)
end
-- prompt player to choose symbol
player.showOptionsDialog("Choose Slot Symbol", slotNames, slotData[slotIndex],
function(chosenSlotName)
slotData[slotIndex] = chosenSlotName
-- update slot symbol
self.UI.setAttribute("slot" .. slotIndex, "text", slotNameToChar[chosenSlotName])
-- update slot rotation
self.UI.setAttribute("slot" .. slotIndex, "rotation", getSlotRotation(chosenSlotName))
end
)
end
-- helper function to rotate the left hand
function getSlotRotation(slotName)
if slotName == "Hand (left)" then
return "0 180 180"
else
return "0 0 180"
end
end
-- reset the slot symbols by making a deep copy of the default data and redrawing
function resetSlotSymbols()
slotData = {}
for _, slotName in ipairs(defaultSlotData) do
table.insert(slotData, slotName)
end
redrawSlotSymbols()
-- need to re-add the click functions if currently in edit mode
if currentlyEditingSlots then
addClickFunctionToSlots()
end
end
-- enables the click functions for editing
function addClickFunctionToSlots()
for i = 1, #slotData do
self.UI.setAttribute("slotPanel" .. i, "onClick", "slotClickfunction")
end
end
---------------------------------------------------------
-- color related functions
---------------------------------------------------------
-- changes the player color
function changeColor(clickedByColor)
local colorList = {
"White",
"Brown",
"Red",
"Orange",
"Yellow",
"Green",
"Teal",
"Blue",
"Purple",
"Pink"
}
local colorList = Player.getColors()
-- remove existing colors from the list of choices
for _, existingColor in ipairs(Player.getAvailableColors()) do
for i, newColor in ipairs(colorList) do
if existingColor == newColor then
if existingColor == newColor or newColor == "Black" or newColor == "Grey" then
table.remove(colorList, i)
end
end
@ -558,16 +708,14 @@ function syncAllCustomizableCards()
end
function syncCustomizableMetadata(card)
local cardMetadata = JSON.decode(card.getGMNotes()) or { }
if cardMetadata == nil or cardMetadata.customizations == nil then
return
end
local cardMetadata = JSON.decode(card.getGMNotes()) or {}
if cardMetadata == nil or cardMetadata.customizations == nil then return end
for _, upgradeSheet in ipairs(searchAroundSelf("isCard")) do
local upgradeSheetMetadata = JSON.decode(upgradeSheet.getGMNotes()) or { }
local upgradeSheetMetadata = JSON.decode(upgradeSheet.getGMNotes()) or {}
if upgradeSheetMetadata.id == (cardMetadata.id .. "-c") then
for i, customization in ipairs(cardMetadata.customizations) do
if customization.replaces ~= nil and customization.replaces.uses ~= nil then
-- Allowed use of call(), no APIs for individual cards
if upgradeSheet.call("isUpgradeActive", i) then
cardMetadata.uses = customization.replaces.uses
card.setGMNotes(JSON.encode(cardMetadata))
@ -584,7 +732,7 @@ function syncCustomizableMetadata(card)
end
function spawnTokensFor(object)
local extraUses = { }
local extraUses = {}
if activeInvestigatorId == "03004" then
extraUses["Charge"] = 1
end
@ -638,15 +786,15 @@ function shouldSpawnTokens(card)
-- Spawn tokens for assets and events on the main area
if inArea(localCardPos, MAIN_PLAY_AREA)
and (metadata.type == "Asset"
or metadata.type == "Event") then
or metadata.type == "Event") then
return true
end
-- Spawn tokens for all encounter types in the threat area
if inArea(localCardPos, THREAT_AREA)
and (metadata.type == "Treachery"
or metadata.type == "Enemy"
or metadata.weakness) then
or metadata.type == "Enemy"
or metadata.weakness) then
return true
end
@ -691,6 +839,8 @@ end
-- investigator ID grabbing and skill tracker
---------------------------------------------------------
-- updates the internal investigator id and action tokens if an investigator card is detected
---@param card tts__Object Card that might be an investigator
function maybeUpdateActiveInvestigator(card)
if not inArea(self.positionToLocal(card.getPosition()), INVESTIGATOR_AREA) then return end
@ -710,13 +860,13 @@ function maybeUpdateActiveInvestigator(card)
elseif activeInvestigatorId ~= "00000" then
class = "Neutral"
activeInvestigatorId = "00000"
ownedObjects.InvestigatorSkillTracker.call("updateStats", {1, 1, 1, 1})
ownedObjects.InvestigatorSkillTracker.call("updateStats", { 1, 1, 1, 1 })
else
return
end
-- change state of action tokens
local search = searchArea(self.positionToWorld({-1.1, 0.05, -0.27}), {4, 1, 1})
local search = searchArea(self.positionToWorld({ -1.1, 0.05, -0.27 }), { 4, 1, 1 })
local smallToken = nil
local STATE_TABLE = {
["Guardian"] = 1,
@ -761,7 +911,7 @@ end
-- manipulation of owned objects
---------------------------------------------------------
-- updates the specific owned counter
-- updates the specified owned counter
---@param param table Contains the information to update:
--- type: String Counter to target
--- newValue: Number Value to set the counter to
@ -775,20 +925,21 @@ function updateCounter(param)
end
end
-- returns the resource counter amount
-- get the value the specified owned counter
---@param type string Counter to target
---@return number: Counter value
function getCounterValue(type)
return ownedObjects[type].getVar("val")
end
-- set investigator skill tracker to "1, 1, 1, 1"
function resetSkillTracker()
local obj = ownedObjects.InvestigatorSkillTracker
if obj ~= nil then
obj.call("updateStats", { 1, 1, 1, 1 })
else
printToAll("Skill tracker for " .. matColor .. " playmat could not be found.", "Yellow")
end
local obj = ownedObjects.InvestigatorSkillTracker
if obj ~= nil then
obj.call("updateStats", { 1, 1, 1, 1 })
else
printToAll("Skill tracker for " .. matColor .. " playmat could not be found.", "Yellow")
end
end
---------------------------------------------------------
@ -811,25 +962,18 @@ function returnGlobalDrawPosition()
return self.positionToWorld(DRAW_DECK_POSITION)
end
-- Sets this playermat's draw 1 button to visible
-- creates / removes the draw 1 button
---@param visible boolean Whether the draw 1 button should be visible
function showDrawButton(visible)
isDrawButtonVisible = visible
-- create the "Draw 1" button
if isDrawButtonVisible then
self.createButton({
label = "Draw 1",
click_function = "doDrawOne",
function_owner = self,
position = { 1.84, 0.1, -0.36 },
scale = { 0.12, 0.12, 0.12 },
width = 800,
height = 280,
font_size = 180
})
-- remove the "Draw 1" button
-- Draw 1 button: modified default data
buttonParameters.label = "Draw 1"
buttonParameters.click_function = "doDrawOne"
buttonParameters.tooltip = ""
buttonParameters.position.z = -0.35
self.createButton(buttonParameters)
else
local buttons = self.getButtons()
for i = 1, #buttons do
@ -845,13 +989,13 @@ end
function clickableClues(showCounter)
local clickerPos = ownedObjects.ClickableClueCounter.getPosition()
local clueCount = 0
-- move clue counters
local modY = showCounter and 0.525 or -0.525
ownedObjects.ClickableClueCounter.setPosition(clickerPos + Vector(0, modY, 0))
if showCounter then
-- current clue count
-- get current clue count
clueCount = ownedObjects.ClueCounter.getVar("exposedValue")
-- remove clues
@ -860,11 +1004,11 @@ function clickableClues(showCounter)
-- set value for clue clickers
ownedObjects.ClickableClueCounter.call("updateVal", clueCount)
else
-- current clue count
-- get current clue count
clueCount = ownedObjects.ClickableClueCounter.getVar("val")
-- spawn clues
local pos = self.positionToWorld({x = -1.12, y = 0.05, z = 0.7})
local pos = self.positionToWorld({ x = -1.12, y = 0.05, z = 0.7 })
for i = 1, clueCount do
pos.y = pos.y + 0.045 * i
tokenManager.spawnToken(pos, "clue", self.getRotation())
@ -895,8 +1039,7 @@ end
function setLimitSnapsByType(matchTypes)
local snaps = self.getSnapPoints()
for i, snap in ipairs(snaps) do
local snapPos = snap.position
if inArea(snapPos, MAIN_PLAY_AREA) then
if inArea(snap.position, MAIN_PLAY_AREA) then
local snapTags = snaps[i].tags
if matchTypes then
if snapTags == nil then
@ -908,7 +1051,7 @@ function setLimitSnapsByType(matchTypes)
snaps[i].tags = nil
end
end
if inArea(snapPos, INVESTIGATOR_AREA) then
if inArea(snap.position, INVESTIGATOR_AREA) then
local snapTags = snaps[i].tags
if matchTypes then
if snapTags == nil then
@ -924,16 +1067,15 @@ function setLimitSnapsByType(matchTypes)
self.setSnapPoints(snaps)
end
-- Simple method to check if the given point is in a specified area. Local use only,
-- Simple method to check if the given point is in a specified area. Local use only
---@param point tts__Vector Point to check, only x and z values are relevant
---@param bounds table Defined area to see if the point is within. See MAIN_PLAY_AREA for sample
-- bounds definition.
---@param bounds table Defined area to see if the point is within. See MAIN_PLAY_AREA for sample bounds definition.
---@return boolean: True if the point is in the area defined by bounds
function inArea(point, bounds)
return (point.x < bounds.upperLeft.x
and point.x > bounds.lowerRight.x
and point.z < bounds.upperLeft.z
and point.z > bounds.lowerRight.z)
and point.x > bounds.lowerRight.x
and point.z < bounds.upperLeft.z
and point.z > bounds.lowerRight.z)
end
-- called by custom data helpers to add player card data