-- 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) __bundle_register("playercards/CardsWithHelper", function(require, _LOADED, __bundle_register, __bundle_modules) --[[ Library for cards that have helpers This file is used to share code between cards with helpers. It syncs the visibility of the helper with the option panel and makes sure the card has the respective tag. Additionally, it will call 'initiliaze()' and 'shutOff()' in the parent file if they are present. Instructions: 1) Define the global variables before requiring this file: hasXML = true (whether the card has an XML display) isHelperEnabled = false (default state of the helper, should be 'false') 2) In 'onLoad()'', call 'syncDisplayWithOptionPanel()' ----------------------------------------------------------]] local optionPanelApi = require("core/OptionPanelApi") -- if the respective option is enabled in onLoad(), enable the helper function syncDisplayWithOptionPanel() self.addTag("CardWithHelper") local options = optionPanelApi.getOptions() if options.enableCardHelpers then setHelperState(true) else updateDisplay() end end -- forces a new state function setHelperState(newState) isHelperEnabled = newState updateSave() updateDisplay() end -- toggles the current state function toggleHelper() isHelperEnabled = not isHelperEnabled updateSave() updateDisplay() end -- updates the visibility and calls events (after a small delay to allow XML being set) function updateDisplay() Wait.frames(actualDisplayUpdate, 5) end function actualDisplayUpdate() if isHelperEnabled then self.clearContextMenu() self.addContextMenuItem("Disable Helper", toggleHelper) if hasXML then self.UI.show("Helper") end if initialize then initialize() end else self.clearContextMenu() self.addContextMenuItem("Enable Helper", toggleHelper) if hasXML then self.UI.hide("Helper") end if shutOff then shutOff() end end end end) __bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local OptionPanelApi = {} -- loads saved options ---@param options table Set a new state for the option table OptionPanelApi.loadSettings = function(options) return Global.call("loadSettings", options) end ---@return any: Table of option panel state OptionPanelApi.getOptions = function() return Global.getTable("optionPanel") end return OptionPanelApi end end) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/NkosiMabati3") end) __bundle_register("playercards/cards/NkosiMabati3", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/CardsWithHelper") local chaosBagApi = require("chaosbag/ChaosBagApi") -- 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" } function onSave() return JSON.encode(sigil) end function onLoad(savedData) self.addContextMenuItem("Enable Helper", chooseSigil) sigil = JSON.decode(savedData) if sigil and sigil ~= nil then makeXMLButton() self.clearContextMenu() self.addContextMenuItem("Clear Helper", deleteButtons) end end 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", attributes = { height = 450, width = 1400, rotation = "0 0 180", scale = "0.1 0.1 1", position = "0 -55 -22", padding = "50 50 50 50", font = "font_teutonic-arkham", fontSize = 300, iconWidth = "400", iconAlignment = "Right", onClick = "resolveSigil", icon = iconName, color = tokenColor[sigil], textColor = "White" }, value = "Resolve" } } ) end -- Create dialog window to choose sigil and create sigil-drawing button function chooseSigil(playerColor) Player[playerColor].clearSelectedObjects() self.clearContextMenu() self.addContextMenuItem("Clear Helper", deleteButtons) -- 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() end ) end -- Delete button and remove sigil function deleteButtons(playerColor) Player[playerColor].clearSelectedObjects() self.clearContextMenu() self.addContextMenuItem("Enable Helper", chooseSigil) self.UI.setXml("") sigil = nil end function resolveSigil() local match = false for _, obj in ipairs(chaosBagApi.findChaosBag().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 end Global.call("activeRedrawEffect", { DRAW_SPECIFIC_TOKEN = sigil, VALID_TOKENS = { ["Tablet"] = true, ["Elder Thing"] = true, ["Cultist"] = true } }) 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) 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) Global.call("releaseAllSealedTokens", playerColor) end -- returns all drawn tokens to the chaos bag ChaosBagApi.returnChaosTokens = function() 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) 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 ---@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 ---@param id string ID of the chaos token ChaosBagApi.spawnChaosToken = function(id) 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: True if the bag is manipulated, false if it should be blocked. ChaosBagApi.canTouchChaosTokens = function() return Global.call("canTouchChaosTokens") end -- draws a chaos token to a playermat ---@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 ---@param takeParameters? table Position and rotation of the location where the new token should be drawn to, usually to replace a returned token ---@return tts__Object: Object reference to the token that was drawn ChaosBagApi.drawChaosToken = function(mat, drawAdditional, tokenType, guidToBeResolved, takeParameters) return Global.call("drawChaosToken", { mat = mat, drawAdditional = drawAdditional, tokenType = tokenType, guidToBeResolved = guidToBeResolved, takeParameters = takeParameters }) 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) return __bundle_require("__root")