-- 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("accessories/UnderworldMarketHelper") end) __bundle_register("accessories/UnderworldMarketHelper", function(require, _LOADED, __bundle_register, __bundle_modules) local searchLib = require("util/SearchLib") function onload(savedData) revealCardPositions = { Vector(3.5, 0.25, 0), Vector(-3.5, 0.25, 0) } revealCardPositionsSwap = { Vector(-3.5, 0.25, 0), Vector(3.5, 0.25, 0) } self.createButton({ label = 'Underworld Market\nHelper', click_function = "none", function_owner = self, position = {0,-0.1,-1.6}, height = 0, width = 0, font_size = 145, font_color = {1,1,1} }) hiddenCards = 10 hiddenCardLabel = '-----' isSetup = false movingCards = false self.addContextMenuItem('Reset helper', resetHelper) if savedData ~= '' then local loaded_data = JSON.decode(savedData) hiddenCards = loaded_data.saved_hiddenCards isSetup = true refreshButtons() end end function onSave() return JSON.encode({ saved_hiddenCards = hiddenCards }) end function onObjectEnterContainer(container, object) if container ~= self then return end if isSetup and object.tag == "Card" then refreshButtons() end if object.tag == "Deck" then if validateDeck(object) then takeDeckOut(object.getGUID(), self.getPosition() + Vector(0, 0.1, 0)) refreshButtons() isSetup = true end elseif object.tag ~= "Card" then broadcastToAll("The 'Underworld Market Helper' is meant to be used for cards.", "White") end end function onObjectLeaveContainer(container, object) if container ~= self then return end if isSetup then refreshButtons() end end function validateDeck(deck) if deck.getQuantity() ~= 10 then print('Underworld Market Helper: Deck must include exactly 10 cards.') return false end local illicitCount = 0 for _, card in ipairs(deck.getObjects()) do decodedGMNotes = JSON.decode(card.gm_notes) if decodedGMNotes ~= nil and string.find(decodedGMNotes.traits, "Illicit", 1, true) then illicitCount = illicitCount + 1 end end if illicitCount ~= 10 then print('Underworld Market Helper: Deck must include 10 Illicit cards.') return false end return true end function refreshButtons() local cardsList = '' for i, card in ipairs(self.getObjects()) do local localCardName = card.name if i <= hiddenCards then localCardName = hiddenCardLabel end cardsList = cardsList .. localCardName .. '\n' end self.clearButtons() self.createButton({ label = 'Market Deck:', click_function = "none", function_owner = self, position = {0,-0.1,-1.6}, height = 0, width = 0, font_size = 150, font_color = {1,1,1} }) self.createButton({ label = cardsList, click_function = "none", function_owner = self, position = {0,-0.1,0.15}, height = 0, width = 0, font_size = 115, font_color = {1,1,1} }) self.createButton({ click_function = 'revealFirstTwoCards', function_owner = self, label = 'Reveal', position = {-0.85,0,1.6}, width = 375, height = 175, font_size = 90 }) self.createButton({ click_function = 'swap', function_owner = self, label = 'Swap', position = {0,0,1.6}, width = 375, height = 175, font_size = 90 }) self.createButton({ click_function = 'finish', function_owner = self, label = 'Finish', position = {0.85,0,1.6}, width = 375, height = 175, font_size = 90 }) end function takeDeckOut(guid, pos) local deck = self.takeObject({ guid = guid, position = pos, smooth = false }) for i = 1, #deck.getObjects() do self.putObject(deck.takeObject({ position = pos + Vector(0, 0.1 * i, 0), smooth = false })) end self.shuffle() end function getRevealedCards() local revealedCards = {} for _, pos in ipairs(revealCardPositions) do for _, obj in ipairs(searchLib.atPosition(self.positionToWorld(pos), "isCard")) do table.insert(revealedCards, obj.getGUID()) end end return revealedCards end function revealFirstTwoCards() if movingCards or #getRevealedCards() > 0 then return end for i, card in ipairs(self.getObjects()) do movingCards = true self.takeObject({ index = 0, rotation = self.getRotation(), position = self.positionToWorld(revealCardPositions[i]), callback_function = function(obj) obj.resting = true movingCards = false end }) hiddenCards = hiddenCards - 1 if i == 2 or #self.getObjects() == 0 then break end end refreshButtons() end function swap() if movingCards then return end local revealedCards = getRevealedCards() if #revealedCards == 2 then for i, revealedCardGUID in ipairs(revealedCards) do local revealedCard = getObjectFromGUID(revealedCardGUID) revealedCard.setPositionSmooth(self.positionToWorld(revealCardPositionsSwap[i]), false, false) end end end function finish() if movingCards then return end local revealedCards = getRevealedCards() movingCards = true for i, revealedCardGUID in ipairs(revealedCards) do self.putObject(getObjectFromGUID(revealedCardGUID)) end Wait.time( function() movingCards = false end, 0.75) end function resetHelper() for i, card in ipairs(self.getObjects()) do self.takeObject({ index = 0, smooth = false, rotation = self.getRotation(), position = self.positionToWorld(revealCardPositions[2]) }) end self.clearButtons() self.createButton({ label = 'Underworld Market\nHelper', click_function = "none", function_owner = self, position = {0,-0.1,-1.6}, height = 0, width = 0, font_size = 145, font_color = {1,1,1} }) hiddenCards = 10 isSetup = false movingCards = false self.reset() print('Underworld Market Helper: Helper has been reset.') end end) __bundle_register("util/SearchLib", function(require, _LOADED, __bundle_register, __bundle_modules) do local SearchLib = {} local filterFunctions = { isActionToken = function(x) return x.getDescription() == "Action Token" end, isCard = function(x) return x.type == "Card" end, isDeck = function(x) return x.type == "Deck" end, isCardOrDeck = function(x) return x.type == "Card" or x.type == "Deck" end, isClue = function(x) return x.memo == "clueDoom" and x.is_face_down == false end, isTileOrToken = function(x) return x.type == "Tile" end } -- performs the actual search and returns a filtered list of object references ---@param pos Table Global position ---@param rot Table Global rotation ---@param size Table Size ---@param filter String Name of the filter function ---@param direction Table Direction (positive is up) ---@param maxDistance Number Distance for the cast local function returnSearchResult(pos, rot, size, filter, direction, maxDistance) if filter then filter = filterFunctions[filter] end local searchResult = Physics.cast({ origin = pos, direction = direction or { 0, 1, 0 }, orientation = rot or { 0, 0, 0 }, type = 3, size = size, max_distance = maxDistance or 0 }) -- filtering the result local objList = {} for _, v in ipairs(searchResult) do if not filter or filter(v.hit_object) then table.insert(objList, v.hit_object) end end return objList end -- searches the specified area SearchLib.inArea = function(pos, rot, size, filter) return returnSearchResult(pos, rot, size, filter) end -- searches the area on an object SearchLib.onObject = function(obj, filter) pos = obj.getPosition() size = obj.getBounds().size:setAt("y", 1) return returnSearchResult(pos, _, size, filter) end -- searches the specified position (a single point) SearchLib.atPosition = function(pos, filter) size = { 0.1, 2, 0.1 } return returnSearchResult(pos, _, size, filter) end -- searches below the specified position (downwards until y = 0) SearchLib.belowPosition = function(pos, filter) direction = { 0, -1, 0 } maxDistance = pos.y return returnSearchResult(pos, _, size, filter, direction, maxDistance) end return SearchLib end end) return __bundle_require("__root")