ah_sce_unpacked/unpacked/Custom_Token BlessCurse Manager 5933fb.ttslua

617 lines
20 KiB
Plaintext
Raw Normal View History

2022-12-13 14:02:30 -05:00
-- Bundled by luabundle {"version":"1.6.0"}
local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)
local loadingPlaceholder = {[{}] = true}
local register
local modules = {}
local require
local loaded = {}
register = function(name, body)
if not modules[name] then
modules[name] = body
end
end
require = function(name)
local loadedModule = loaded[name]
if loadedModule then
if loadedModule == loadingPlaceholder then
return nil
end
else
if not modules[name] then
if not superRequire then
local identifier = type(name) == 'string' and '\"' .. name .. '\"' or tostring(name)
error('Tried to require ' .. identifier .. ', but no such module has been registered')
else
return superRequire(name)
end
end
loaded[name] = loadingPlaceholder
loadedModule = modules[name](require, loaded, register, modules)
loaded[name] = loadedModule
end
return loadedModule
end
return require, loaded, register, modules
end)(nil)
2024-02-17 19:48:30 -05:00
__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules)
do
local TokenArrangerApi = {}
local guidReferenceApi = require("core/GUIDReferenceApi")
-- local function to call the token arranger, if it is on the table
---@param functionName string Name of the function to cal
---@param argument? table Parameter to pass
local function callIfExistent(functionName, argument)
local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger")
if tokenArranger ~= nil then
tokenArranger.call(functionName, argument)
end
end
-- updates the token modifiers with the provided data
---@param fullData table Contains the chaos token metadata
TokenArrangerApi.onTokenDataChanged = function(fullData)
callIfExistent("onTokenDataChanged", fullData)
end
-- deletes already laid out tokens
TokenArrangerApi.deleteCopiedTokens = function()
callIfExistent("deleteCopiedTokens")
end
-- updates the laid out tokens
TokenArrangerApi.layout = function()
Wait.time(function() callIfExistent("layout") end, 0.1)
end
return TokenArrangerApi
end
end)
__bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules)
do
local ChaosBagApi = {}
-- respawns the chaos bag with a new state of tokens
---@param tokenList table List of chaos token ids
ChaosBagApi.setChaosBagState = function(tokenList)
return Global.call("setChaosBagState", tokenList)
end
-- returns a Table List of chaos token ids in the current chaos bag
-- requires copying the data into a new table because TTS is weird about handling table return values in Global
ChaosBagApi.getChaosBagState = function()
local chaosBagContentsCatcher = Global.call("getChaosBagState")
local chaosBagContents = {}
for _, v in ipairs(chaosBagContentsCatcher) do
table.insert(chaosBagContents, v)
end
return chaosBagContents
end
-- checks scripting zone for chaos bag (also called by a lot of objects!)
ChaosBagApi.findChaosBag = function()
return Global.call("findChaosBag")
end
-- returns a table of object references to the tokens in play (does not include sealed tokens!)
ChaosBagApi.getTokensInPlay = function()
return Global.call("getChaosTokensinPlay")
end
-- returns all sealed tokens on cards to the chaos bag
---@param playerColor string Color of the player to show the broadcast to
ChaosBagApi.releaseAllSealedTokens = function(playerColor)
return Global.call("releaseAllSealedTokens", playerColor)
end
-- returns all drawn tokens to the chaos bag
ChaosBagApi.returnChaosTokens = function()
return Global.call("returnChaosTokens")
end
-- removes the specified chaos token from the chaos bag
---@param id string ID of the chaos token
ChaosBagApi.removeChaosToken = function(id)
return Global.call("removeChaosToken", id)
end
-- returns a chaos token to the bag and calls all relevant functions
---@param token tts__Object Chaos token to return
ChaosBagApi.returnChaosTokenToBag = function(token)
return Global.call("returnChaosTokenToBag", token)
end
-- spawns the specified chaos token and puts it into the chaos bag
---@param id string ID of the chaos token
ChaosBagApi.spawnChaosToken = function(id)
return Global.call("spawnChaosToken", id)
end
-- Checks to see if the chaos bag can be manipulated. If a player is searching the bag when tokens
-- 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.
ChaosBagApi.canTouchChaosTokens = function()
return Global.call("canTouchChaosTokens")
end
-- called by playermats (by the "Draw chaos token" button)
---@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
ChaosBagApi.drawChaosToken = function(mat, drawAdditional, tokenType, guidToBeResolved)
return Global.call("drawChaosToken", {mat = mat, drawAdditional = drawAdditional, tokenType = tokenType, guidToBeResolved = guidToBeResolved})
end
-- returns a Table List of chaos token ids in the current chaos bag
-- requires copying the data into a new table because TTS is weird about handling table return values in Global
ChaosBagApi.getIdUrlMap = function()
return Global.getTable("ID_URL_MAP")
end
return ChaosBagApi
end
end)
__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules)
do
local GUIDReferenceApi = {}
local function getGuidHandler()
return getObjectFromGUID("123456")
end
---@param owner string Parent object for this search
---@param type string Type of object to search for
---@return any: Object reference to the matching object
GUIDReferenceApi.getObjectByOwnerAndType = function(owner, type)
return getGuidHandler().call("getObjectByOwnerAndType", { owner = owner, type = type })
end
-- returns all matching objects as a table with references
---@param type string Type of object to search for
---@return table: List of object references to matching objects
GUIDReferenceApi.getObjectsByType = function(type)
return getGuidHandler().call("getObjectsByType", type)
end
-- returns all matching objects as a table with references
---@param owner string Parent object for this search
---@return table: List of object references to matching objects
GUIDReferenceApi.getObjectsByOwner = function(owner)
return getGuidHandler().call("getObjectsByOwner", owner)
end
-- sends new information to the reference handler to edit the main index
---@param owner string Parent of the object
---@param type string Type of the object
---@param guid string GUID of the object
GUIDReferenceApi.editIndex = function(owner, type, guid)
return getGuidHandler().call("editIndex", {
owner = owner,
type = type,
guid = guid
})
end
return GUIDReferenceApi
end
end)
2024-01-06 21:32:07 -05:00
__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules)
require("chaosbag/BlessCurseManager")
end)
2023-04-22 16:56:01 -04:00
__bundle_register("chaosbag/BlessCurseManager", function(require, _LOADED, __bundle_register, __bundle_modules)
2024-02-04 10:51:51 -05:00
local chaosBagApi = require("chaosbag/ChaosBagApi")
local tokenArrangerApi = require("accessories/TokenArrangerApi")
2022-12-13 14:02:30 -05:00
-- common button parameters
local buttonParamaters = {}
buttonParamaters.function_owner = self
buttonParamaters.color = { 0, 0, 0, 0 }
buttonParamaters.width = 700
buttonParamaters.height = 700
2023-04-22 16:56:01 -04:00
local updating
2022-12-13 14:02:30 -05:00
---------------------------------------------------------
-- creating buttons and menus + initializing tables
---------------------------------------------------------
2024-02-04 10:51:51 -05:00
function onLoad()
-- index: 0 - bless
buttonParamaters.click_function = "clickBless"
buttonParamaters.position = { -1.03, 0, 0.46 }
buttonParamaters.tooltip = "Add / Remove Bless"
self.createButton(buttonParamaters)
-- index: 1 - curse
buttonParamaters.click_function = "clickCurse"
buttonParamaters.position[1] = -buttonParamaters.position[1]
buttonParamaters.tooltip = "Add / Remove Curse"
self.createButton(buttonParamaters)
-- index: 2 - bless count
buttonParamaters.tooltip = ""
buttonParamaters.click_function = "none"
buttonParamaters.width = 0
buttonParamaters.height = 0
buttonParamaters.color = { 0.4, 0.4, 0.4 }
buttonParamaters.font_color = { 1, 1, 1 }
buttonParamaters.font_size = 235
buttonParamaters.position = { -1.03, 0.06, -0.8 }
self.createButton(buttonParamaters)
-- index: 3 - curse count
buttonParamaters.position[1] = -buttonParamaters.position[1]
self.createButton(buttonParamaters)
-- context menu
self.addContextMenuItem("Remove all", doRemove)
self.addContextMenuItem("Reset", doReset)
-- initializing tables
initializeState()
broadcastCount("Curse")
broadcastCount("Bless")
2023-08-27 21:09:46 -04:00
end
function resetTables()
2024-02-04 10:51:51 -05:00
numInPlay = { Bless = 0, Curse = 0 }
tokensTaken = { Bless = {}, Curse = {} }
sealedTokens = {}
2022-12-13 14:02:30 -05:00
end
function initializeState()
2024-02-04 10:51:51 -05:00
resetTables()
-- count tokens in the bag
local chaosBag = chaosBagApi.findChaosBag()
for _, v in ipairs(chaosBag.getObjects()) do
if v.name == "Bless" then
numInPlay.Bless = numInPlay.Bless + 1
elseif v.name == "Curse" then
numInPlay.Curse = numInPlay.Curse + 1
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
end
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
-- find tokens in the play area
for _, obj in ipairs(getObjects()) do
local pos = obj.getPosition()
2024-02-17 19:48:30 -05:00
if pos.x > -65 and pos.x < 10 and pos.z > -35 and pos.z < 35 and obj.type == "Tile" then
2024-02-04 10:51:51 -05:00
if obj.getName() == "Bless" then
table.insert(tokensTaken.Bless, obj.getGUID())
numInPlay.Bless = numInPlay.Bless + 1
elseif obj.getName() == "Curse" then
table.insert(tokensTaken.Curse, obj.getGUID())
numInPlay.Curse = numInPlay.Curse + 1
end
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
end
updateButtonLabels()
end
function updateButtonLabels()
self.editButton({ index = 2, label = formatTokenCount("Bless", true)})
self.editButton({ index = 3, label = formatTokenCount("Curse", true)})
2022-12-13 14:02:30 -05:00
end
function broadcastCount(token)
2024-02-04 10:51:51 -05:00
local count = formatTokenCount(token)
if count == "(0 + 0)" then return end
broadcastToAll(token .. " Tokens " .. count, "White")
2022-12-13 14:02:30 -05:00
end
2023-08-27 21:09:46 -04:00
function broadcastStatus(color)
2024-02-04 10:51:51 -05:00
broadcastToColor("Curse Tokens " .. formatTokenCount("Curse"), color, "White")
broadcastToColor("Bless Tokens " .. formatTokenCount("Bless"), color, "White")
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
---------------------------------------------------------
-- TTS event handling
---------------------------------------------------------
-- enable tracking of bag changes for 1 second
function onObjectDrop(_, object)
if not isBlurseToken(object) then return end
-- check if object was dropped in chaos bag area
for _, zone in ipairs(object.getZones()) do
if zone.getName() == "ChaosBagZone" then
trackBagChange = true
Wait.time(function() trackBagChange = false end, 1)
return
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
end
end
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
-- handle manual returning of bless / curse tokens
function onObjectEnterContainer(container, object)
if not (trackBagChange and isChaosbag(container) and isBlurseToken(object)) then return end
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
-- small delay to ensure token has entered bag
Wait.time(doReset, 0.5)
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
function isChaosbag(obj)
if obj.getDescription() ~= "Chaos Bag" then return end -- early exit for performance
return obj == chaosBagApi.findChaosBag()
2023-04-22 16:56:01 -04:00
end
2024-02-04 10:51:51 -05:00
function isBlurseToken(obj)
local name = obj.getName()
return name == "Bless" or name == "Curse"
2022-12-13 14:02:30 -05:00
end
---------------------------------------------------------
2024-02-04 10:51:51 -05:00
-- context menu functions
2022-12-13 14:02:30 -05:00
---------------------------------------------------------
2024-02-04 10:51:51 -05:00
function doRemove(color)
local chaosBag = chaosBagApi.findChaosBag()
-- remove tokens from chaos bag
local count = { Bless = 0, Curse = 0 }
for _, v in ipairs(chaosBag.getObjects()) do
if v.name == "Bless" or v.name == "Curse" then
chaosBag.takeObject({
guid = v.guid,
position = { 0, 5, 0 },
callback_function = function(obj) obj.destruct() end
})
count[v.name] = count[v.name] + 1
end
end
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
broadcastToColor("Removed " .. count.Bless .. " Bless and " .. count.Curse .. " Curse tokens from the chaos bag.", color, "White")
broadcastToColor("Removed " .. removeTakenTokens("Bless") .. " Bless and " .. removeTakenTokens("Curse") .. " Curse tokens from play.", color, "White")
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
resetTables()
updateButtonLabels()
tokenArrangerApi.layout()
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
function doReset()
initializeState()
broadcastCount("Curse")
broadcastCount("Bless")
tokenArrangerApi.layout()
2022-12-13 14:02:30 -05:00
end
---------------------------------------------------------
2024-02-04 10:51:51 -05:00
-- click functions
2022-12-13 14:02:30 -05:00
---------------------------------------------------------
2024-02-04 10:51:51 -05:00
function clickBless(_, color, isRightClick)
playerColor = color
callFunctions("Bless", isRightClick)
end
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
function clickCurse(_, color, isRightClick)
playerColor = color
callFunctions("Curse", isRightClick)
end
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
function callFunctions(type, isRightClick)
if not chaosBagApi.canTouchChaosTokens() then return end
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
if isRightClick then
removeToken(type)
else
addToken(type)
end
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
tokenArrangerApi.layout()
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
---------------------------------------------------------
-- called functions
---------------------------------------------------------
2023-04-22 16:56:01 -04:00
-- returns a formatted string with information about the provided token type (bless / curse)
2024-02-17 19:48:30 -05:00
---@param type string Type of chaos token ("Bless" or "Curse")
---@param omitBrackets? boolean Controls whether the brackets should be omitted from the return
---@return string tokenCount
2024-02-04 10:51:51 -05:00
function formatTokenCount(type, omitBrackets)
if omitBrackets then
return (numInPlay[type] - #tokensTaken[type]) .. " + " .. #tokensTaken[type]
else
return "(" .. (numInPlay[type] - #tokensTaken[type]) .. " + " .. #tokensTaken[type] .. ")"
end
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
-- seals a token on a card (called by cards that seal bless/curse tokens)
2024-02-17 19:48:30 -05:00
---@param param table This contains the type and guid of the sealed token
2023-04-22 16:56:01 -04:00
function sealedToken(param)
2024-02-04 10:51:51 -05:00
table.insert(tokensTaken[param.type], param.guid)
broadcastCount(param.type)
updateButtonLabels()
2023-04-22 16:56:01 -04:00
end
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
-- returns a token to the bag (called by cards that seal bless/curse tokens)
2024-02-17 19:48:30 -05:00
---@param param table This contains the type and guid of the released token
2023-04-22 16:56:01 -04:00
function releasedToken(param)
2024-02-04 10:51:51 -05:00
for i, v in ipairs(tokensTaken[param.type]) do
if v == param.guid then
table.remove(tokensTaken[param.type], i)
break
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
end
updateDisplayAndBroadcast(param.type)
end
-- removes a token (called by cards that seal bless/curse tokens)
2024-02-17 19:48:30 -05:00
---@param param table This contains the type and guid of the released token
2024-02-04 10:51:51 -05:00
function returnedToken(param)
for i, v in ipairs(tokensTaken[param.type]) do
if v == param.guid then
table.remove(tokensTaken[param.type], i)
numInPlay[param.type] = numInPlay[param.type] - 1
break
2023-04-22 16:56:01 -04:00
end
2024-02-04 10:51:51 -05:00
end
updateDisplayAndBroadcast(param.type)
end
function updateDisplayAndBroadcast(type)
if not updating then
updating = true
Wait.frames(function()
broadcastCount(type)
updateButtonLabels()
updating = false
end, 5)
end
2022-12-13 14:02:30 -05:00
end
---------------------------------------------------------
2024-02-04 10:51:51 -05:00
-- main functions: add and remove
2022-12-13 14:02:30 -05:00
---------------------------------------------------------
function addToken(type)
2024-02-04 10:51:51 -05:00
if numInPlay[type] == 10 then
printToColor("10 tokens already in play, not adding any.", playerColor)
return
end
numInPlay[type] = numInPlay[type] + 1
printToAll("Adding " .. type .. " token " .. formatTokenCount(type))
updateButtonLabels()
return chaosBagApi.spawnChaosToken(type)
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
function removeToken(type)
local chaosBag = chaosBagApi.findChaosBag()
local tokens = {}
for _, v in ipairs(chaosBag.getObjects()) do
if v.name == type then
table.insert(tokens, v.guid)
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
end
if #tokens == 0 then
printToColor("No " .. type .. " tokens in the chaos bag.", playerColor)
return
end
chaosBag.takeObject({
guid = table.remove(tokens),
smooth = false,
callback_function = function(obj)
numInPlay[type] = numInPlay[type] - 1
printToAll("Removing " .. type .. " token " .. formatTokenCount(type))
updateButtonLabels()
obj.destruct()
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
})
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
-- removing tokens that were 'taken'
function removeTakenTokens(type)
local count = 0
for _, guid in ipairs(tokensTaken[type]) do
2022-12-13 14:02:30 -05:00
local token = getObjectFromGUID(guid)
2024-02-04 10:51:51 -05:00
if token ~= nil then
token.destruct()
count = count + 1
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
end
return count
2022-12-13 14:02:30 -05:00
end
---------------------------------------------------------
2024-02-04 10:51:51 -05:00
-- Wendy's Menu (context menu for cards on hotkey press)
2022-12-13 14:02:30 -05:00
---------------------------------------------------------
2023-04-22 16:56:01 -04:00
function addMenuOptions(parameters)
2024-02-04 10:51:51 -05:00
local playerColor = parameters.playerColor
local hoveredObject = parameters.hoveredObject
if hoveredObject == nil or hoveredObject.type ~= "Card" then
broadcastToColor("Right-click seal options can only be added to cards.", playerColor)
return
elseif hoveredObject.hasTag("CardThatSeals") or hoveredObject.getVar("MENU_ADDED") == true then
broadcastToColor("This card already has a sealing context menu.", playerColor)
return
end
2022-12-13 14:02:30 -05:00
2024-02-04 10:51:51 -05:00
hoveredObject.addContextMenuItem("Seal Bless", function(color)
sealToken("Bless", color, hoveredObject)
tokenArrangerApi.layout()
end, true)
hoveredObject.addContextMenuItem("Release Bless", function(color)
releaseToken("Bless", color, hoveredObject)
tokenArrangerApi.layout()
end, true)
hoveredObject.addContextMenuItem("Seal Curse", function(color)
sealToken("Curse", color, hoveredObject)
tokenArrangerApi.layout()
end, true)
hoveredObject.addContextMenuItem("Release Curse", function(color)
releaseToken("Curse", color, hoveredObject)
tokenArrangerApi.layout()
end, true)
broadcastToColor("Right-click seal options added to " .. hoveredObject.getName(), playerColor)
hoveredObject.setVar("MENU_ADDED", true)
sealedTokens[hoveredObject.getGUID()] = {}
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
function sealToken(type, playerColor, hoveredObject)
local chaosBag = chaosBagApi.findChaosBag()
for i, token in ipairs(chaosBag.getObjects()) do
if token.name == type then
return chaosBag.takeObject({
position = hoveredObject.getPosition() + Vector(0, 1, 0),
index = i - 1,
smooth = false,
callback_function = function(obj)
table.insert(sealedTokens[hoveredObject.getGUID()], obj)
table.insert(tokensTaken[type], obj.getGUID())
tokenArrangerApi.layout()
updateDisplayAndBroadcast(type)
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
})
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
end
printToColor(type .. " token not found in bag", playerColor)
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
function releaseToken(type, playerColor, hoveredObject)
local chaosBag = chaosBagApi.findChaosBag()
local tokens = sealedTokens[hoveredObject.getGUID()]
if tokens == nil or #tokens == 0 then return end
for i, token in ipairs(tokens) do
if token ~= nil and token.getName() == type then
local guid = token.getGUID()
chaosBag.putObject(token)
for j, v in ipairs(tokensTaken[type]) do
if v == guid then
table.remove(tokensTaken[type], j)
table.remove(tokens, i)
tokenArrangerApi.layout()
updateDisplayAndBroadcast(type)
return
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
end
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
end
printToColor(type .. " token not sealed on " .. hoveredObject.getName(), playerColor)
2022-12-13 14:02:30 -05:00
end
2024-02-04 10:51:51 -05:00
function none() end
2022-12-13 14:02:30 -05:00
end)
return __bundle_require("__root")