Merge pull request #742 from dscarpac/token-stack
Adds XML label to stacks of tokens
This commit is contained in:
commit
bf4fcd6051
@ -47,8 +47,9 @@ do
|
||||
|
||||
-- returns a chaos token to the bag and calls all relevant functions
|
||||
---@param token tts__Object Chaos token to return
|
||||
ChaosBagApi.returnChaosTokenToBag = function(token)
|
||||
Global.call("returnChaosTokenToBag", token)
|
||||
---@param fromBag boolean whether or not the token to return was in the middle of being drawn (true) or elsewhere (false)
|
||||
ChaosBagApi.returnChaosTokenToBag = function(token, fromBag)
|
||||
Global.call("returnChaosTokenToBag", { token = token, fromBag = fromBag })
|
||||
end
|
||||
|
||||
-- spawns the specified chaos token and puts it into the chaos bag
|
||||
|
@ -5,6 +5,7 @@ local navigationOverlayApi = require("core/NavigationOverlayApi")
|
||||
local optionPanelApi = require("core/OptionPanelApi")
|
||||
local playermatApi = require("playermat/PlayermatApi")
|
||||
local searchLib = require("util/SearchLib")
|
||||
local tokenChecker = require("core/token/TokenChecker")
|
||||
local victoryDisplayApi = require("core/VictoryDisplayApi")
|
||||
|
||||
function onLoad()
|
||||
@ -265,7 +266,7 @@ function removeOneUse(playerColor, hoveredObject)
|
||||
for _, obj in ipairs(searchLib.onObject(hoveredObject, "isTileOrToken")) do
|
||||
if not obj.locked and obj.memo ~= "resourceCounter" then
|
||||
-- check for matching object, otherwise use the first hit
|
||||
if obj.memo == searchForType then
|
||||
if obj.memo and obj.memo == searchForType then
|
||||
targetObject = obj
|
||||
break
|
||||
elseif not targetObject then
|
||||
@ -275,6 +276,15 @@ function removeOneUse(playerColor, hoveredObject)
|
||||
end
|
||||
end
|
||||
|
||||
-- release sealed token if card has one and no uses
|
||||
if tokenChecker.isChaosToken(targetObject) and hoveredObject.hasTag("CardThatSeals") then
|
||||
local func = hoveredObject.getVar("releaseOneToken") -- check if function exists
|
||||
if func ~= nil then
|
||||
hoveredObject.call("releaseOneToken", playerColor)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- error handling
|
||||
if not targetObject then
|
||||
broadcastToColor("No tokens found!", playerColor, "Yellow")
|
||||
|
@ -207,6 +207,12 @@ function onObjectEnterZone(zone, object)
|
||||
object.clearContextMenu()
|
||||
object.call("shutOff")
|
||||
end
|
||||
if object.hasTag("CardThatSeals") then
|
||||
local func = object.getVar("resetSealedTokens") -- check if function exists (it won't for older custom content)
|
||||
if func ~= nil then
|
||||
object.call("resetSealedTokens")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -301,13 +307,13 @@ function returnChaosTokens()
|
||||
end
|
||||
|
||||
-- returns a single chaos token to the bag and calls respective functions
|
||||
function returnChaosTokenToBag(token)
|
||||
local name = token.getName()
|
||||
function returnChaosTokenToBag(params)
|
||||
local name = params.token.getName()
|
||||
local chaosBag = findChaosBag()
|
||||
chaosBag.putObject(token)
|
||||
chaosBag.putObject(params.token)
|
||||
tokenArrangerApi.layout()
|
||||
if name == "Bless" or name == "Curse" then
|
||||
blessCurseManagerApi.releasedToken(name, token.getGUID(), true)
|
||||
blessCurseManagerApi.releasedToken(name, params.token.getGUID(), params.fromBag)
|
||||
end
|
||||
end
|
||||
|
||||
@ -418,7 +424,8 @@ function returnAndRedraw(_, tokenGUID)
|
||||
|
||||
-- perform the actual token replacing
|
||||
trackChaosToken(tokenName, mat.getGUID(), true)
|
||||
returnChaosTokenToBag(returnedToken)
|
||||
local params = {token = returnedToken, fromBag = true}
|
||||
returnChaosTokenToBag(params)
|
||||
|
||||
chaosTokens[indexOfReturnedToken] = drawChaosToken({
|
||||
mat = mat,
|
||||
|
@ -1,7 +1,16 @@
|
||||
--[[ Library for cards that seal tokens
|
||||
This file is used to add sealing option to cards' context menu.
|
||||
NOTE: all cards are allowed to release a single token to enable Hallow and A Watchful Peace,
|
||||
and to release all sealed tokens to allow for cards that might leave play with sealed tokens on them.
|
||||
Valid options (set before requiring this file):
|
||||
|
||||
MAX_SEALED --@type: number (maximum number of tokens allowable by the card to be sealed)
|
||||
- required for all cards
|
||||
- if MAX_SEALED is more than 1, then an XML label is created for the topmost token indicating the number of sealed tokens
|
||||
- gives an error if user tries to seal additional tokens on the card
|
||||
- example usage: "The Chthonian Stone"
|
||||
> MAX_SEALED = 1
|
||||
|
||||
UPDATE_ON_HOVER --@type: boolean
|
||||
- automatically updates the context menu options when the card is hovered
|
||||
- the "Read Bag" function reads the content of the chaos bag to update the context menu
|
||||
@ -12,19 +21,16 @@ KEEP_OPEN --@type: boolean
|
||||
- makes the context menu stay open after selecting an option
|
||||
- example usage: "Unrelenting"
|
||||
|
||||
SHOW_SINGLE_RELEASE --@type: boolean
|
||||
SHOW_MULTI_RELEASE --@type: number (maximum amount of tokens to release at once)
|
||||
- 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
|
||||
- this entry allows releasing of multiple tokens at once
|
||||
- example usage: "Nephthys" (to release 3 bless tokens at once)
|
||||
- this entry allows releasing of multiple tokens at once, to the maximum number
|
||||
- does not fail if there are fewer than the maximum sealed
|
||||
- example usage: "Nephthys" (to release up to 3 bless tokens at once)
|
||||
|
||||
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
|
||||
- fails if not enough tokens are sealed
|
||||
- example usage: "Nephthys" (to return 3 bless tokens at once)
|
||||
|
||||
SHOW_MULTI_SEAL --@type: number (amount of tokens to seal at once)
|
||||
@ -58,6 +64,7 @@ Thus it should be implemented like this:
|
||||
> ["+1"] = true,
|
||||
> ["Elder Sign"] = true
|
||||
> }
|
||||
> MAX_SEALED = 1
|
||||
> require...
|
||||
----------------------------------------------------------
|
||||
Example 2: Holy Spear
|
||||
@ -68,8 +75,8 @@ Thus it should be implemented like this:
|
||||
> VALID_TOKENS = {
|
||||
> ["Bless"] = true
|
||||
> }
|
||||
> SHOW_SINGLE_RELEASE = true
|
||||
> SHOW_MULTI_SEAL = 2
|
||||
> MAX_SEALED = 10
|
||||
> require...
|
||||
----------------------------------------------------------]]
|
||||
|
||||
@ -83,6 +90,20 @@ local sealedTokens = {}
|
||||
local ID_URL_MAP = {}
|
||||
local tokensInBag = {}
|
||||
|
||||
-- XML background color for each token for label when stacked
|
||||
local tokenColor = {
|
||||
["Skull"] = "#4A0400E6",
|
||||
["Cultist"] = "#173B0BE6",
|
||||
["Tablet"] = "#1D2238E6",
|
||||
["Elder Thing"] = "#4D2331E6",
|
||||
["Auto-fail"] = "#9B0004E6",
|
||||
["Bless"] = "#9D702CE6",
|
||||
["Curse"] = "#633A84E6",
|
||||
["Frost"] = "#404450E6",
|
||||
["Elder Sign"] = "#50A8CEE6",
|
||||
[""] = "#77674DE6"
|
||||
}
|
||||
|
||||
function onSave() return JSON.encode(sealedTokens) end
|
||||
|
||||
function onLoad(savedData)
|
||||
@ -94,13 +115,15 @@ end
|
||||
|
||||
-- builds the context menu
|
||||
function generateContextMenu()
|
||||
-- conditional single or multi release options
|
||||
if SHOW_SINGLE_RELEASE then
|
||||
self.addContextMenuItem("Release token", releaseOneToken)
|
||||
elseif SHOW_MULTI_RELEASE then
|
||||
self.addContextMenuItem("Release one token", releaseOneToken)
|
||||
|
||||
-- conditional release options
|
||||
if MAX_SEALED > 1 then
|
||||
self.addContextMenuItem("Release all tokens", releaseAllTokens)
|
||||
end
|
||||
|
||||
if SHOW_MULTI_RELEASE then
|
||||
self.addContextMenuItem("Release " .. SHOW_MULTI_RELEASE .. " token(s)", releaseMultipleTokens)
|
||||
else
|
||||
self.addContextMenuItem("Release token(s)", releaseAllTokens)
|
||||
end
|
||||
|
||||
if RESOLVE_TOKEN then
|
||||
@ -138,7 +161,7 @@ function generateContextMenu()
|
||||
end
|
||||
|
||||
if allowed then
|
||||
for i = 1, SHOW_MULTI_SEAL do
|
||||
for i = SHOW_MULTI_SEAL, 1, -1 do
|
||||
sealToken(map.name, playerColor)
|
||||
end
|
||||
else
|
||||
@ -175,6 +198,10 @@ end
|
||||
|
||||
-- seals the named token on this card
|
||||
function sealToken(name, playerColor)
|
||||
if #sealedTokens >= MAX_SEALED then
|
||||
printToColor("Cannot seal any more tokens on this card", playerColor, "Red")
|
||||
return
|
||||
end
|
||||
if not chaosBagApi.canTouchChaosTokens() then return end
|
||||
local chaosbag = chaosBagApi.findChaosBag()
|
||||
for i, obj in ipairs(chaosbag.getObjects()) do
|
||||
@ -191,6 +218,16 @@ function sealToken(name, playerColor)
|
||||
if name == "Bless" or name == "Curse" then
|
||||
blessCurseManagerApi.sealedToken(name, guid)
|
||||
end
|
||||
-- destroy XML on just covered token
|
||||
if #sealedTokens > 1 then
|
||||
local coveredToken = getObjectFromGUID(sealedTokens[#sealedTokens - 1])
|
||||
if coveredToken ~= nil then
|
||||
coveredToken.UI.setXml("")
|
||||
else
|
||||
table.remove(sealedTokens, #sealedTokens - 1)
|
||||
end
|
||||
end
|
||||
updateStackSize()
|
||||
end
|
||||
})
|
||||
return
|
||||
@ -210,16 +247,22 @@ function releaseOneToken(playerColor)
|
||||
end
|
||||
end
|
||||
|
||||
-- release multiple tokens at once
|
||||
-- release up to multiple tokens at once with no minimum
|
||||
function releaseMultipleTokens(playerColor)
|
||||
if SHOW_MULTI_RELEASE <= #sealedTokens then
|
||||
for i = 1, SHOW_MULTI_RELEASE do
|
||||
if #sealedTokens == 0 then
|
||||
printToColor("Not enough tokens sealed.", playerColor)
|
||||
return
|
||||
end
|
||||
|
||||
local numRemoved = SHOW_MULTI_RELEASE
|
||||
if #sealedTokens < SHOW_MULTI_RELEASE then
|
||||
numRemoved = #sealedTokens
|
||||
end
|
||||
|
||||
for i = 1, numRemoved do
|
||||
putTokenAway(table.remove(sealedTokens))
|
||||
end
|
||||
printToColor("Releasing " .. SHOW_MULTI_RELEASE .. " tokens", playerColor)
|
||||
else
|
||||
printToColor("Not enough tokens sealed.", playerColor)
|
||||
end
|
||||
printToColor("Releasing " .. numRemoved .. " tokens", playerColor)
|
||||
end
|
||||
|
||||
-- releases all sealed tokens
|
||||
@ -260,6 +303,7 @@ function putTokenAway(guid)
|
||||
if name == "Bless" or name == "Curse" then
|
||||
blessCurseManagerApi.releasedToken(name, guid)
|
||||
end
|
||||
updateStackSize()
|
||||
end
|
||||
|
||||
-- returns the token to the pool (== removes it)
|
||||
@ -272,6 +316,7 @@ function returnToken(guid)
|
||||
if name == "Bless" or name == "Curse" then
|
||||
blessCurseManagerApi.returnedToken(name, guid)
|
||||
end
|
||||
updateStackSize()
|
||||
end
|
||||
|
||||
-- resolves sealed token as if it came from the chaos bag
|
||||
@ -283,5 +328,41 @@ function resolveSealed()
|
||||
local closestMatColor = playermatApi.getMatColorByPosition(self.getPosition())
|
||||
local mat = guidReferenceApi.getObjectByOwnerAndType(closestMatColor, "Playermat")
|
||||
local guidToBeResolved = table.remove(sealedTokens)
|
||||
local resolvedToken = getObjectFromGUID(guidToBeResolved)
|
||||
resolvedToken.UI.setXml("")
|
||||
updateStackSize()
|
||||
chaosBagApi.drawChaosToken(mat, true, _, guidToBeResolved)
|
||||
end
|
||||
|
||||
function updateStackSize()
|
||||
if MAX_SEALED == 1 then return end
|
||||
if #sealedTokens == 0 then return end
|
||||
-- get topmost sealed token
|
||||
local topToken = getObjectFromGUID(sealedTokens[#sealedTokens])
|
||||
local name = topToken.getName()
|
||||
|
||||
topToken.UI.setXmlTable({
|
||||
{
|
||||
tag = "Panel",
|
||||
attributes = {
|
||||
height = 380,
|
||||
width = 380,
|
||||
rotation = "0 0 180",
|
||||
scale = "0.2 0.2 1",
|
||||
position = "0 0 -12",
|
||||
color = tokenColor[name] or "#77674DE6"
|
||||
},
|
||||
children = {
|
||||
tag = "Text",
|
||||
attributes = {
|
||||
fontSize = "380",
|
||||
font = "font_teutonic-arkham",
|
||||
color = "#ffffff",
|
||||
outline = "#000000",
|
||||
outlineSize = "8 -8",
|
||||
text = "x" .. #sealedTokens
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
end
|
||||
|
@ -2,5 +2,6 @@ VALID_TOKENS = {
|
||||
["+1"] = true,
|
||||
["Elder Sign"] = true
|
||||
}
|
||||
MAX_SEALED = 1
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -3,5 +3,6 @@ VALID_TOKENS = {
|
||||
}
|
||||
|
||||
KEEP_OPEN = true
|
||||
MAX_SEALED = 5
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -2,4 +2,6 @@ VALID_TOKENS = {
|
||||
["Elder Sign"] = true
|
||||
}
|
||||
|
||||
MAX_SEALED = 1
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -2,8 +2,8 @@ VALID_TOKENS = {
|
||||
["Curse"] = true
|
||||
}
|
||||
|
||||
SHOW_SINGLE_RELEASE = true
|
||||
KEEP_OPEN = true
|
||||
MAX_SEALED = 3
|
||||
RESOLVE_TOKEN = true
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -2,8 +2,8 @@ VALID_TOKENS = {
|
||||
["Bless"] = true
|
||||
}
|
||||
|
||||
SHOW_SINGLE_RELEASE = true
|
||||
KEEP_OPEN = true
|
||||
MAX_SEALED = 3
|
||||
RESOLVE_TOKEN = true
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -2,7 +2,7 @@ VALID_TOKENS = {
|
||||
["Curse"] = true
|
||||
}
|
||||
|
||||
SHOW_SINGLE_RELEASE = true
|
||||
MAX_SEALED = 10
|
||||
KEEP_OPEN = true
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -2,7 +2,7 @@ VALID_TOKENS = {
|
||||
["Bless"] = true
|
||||
}
|
||||
|
||||
SHOW_SINGLE_RELEASE = true
|
||||
SHOW_MULTI_SEAL = 2
|
||||
MAX_SEALED = 10
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -2,8 +2,9 @@ VALID_TOKENS = {
|
||||
["Bless"] = true
|
||||
}
|
||||
|
||||
SHOW_SINGLE_RELEASE = true
|
||||
KEEP_OPEN = true
|
||||
SHOW_MULTI_RELEASE = 3
|
||||
SHOW_MULTI_RETURN = 3
|
||||
MAX_SEALED = 10
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -5,5 +5,6 @@ INVALID_TOKENS = {
|
||||
}
|
||||
|
||||
UPDATE_ON_HOVER = true
|
||||
MAX_SEALED = 1
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -3,5 +3,6 @@ VALID_TOKENS = {
|
||||
}
|
||||
|
||||
KEEP_OPEN = true
|
||||
MAX_SEALED = 3
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -3,6 +3,6 @@ VALID_TOKENS = {
|
||||
}
|
||||
|
||||
KEEP_OPEN = true
|
||||
SHOW_SINGLE_RELEASE = true
|
||||
MAX_SEALED = 5
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -2,4 +2,6 @@ VALID_TOKENS = {
|
||||
["Auto-fail"] = true
|
||||
}
|
||||
|
||||
MAX_SEALED = 1
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -2,4 +2,6 @@ VALID_TOKENS = {
|
||||
["Elder Sign"] = true
|
||||
}
|
||||
|
||||
MAX_SEALED = 1
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -2,6 +2,6 @@ VALID_TOKENS = {
|
||||
["0"] = true
|
||||
}
|
||||
|
||||
SHOW_SINGLE_RELEASE = true
|
||||
MAX_SEALED = 4 -- Core Set is component-limited to 4 '0' tokens
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -3,6 +3,6 @@ VALID_TOKENS = {
|
||||
}
|
||||
|
||||
KEEP_OPEN = true
|
||||
SHOW_SINGLE_RELEASE = true
|
||||
MAX_SEALED = 5
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -5,4 +5,6 @@ VALID_TOKENS = {
|
||||
["Elder Thing"] = true,
|
||||
}
|
||||
|
||||
MAX_SEALED = 1
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -3,5 +3,6 @@ VALID_TOKENS = {
|
||||
}
|
||||
|
||||
RESOLVE_TOKEN = true
|
||||
MAX_SEALED = 1
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -5,5 +5,6 @@ INVALID_TOKENS = {
|
||||
|
||||
UPDATE_ON_HOVER = true
|
||||
KEEP_OPEN = true
|
||||
MAX_SEALED = 3
|
||||
|
||||
require("playercards/CardsThatSealTokens")
|
||||
|
@ -260,7 +260,7 @@ function discardListOfObjects(objList)
|
||||
end
|
||||
elseif tokenChecker.isChaosToken(obj) then
|
||||
-- put chaos tokens back into bag (e.g. Unrelenting)
|
||||
chaosBagApi.returnChaosTokenToBag(obj)
|
||||
chaosBagApi.returnChaosTokenToBag(obj, false)
|
||||
elseif not obj.getLock() and not obj.hasTag("DontDiscard") then
|
||||
-- don't touch locked objects (like the table etc.) or specific objects (like key tokens)
|
||||
ownedObjects.Trash.putObject(obj)
|
||||
@ -878,7 +878,7 @@ function removeTokensFromObject(object)
|
||||
|
||||
for _, obj in ipairs(searchLib.onObject(object)) do
|
||||
if tokenChecker.isChaosToken(obj) then
|
||||
chaosBagApi.returnChaosTokenToBag(obj)
|
||||
chaosBagApi.returnChaosTokenToBag(obj, false)
|
||||
elseif obj.getGUID() ~= "4ee1f2" and -- table
|
||||
obj ~= self and
|
||||
obj.type ~= "Deck" and
|
||||
|
Loading…
Reference in New Issue
Block a user