SCED/src/playercards/CardsThatSealTokens.ttslua

265 lines
8.5 KiB
Plaintext
Raw Normal View History

--[[ Library for cards that seal tokens
This file is used to add sealing option to cards' context menu.
Valid options (set before requiring this file):
2023-04-07 16:03:07 -04:00
2023-04-07 17:43:24 -04:00
UPDATE_ON_HOVER --@type: boolean
- automatically updates the context menu options when the card is hovered
2023-04-07 16:03:07 -04:00
- the "Read Bag" function reads the content of the chaos bag to update the context menu
- example usage: "Unrelenting" (to only display valid tokens)
2023-06-13 13:08:50 -04:00
KEEP_OPEN --@type: boolean
- meant for cards that seal single tokens multiple times (one by one)
- makes the context menu stay open after selecting an option
- example usage: "Unrelenting"
2023-04-07 16:03:07 -04:00
SHOW_SINGLE_RELEASE --@type: boolean
- enables an entry in the context menu
- this entry allows releasing a single token
- example usage: "Holy Spear" (to keep the other tokens and just release one)
SHOW_MULTI_RELEASE --@type: number (amount of tokens to release at once)
- enables an entry in the context menu
2023-05-02 16:56:39 -04:00
- this entry allows releasing of multiple tokens at once
2023-04-07 16:03:07 -04:00
- example usage: "Nephthys" (to release 3 bless tokens at once)
2024-01-15 05:57:48 -05:00
SHOW_MULTI_RETURN --@type: number (amount of tokens to return to pool at once)
- enables an entry in the context menu
- this entry allows returning tokens to the token pool
- example usage: "Nephthys" (to return 3 bless tokens at once)
2023-04-07 16:03:07 -04:00
SHOW_MULTI_SEAL --@type: number (amount of tokens to seal at once)
- enables an entry in the context menu
- this entry allows sealing of multiple tokens at once
- example usage: "Holy Spear" (to seal two bless tokens at once)
VALID_TOKENS --@type: table ([tokenName] = true)
- this table defines which tokens should be abled to be sealed
- needs to be defined for each card -> even if empty
- example usage: "The Chthonian Stone"
> VALID_TOKENS = {
> ["Skull"] = true,
> ["Cultist"] = true,
> ["Tablet"] = true,
> ["Elder Thing"] = true,
> }
INVALID_TOKENS --@type: table ([tokenName] = true)
- this table defines which tokens are invalid for sealing
- only needs to be defined if needed
- usually combined with empty "VALID_TOKENS" table
- example usage: "Protective Incantation" (not allowed to seal Auto-fail)
----------------------------------------------------------
Example 1: Crystalline Elder Sign
This card can only seal the "+1" or "Elder Sign" token,
it does not need specific options for multi-sealing or releasing.
Thus it should be implemented like this:
2023-05-02 16:56:39 -04:00
> VALID_TOKENS = {
> ["+1"] = true,
> ["Elder Sign"] = true
> }
2023-05-07 10:22:10 -04:00
> require...
2023-04-07 16:03:07 -04:00
----------------------------------------------------------
Example 2: Holy Spear
This card features the following abilities (just listing the relevant parts):
- releasing a single bless token
- sealing two bless tokens
Thus it should be implemented like this:
2023-05-02 16:56:39 -04:00
> VALID_TOKENS = {
> ["Bless"] = true
> }
> SHOW_SINGLE_RELEASE = true
> SHOW_MULTI_SEAL = 2
2023-05-07 10:22:10 -04:00
> require...
----------------------------------------------------------]]
2023-03-04 07:54:10 -05:00
local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi")
local chaosBagApi = require("chaosbag/ChaosBagApi")
2023-09-26 10:14:37 -04:00
local tokenArrangerApi = require("accessories/TokenArrangerApi")
2023-06-27 06:10:32 -04:00
local sealedTokens = {}
2023-04-07 16:03:07 -04:00
local ID_URL_MAP = {}
2023-04-08 14:04:30 -04:00
local tokensInBag = {}
2023-03-04 07:54:10 -05:00
function onSave() return JSON.encode(sealedTokens) end
function onLoad(savedData)
sealedTokens = JSON.decode(savedData) or {}
ID_URL_MAP = chaosBagApi.getIdUrlMap()
generateContextMenu()
2023-06-27 06:10:32 -04:00
self.addTag("CardThatSeals")
end
-- builds the context menu
function generateContextMenu()
-- conditional single or multi release options
2023-03-04 07:54:10 -05:00
if SHOW_SINGLE_RELEASE then
self.addContextMenuItem("Release token", releaseOneToken)
elseif SHOW_MULTI_RELEASE then
2023-04-07 16:03:07 -04:00
self.addContextMenuItem("Release " .. SHOW_MULTI_RELEASE .. " token(s)", releaseMultipleTokens)
2023-03-04 07:54:10 -05:00
else
2023-04-07 16:03:07 -04:00
self.addContextMenuItem("Release token(s)", releaseAllTokens)
2023-03-04 07:54:10 -05:00
end
2024-01-15 05:57:48 -05:00
-- conditional release option
if SHOW_MULTI_RETURN then
self.addContextMenuItem("Return " .. SHOW_MULTI_RETURN .. " token(s)", returnMultipleTokens)
end
-- main context menu options to seal tokens
2023-03-04 07:54:10 -05:00
for _, map in pairs(ID_URL_MAP) do
2023-04-07 17:43:24 -04:00
if (VALID_TOKENS[map.name] ~= nil) or (UPDATE_ON_HOVER and tokensInBag[map.name] and not INVALID_TOKENS[map.name]) then
if not SHOW_MULTI_SEAL then
self.addContextMenuItem("Seal " .. map.name, function(playerColor)
sealToken(map.name, playerColor)
2023-06-13 13:08:50 -04:00
end, KEEP_OPEN)
else
self.addContextMenuItem("Seal " .. SHOW_MULTI_SEAL .. " " .. map.name, function(playerColor)
readBag()
local allowed = true
local notFound
for name, _ in pairs(VALID_TOKENS) do
if (tokensInBag[name] or 0) < SHOW_MULTI_SEAL then
allowed = false
notFound = name
end
end
if allowed then
for i = 1, SHOW_MULTI_SEAL do
sealToken(map.name, playerColor)
end
else
printToColor("Not enough " .. notFound .. " tokens in the chaos bag.", playerColor)
end
end)
end
2023-03-04 07:54:10 -05:00
end
end
end
-- generates a list of chaos tokens that is in the chaos bag
function readBag()
local chaosbag = chaosBagApi.findChaosBag()
tokensInBag = {}
for _, token in ipairs(chaosbag.getObjects()) do
tokensInBag[token.name] = (tokensInBag[token.name] or 0) + 1
end
end
2024-01-15 18:06:55 -05:00
function resetSealedTokens()
sealedTokens = {}
end
2023-04-07 16:16:31 -04:00
-- native event from TTS - used to update the context menu for cards like "Unrelenting"
function onHover()
2023-04-07 17:43:24 -04:00
if UPDATE_ON_HOVER then
2023-04-07 16:16:31 -04:00
readBag()
2023-04-07 17:43:24 -04:00
self.clearContextMenu()
2023-04-07 16:16:31 -04:00
generateContextMenu()
end
end
2023-03-04 07:54:10 -05:00
-- seals the named token on this card
function sealToken(name, playerColor)
if not chaosBagApi.canTouchChaosTokens() then return end
local chaosbag = chaosBagApi.findChaosBag()
2023-03-04 07:54:10 -05:00
for i, obj in ipairs(chaosbag.getObjects()) do
if obj.name == name then
chaosbag.takeObject({
position = self.getPosition() + Vector(0, 0.5 + 0.1 * #sealedTokens, 0),
rotation = self.getRotation(),
index = i - 1,
smooth = false,
callback_function = function(token)
local guid = token.getGUID()
table.insert(sealedTokens, guid)
tokenArrangerApi.layout()
2023-03-04 07:54:10 -05:00
if name == "Bless" or name == "Curse" then
blessCurseManagerApi.sealedToken(name, guid)
end
end
})
return
end
end
printToColor(name .. " token not found in chaos bag", playerColor)
end
-- release the last sealed token
2023-05-07 10:22:10 -04:00
function releaseOneToken(playerColor)
if not chaosBagApi.canTouchChaosTokens() then return end
2023-04-07 16:03:07 -04:00
if #sealedTokens == 0 then
2023-05-07 10:22:10 -04:00
printToColor("No sealed token(s) found", playerColor)
2023-03-04 07:54:10 -05:00
else
2023-05-07 10:22:10 -04:00
printToColor("Releasing token", playerColor)
putTokenAway(table.remove(sealedTokens))
2023-03-04 07:54:10 -05:00
end
end
2023-04-07 16:03:07 -04:00
-- release multiple tokens at once
function releaseMultipleTokens(playerColor)
2023-05-02 16:56:39 -04:00
if SHOW_MULTI_RELEASE <= #sealedTokens then
2023-04-07 16:03:07 -04:00
for i = 1, SHOW_MULTI_RELEASE do
2023-05-07 10:22:10 -04:00
putTokenAway(table.remove(sealedTokens))
2023-04-07 16:03:07 -04:00
end
2023-05-07 10:22:10 -04:00
printToColor("Releasing " .. SHOW_MULTI_RELEASE .. " tokens", playerColor)
2023-04-07 16:03:07 -04:00
else
2023-05-02 16:56:39 -04:00
printToColor("Not enough tokens sealed.", playerColor)
2023-04-07 16:03:07 -04:00
end
end
2023-04-08 14:04:30 -04:00
2023-03-04 07:54:10 -05:00
-- releases all sealed tokens
2023-04-07 16:03:07 -04:00
function releaseAllTokens(playerColor)
if not chaosBagApi.canTouchChaosTokens() then return end
2023-03-04 07:54:10 -05:00
if #sealedTokens == 0 then
printToColor("No sealed token(s) found", playerColor)
else
printToColor("Releasing token(s)", playerColor)
for _, guid in ipairs(sealedTokens) do
putTokenAway(guid)
2023-03-04 07:54:10 -05:00
end
sealedTokens = {}
end
end
2024-01-15 05:57:48 -05:00
-- returns multiple tokens at once to the token pool
function returnMultipleTokens(playerColor)
if SHOW_MULTI_RETURN <= #sealedTokens then
for i = 1, SHOW_MULTI_RETURN do
returnToken(table.remove(sealedTokens))
end
printToColor("Returning " .. SHOW_MULTI_RETURN .. " tokens", playerColor)
else
printToColor("Not enough tokens sealed.", playerColor)
end
end
-- returns the token (referenced by GUID) to the chaos bag
function putTokenAway(guid)
local token = getObjectFromGUID(guid)
if not token then return end
local name = token.getName()
local chaosbag = chaosBagApi.findChaosBag()
chaosbag.putObject(token)
tokenArrangerApi.layout()
if name == "Bless" or name == "Curse" then
blessCurseManagerApi.releasedToken(name, guid)
end
end
2024-01-15 05:57:48 -05:00
-- returns the token to the pool (== removes it)
function returnToken(guid)
local token = getObjectFromGUID(guid)
if not token then return end
local name = token.getName()
token.destruct()
if name == "Bless" or name == "Curse" then
blessCurseManagerApi.returnedToken(name, guid)
end
end