-- 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("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("tokens/BlessCurseManager") end) __bundle_register("tokens/BlessCurseManager", function(require, _LOADED, __bundle_register, __bundle_modules) -- Bless / Curse Manager -- updated by: Chr1Z -- made by: Tikatoy -- description: helps with adding / removing and sealing of bless and curse tokens information = { version = "3.5", last_updated = "12.11.2022" } local IMAGE_URL = { Bless = "http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/", Curse = "http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/" } -- common button parameters local buttonParamaters = {} buttonParamaters.function_owner = self buttonParamaters.color = { 0, 0, 0, 0 } buttonParamaters.width = 700 buttonParamaters.height = 700 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 = " " -- variable will be set by outside call tokenArranger = nil --------------------------------------------------------- -- 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) self.addContextMenuItem("More Information", function() printToAll("------------------------------", "White") printToAll("Bless / Curse Manager v" .. information["version"] .. " by Chr1Z", "Orange") printToAll("last updated: " .. information["last_updated"], "White") printToAll("original by Tikatoy", "White") end) -- hotkeys addHotkey("Bless Curse Status", printStatus, false) addHotkey("Wendy's Menu", addMenuOptions, false) -- initializing tables numInPlay = { Bless = 0, Curse = 0 } tokensTaken = { Bless = {}, Curse = {} } sealedTokens = {} Wait.time(initializeState, 1) end function initializeState() -- count tokens in the bag local chaosbag = getChaosBag() if chaosbag == nil then return end 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() if pos.x > -50 and pos.x < 50 and pos.z > 8 and pos.z < 50 then 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 broadcastCount("Curse") broadcastCount("Bless") end function broadcastCount(token) local count = getTokenCount(token) if count == "(0/0)" then return end broadcastToAll(token .. " Tokens " .. count, "White") end function printStatus(color) broadcastToColor("Curse Tokens " .. getTokenCount("Curse"), color, "White") broadcastToColor("Bless Tokens " .. getTokenCount("Bless"), color, "White") end -- context menu function 1 function doRemove(color) local chaosbag = getChaosBag() if chaosbag == nil then broadcastToAll("Chaos bag not found!", "Red") return end -- 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 broadcastToColor("Removed " .. count["Bless"] .. " Bless and " .. count["Curse"] .. " Curse tokens from the chaos bag.", color, "White") -- removing tokens that were 'taken' local function removeType(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 end broadcastToColor("Removed " .. removeType("Bless") .. " Bless and " .. removeType("Curse") .. " Curse tokens from play.", color, "White") doReset(color) end -- context menu function 2 function doReset(color) -- delete previously pulled out tokens by the token arranger if tokenArranger then tokenArranger.call("deleteCopiedTokens") end playerColor = color numInPlay = { Bless = 0, Curse = 0 } tokensTaken = { Bless = {}, Curse = {} } initializeState() updateTokenArranger() 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) if not Global.call("canTouchChaosTokens") then return end 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 if success ~= 0 then updateTokenArranger() end end UPDATING = false function updateTokenArranger() if tokenArranger and not UPDATING then UPDATING = true Wait.time(function() UPDATING = false tokenArranger.call("layout") end, 1.5) end end function getChaosBag() local zone = getObjectFromGUID("83ef06") if zone == nil then printToAll("Zone for chaosbag not found!", "Red") return end local items = zone.getObjects() local chaosbag = nil for _, v in ipairs(items) do if v.getDescription() == "Chaos Bag" then chaosbag = getObjectFromGUID(v.getGUID()) break end end if chaosbag == nil then printToColor("No chaos bag found", playerColor) end return chaosbag end function getTokenCount(type) if type == nil then type = mode end return "(" .. (numInPlay[type] - #tokensTaken[type]) .. "/" .. #tokensTaken[type] .. ")" 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 return spawnToken(type) end function spawnToken(type) local chaosbag = getChaosBag() if chaosbag == nil then return 0 end local pos = chaosbag.getPosition() local obj = spawnObject({ type = 'Custom_Tile', position = { pos.x, pos.y + 1, pos.z }, callback_function = function(obj) obj.setName(type) chaosbag.putObject(obj) numInPlay[type] = numInPlay[type] + 1 printToAll("Adding " .. type .. " token " .. getTokenCount(type)) end }) obj.setCustomObject({ type = 2, image = IMAGE_URL[type], thickness = 0.1, }) obj.scale { 0.81, 1, 0.81 } end function takeToken(type, remove) local chaosbag = getChaosBag() if chaosbag == nil then broadcastToAll("Chaos bag not found!", "Red") return 0 end 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 printToAll("Removing " .. type .. " token " .. getTokenCount(type)) obj.destruct() else table.insert(tokensTaken[type], obj.getGUID()) printToAll("Taking " .. type .. " token " .. getTokenCount(type)) 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 local chaosbag = getChaosBag() if chaosbag == nil then return 0 end chaosbag.putObject(token) printToAll("Returning " .. type .. " token " .. getTokenCount(type)) end --------------------------------------------------------- -- Wendy Menu (context menu for cards on hotkey press) --------------------------------------------------------- function addMenuOptions(playerColor, hoveredObject) 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) updateTokenArranger() end, true) hoveredObject.addContextMenuItem("Release Bless", function(color) releaseToken("Bless", color, hoveredObject) updateTokenArranger() end, true) hoveredObject.addContextMenuItem("Seal Curse", function(color) sealToken("Curse", color, hoveredObject) updateTokenArranger() end, true) hoveredObject.addContextMenuItem("Release Curse", function(color) releaseToken("Curse", color, hoveredObject) updateTokenArranger() 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) local chaosbag = getChaosBag() 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()) printToColor("Sealing " .. type .. " token " .. getTokenCount(type), playerColor) end, 1) end }) return end end printToColor(type .. " token not found in bag", playerColor) end function releaseToken(type, playerColor, enemy) local chaosbag = getChaosBag() 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) printToColor("Releasing " .. type .. " token" .. getTokenCount(type), playerColor) return end end end end printToColor(type .. " token not sealed on " .. enemy.getName(), playerColor) end end) return __bundle_require("__root")