ah_sce_unpacked/unpacked/Custom_Token BlessCurse Manager 5933fb.ttslua

620 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-01-06 21:32:29 -05:00
__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.getTable("chaosTokens")
end
-- returns all sealed tokens on cards to the chaos bag
ChaosBagApi.releaseAllSealedTokens = function(playerColor)
return Global.call("releaseAllSealedTokens", playerColor)
end
-- returns all drawn tokens to the chaos bag
ChaosBagApi.returnChaosTokens = function(playerColor)
return Global.call("returnChaosTokens", playerColor)
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
-- 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 Boolean. 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)
ChaosBagApi.drawChaosToken = function(mat, tokenOffset, isRightClick)
return Global.call("drawChaosToken", {mat, tokenOffset, isRightClick})
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
-- returns all matching objects as a table with references
---@param owner String Parent object for this search
---@param type String Type of object to search for
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
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
GUIDReferenceApi.getObjectsByOwner = function(owner)
return getGuidHandler().call("getObjectsByOwner", owner)
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-01-06 21:32:07 -05:00
local chaosBagApi = require("chaosbag/ChaosBagApi")
2023-04-22 16:56:01 -04:00
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 altState = false
local MODE = {
[false] = "Add / Remove",
[true] = "Take / Return"
}
local BUTTON_COLOR = {
[false] = { 0.4, 0.4, 0.4 },
[true] = { 0.9, 0.9, 0.9 }
}
local FONT_COLOR = {
[false] = { 1, 1, 1 },
[true] = { 0, 0, 0 }
}
local whitespace = " "
local updating
2022-12-13 14:02:30 -05:00
---------------------------------------------------------
-- creating buttons and menus + initializing tables
---------------------------------------------------------
function onSave() return JSON.encode(altState) end
function onLoad(saved_state)
if saved_state ~= nil then
altState = JSON.decode(saved_state)
end
-- index: 0 - bless
buttonParamaters.click_function = "clickBless"
buttonParamaters.position = { -1.03, 0.05, 0.46 }
self.createButton(buttonParamaters)
-- index: 1 - curse
buttonParamaters.click_function = "clickCurse"
buttonParamaters.position[1] = -buttonParamaters.position[1]
self.createButton(buttonParamaters)
-- index: 2 - alternative mode (take / return)
buttonParamaters.click_function = "enableAlt"
buttonParamaters.width = 900
buttonParamaters.height = 210
buttonParamaters.position = { -1.03, 0.05, -0.85 }
self.createButton(buttonParamaters)
-- index: 3 - default mode (add / remove)
buttonParamaters.click_function = "enableDefault"
buttonParamaters.position[1] = -buttonParamaters.position[1]
self.createButton(buttonParamaters)
-- load labels, tooltips and colors
updateButtons()
-- context menu
self.addContextMenuItem("Remove all", doRemove)
self.addContextMenuItem("Reset", doReset)
2023-08-27 21:09:46 -04:00
-- initializing tables
initializeState()
broadcastCount("Curse")
broadcastCount("Bless")
end
function resetTables()
2022-12-13 14:02:30 -05:00
numInPlay = { Bless = 0, Curse = 0 }
tokensTaken = { Bless = {}, Curse = {} }
sealedTokens = {}
end
function initializeState()
2023-08-27 21:09:46 -04:00
resetTables()
2022-12-13 14:02:30 -05:00
-- count tokens in the bag
2024-01-06 21:32:07 -05:00
local chaosbag = chaosBagApi.findChaosBag()
2022-12-13 14:02:30 -05:00
local tokens = {}
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
end
end
-- find tokens in the play area
for _, obj in ipairs(getObjects()) do
local pos = obj.getPosition()
2023-08-27 21:09:46 -04:00
if pos.x > -65 and pos.x < 10 and pos.z > -35 and pos.z < 35 then
2022-12-13 14:02:30 -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
end
end
end
function broadcastCount(token)
2023-04-22 16:56:01 -04:00
local count = formatTokenCount(token)
2022-12-13 14:02:30 -05:00
if count == "(0/0)" then return end
broadcastToAll(token .. " Tokens " .. count, "White")
end
2023-08-27 21:09:46 -04:00
function broadcastStatus(color)
2023-04-22 16:56:01 -04:00
broadcastToColor("Curse Tokens " .. formatTokenCount("Curse"), color, "White")
broadcastToColor("Bless Tokens " .. formatTokenCount("Bless"), color, "White")
2022-12-13 14:02:30 -05:00
end
-- context menu function 1
function doRemove(color)
2024-01-06 21:32:07 -05:00
local chaosbag = chaosBagApi.findChaosBag()
2022-12-13 14:02:30 -05:00
-- 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
2023-04-22 16:56:01 -04: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
2023-08-27 21:09:46 -04:00
resetTables()
tokenArrangerApi.layout()
2022-12-13 14:02:30 -05:00
end
-- context menu function 2
function doReset(color)
initializeState()
2023-08-27 21:09:46 -04:00
broadcastCount("Curse")
broadcastCount("Bless")
2023-04-22 16:56:01 -04:00
tokenArrangerApi.layout()
end
-- removing tokens that were 'taken'
function removeTakenTokens(type)
local count = 0
for _, guid in ipairs(tokensTaken[type]) do
local token = getObjectFromGUID(guid)
if token ~= nil then
token.destruct()
count = count + 1
end
end
return count
2022-12-13 14:02:30 -05:00
end
---------------------------------------------------------
-- click functions
---------------------------------------------------------
-- click function 1
function clickBless(_, color, isRightClick)
playerColor = color
callFunctions("Bless", isRightClick)
end
-- click function 2
function clickCurse(_, color, isRightClick)
playerColor = color
callFunctions("Curse", isRightClick)
end
-- click function 3
function enableAlt()
if altState then return end
altState = not altState
updateButtons()
end
-- click function 4
function enableDefault()
if not altState then return end
altState = not altState
updateButtons()
end
---------------------------------------------------------
-- called functions
---------------------------------------------------------
function updateButtons()
self.editButton({
index = 0,
tooltip = MODE[altState] .. " Bless"
})
self.editButton({
index = 1,
tooltip = MODE[altState] .. " Curse"
})
self.editButton({
index = 2,
label = whitespace .. MODE[true] .. (altState and " ✓" or whitespace) .. " ",
color = BUTTON_COLOR[not altState],
font_color = FONT_COLOR[not altState]
})
self.editButton({
index = 3,
label = whitespace .. MODE[false] .. (altState and whitespace or " ✓") .. " ",
color = BUTTON_COLOR[altState],
font_color = FONT_COLOR[altState]
})
end
-- function that is called by click_functions 1+2 and calls the other functions
function callFunctions(token, isRightClick)
2024-01-06 21:32:07 -05:00
if not chaosBagApi.canTouchChaosTokens() then
2023-01-29 19:31:52 -05:00
return
end
2022-12-13 14:02:30 -05:00
local success
if not altState then
if isRightClick then
success = takeToken(token, true)
else
success = addToken(token)
end
else
if isRightClick then
success = returnToken(token)
else
success = takeToken(token, false)
end
end
2023-04-22 16:56:01 -04:00
if success ~= 0 then tokenArrangerApi.layout() end
2022-12-13 14:02:30 -05:00
end
2023-04-22 16:56:01 -04:00
-- returns a formatted string with information about the provided token type (bless / curse)
function formatTokenCount(type)
if type == nil then type = mode end
return "(" .. (numInPlay[type] - #tokensTaken[type]) .. "/" .. #tokensTaken[type] .. ")"
2022-12-13 14:02:30 -05:00
end
2023-04-22 16:56:01 -04:00
-- called by cards that seal bless/curse tokens
---@param param Table This contains the type and guid of the sealed token
function sealedToken(param)
table.insert(tokensTaken[param.type], param.guid)
broadcastCount(param.type)
end
2022-12-13 14:02:30 -05:00
2023-04-22 16:56:01 -04:00
-- called by cards that seal bless/curse tokens
---@param param Table This contains the type and guid of the released token
function releasedToken(param)
for i, v in ipairs(tokensTaken[param.type]) do
if v == param.guid then
table.remove(tokensTaken[param.type], i)
2022-12-13 14:02:30 -05:00
break
end
end
2023-04-22 16:56:01 -04:00
if not updating then
updating = true
Wait.frames(function()
broadcastCount(param.type)
updating = false
end, 1)
end
2022-12-13 14:02:30 -05:00
end
---------------------------------------------------------
-- main functions: add, take and return
---------------------------------------------------------
function addToken(type)
if numInPlay[type] == 10 then
printToColor("10 tokens already in play, not adding any.", playerColor)
return 0
end
2023-04-22 16:56:01 -04:00
numInPlay[type] = numInPlay[type] + 1
printToAll("Adding " .. type .. " token " .. formatTokenCount(type))
2024-01-06 21:32:07 -05:00
return chaosBagApi.spawnChaosToken(type)
2022-12-13 14:02:30 -05:00
end
function takeToken(type, remove)
2024-01-06 21:32:07 -05:00
local chaosbag = chaosBagApi.findChaosBag()
2022-12-13 14:02:30 -05:00
if not remove and not SEAL_CARD_MESSAGE then
broadcastToColor("For sealing tokens on cards try right-clicking on the card for seal options.", playerColor)
SEAL_CARD_MESSAGE = true
end
local tokens = {}
for _, v in ipairs(chaosbag.getObjects()) do
if v.name == type then
table.insert(tokens, v.guid)
end
end
if #tokens == 0 then
printToColor("No " .. type .. " tokens in the chaos bag.", playerColor)
return 0
end
local pos = self.getPosition() + Vector(2.25, 0, 0.85)
if type == "Curse" then pos[3] = pos[3] - 1.7 end
chaosbag.takeObject({
guid = table.remove(tokens),
position = pos,
smooth = false,
callback_function = function(obj)
if remove then
numInPlay[type] = numInPlay[type] - 1
2023-04-22 16:56:01 -04:00
printToAll("Removing " .. type .. " token " .. formatTokenCount(type))
2022-12-13 14:02:30 -05:00
obj.destruct()
else
table.insert(tokensTaken[type], obj.getGUID())
2023-04-22 16:56:01 -04:00
printToAll("Taking " .. type .. " token " .. formatTokenCount(type))
2022-12-13 14:02:30 -05:00
end
end
})
end
function returnToken(type)
local guid = table.remove(tokensTaken[type])
if guid == nil then
printToColor("No " .. type .. " tokens to return", playerColor)
return 0
end
local token = getObjectFromGUID(guid)
if token == nil then
printToColor("Couldn't find token " .. guid .. ", not returning to bag", playerColor)
return 0
end
2024-01-06 21:32:07 -05:00
local chaosbag = chaosBagApi.findChaosBag()
2022-12-13 14:02:30 -05:00
if chaosbag == nil then
return 0
end
chaosbag.putObject(token)
2023-04-22 16:56:01 -04:00
printToAll("Returning " .. type .. " token " .. formatTokenCount(type))
2022-12-13 14:02:30 -05:00
end
---------------------------------------------------------
-- Wendy Menu (context menu for cards on hotkey press)
---------------------------------------------------------
2023-04-22 16:56:01 -04:00
function addMenuOptions(parameters)
local playerColor = parameters.playerColor
local hoveredObject = parameters.hoveredObject
2022-12-13 14:02:30 -05:00
if hoveredObject == nil or hoveredObject.getVar("MENU_ADDED") == true then return end
if hoveredObject.tag ~= "Card" then
broadcastToColor("Right-click seal options can only be added to cards", playerColor)
return
end
hoveredObject.addContextMenuItem("Seal Bless", function(color)
sealToken("Bless", color, hoveredObject)
2023-04-22 16:56:01 -04:00
tokenArrangerApi.layout()
2022-12-13 14:02:30 -05:00
end, true)
hoveredObject.addContextMenuItem("Release Bless", function(color)
releaseToken("Bless", color, hoveredObject)
2023-04-22 16:56:01 -04:00
tokenArrangerApi.layout()
2022-12-13 14:02:30 -05:00
end, true)
hoveredObject.addContextMenuItem("Seal Curse", function(color)
sealToken("Curse", color, hoveredObject)
2023-04-22 16:56:01 -04:00
tokenArrangerApi.layout()
2022-12-13 14:02:30 -05:00
end, true)
hoveredObject.addContextMenuItem("Release Curse", function(color)
releaseToken("Curse", color, hoveredObject)
2023-04-22 16:56:01 -04:00
tokenArrangerApi.layout()
2022-12-13 14:02:30 -05:00
end, true)
broadcastToColor("Right-click seal options added to " .. hoveredObject.getName(), playerColor)
hoveredObject.setVar("MENU_ADDED", true)
sealedTokens[hoveredObject.getGUID()] = {}
end
function sealToken(type, playerColor, enemy)
2024-01-06 21:32:07 -05:00
local chaosbag = chaosBagApi.findChaosBag()
2022-12-13 14:02:30 -05:00
if chaosbag == nil then return end
local pos = enemy.getPosition()
for i, token in ipairs(chaosbag.getObjects()) do
if token.name == type then
chaosbag.takeObject({
position = { pos.x, pos.y + 1, pos.z },
index = i - 1,
smooth = false,
callback_function = function(obj)
Wait.frames(function()
table.insert(sealedTokens[enemy.getGUID()], obj)
table.insert(tokensTaken[type], obj.getGUID())
2023-04-22 16:56:01 -04:00
printToColor("Sealing " .. type .. " token " .. formatTokenCount(type), playerColor)
2022-12-13 14:02:30 -05:00
end, 1)
end
})
return
end
end
printToColor(type .. " token not found in bag", playerColor)
end
function releaseToken(type, playerColor, enemy)
2024-01-06 21:32:07 -05:00
local chaosbag = chaosBagApi.findChaosBag()
2022-12-13 14:02:30 -05:00
if chaosbag == nil then return end
local tokens = sealedTokens[enemy.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)
2023-04-22 16:56:01 -04:00
printToColor("Releasing " .. type .. " token" .. formatTokenCount(type), playerColor)
2022-12-13 14:02:30 -05:00
return
end
end
end
end
printToColor(type .. " token not sealed on " .. enemy.getName(), playerColor)
end
end)
2023-04-22 16:56:01 -04:00
__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules)
do
local TokenArrangerApi = {}
2024-01-06 21:32:29 -05:00
local guidReferenceApi = require("core/GUIDReferenceApi")
2023-04-22 16:56:01 -04:00
-- local function to call the token arranger, if it is on the table
---@param functionName String Name of the function to cal
---@param argument Variant Parameter to pass
local function callIfExistent(functionName, argument)
2024-01-06 21:32:29 -05:00
local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger")
2023-04-22 16:56:01 -04:00
if tokenArranger ~= nil then
tokenArranger.call(functionName, argument)
end
end
-- updates the token modifiers with the provided data
---@param tokenData 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)
2022-12-13 14:02:30 -05:00
return __bundle_require("__root")