diff --git a/unpacked.ttslua b/unpacked.ttslua index 44592a452..a30978f69 100644 --- a/unpacked.ttslua +++ b/unpacked.ttslua @@ -41,300 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("core/SoundCubeApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local SoundCubeApi = {} - - -- this table links the name of a trigger effect to its index - local soundIndices = { - ["Vacuum"] = 0, - ["Deep Bell"] = 1, - ["Dark Souls"] = 2 - } - - local function playTriggerEffect(index) - getObjectsWithTag("SoundCube")[1].AssetBundle.playTriggerEffect(index) - end - - -- plays the by name requested sound - ---@param soundName String Name of the sound to play - SoundCubeApi.playSoundByName = function(soundName) - playTriggerEffect(soundIndices[soundName]) - end - - return SoundCubeApi -end -end) -__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local CHAOS_TOKEN_NAMES = { - ["Elder Sign"] = true, - ["+1"] = true, - ["0"] = true, - ["-1"] = true, - ["-2"] = true, - ["-3"] = true, - ["-4"] = true, - ["-5"] = true, - ["-6"] = true, - ["-7"] = true, - ["-8"] = true, - ["Skull"] = true, - ["Cultist"] = true, - ["Tablet"] = true, - ["Elder Thing"] = true, - ["Auto-fail"] = true, - ["Bless"] = true, - ["Curse"] = true, - ["Frost"] = true - } - - local TokenChecker = {} - - -- returns true if the passed object is a chaos token (by name) - TokenChecker.isChaosToken = function(obj) - if CHAOS_TOKEN_NAMES[obj.getName()] then - return true - else - return false - end - end - - return TokenChecker -end -end) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlaymatApi = { } - local internal = { } - - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end - end - - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/Global") -end) __bundle_register("core/Global", function(require, _LOADED, __bundle_register, __bundle_modules) local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi") +local guidReferenceApi = require("core/GUIDReferenceApi") local mythosAreaApi = require("core/MythosAreaApi") local navigationOverlayApi = require("core/NavigationOverlayApi") local playAreaApi = require("core/PlayAreaApi") @@ -348,11 +57,8 @@ local tokenManager = require("core/token/TokenManager") -- general setup --------------------------------------------------------- -ENCOUNTER_DECK_POS = {-3.93, 1, 5.76} -ENCOUNTER_DECK_DISCARD_POSITION = {-3.85, 1, 10.38} - --- GUID of data helper -DATA_HELPER_GUID = "708279" +ENCOUNTER_DECK_POS = { -3.93, 1, 5.76 } +ENCOUNTER_DECK_DISCARD_POSITION = { -3.85, 1, 10.38 } -- GUIDs that will not be interactable (e.g. parts of the table) local NOT_INTERACTABLE = { @@ -373,14 +79,29 @@ chaosTokens = {} local chaosTokensLastMat = nil local bagSearchers = {} -local MAT_COLORS = {"White", "Orange", "Green", "Red"} +local MAT_COLORS = { "White", "Orange", "Green", "Red" } local hideTitleSplashWaitFunctionId = nil -- online functionality related variables -local MOD_VERSION = "3.3.0" +local MOD_VERSION = "3.4.0" local SOURCE_REPO = 'https://raw.githubusercontent.com/chr1z93/loadable-objects/main' -local library, requestObj, modMeta, notificationVisible +local library, requestObj, modMeta local acknowledgedUpgradeVersions = {} +local contentToShow = "campaigns" +local currentListItem = 1 +local xmlVisibility = { + downloadWindow = false, + optionPanel = false, + playareaGallery = false, + updateNotification = false +} +local tabIdTable = { + tab1 = "campaigns", + tab2 = "scenarios", + tab3 = "fanmadeCampaigns", + tab4 = "fanmadeScenarios", + tab5 = "fanmadePlayerCards" +} -- optionPanel data optionPanel = {} @@ -437,14 +158,6 @@ ID_URL_MAP = { -- data for chaos token stat tracker --------------------------------------------------------- -local MAT_GUID_TO_COLOR = { - ["Overall"] = "Overall", - ["8b081b"] = "White", - ["bd0ff4"] = "Orange", - ["383d8b"] = "Green", - ["0840d5"] = "Red" -} - local tokenDrawingStats = { ["Overall"] = {}, ["8b081b"] = {}, @@ -458,7 +171,12 @@ local tokenDrawingStats = { --------------------------------------------------------- -- saving state of optionPanel to restore later -function onSave() return JSON.encode({ optionPanel = optionPanel, acknowledgedUpgradeVersions = acknowledgedUpgradeVersions }) end +function onSave() + return JSON.encode({ + optionPanel = optionPanel, + acknowledgedUpgradeVersions = acknowledgedUpgradeVersions + }) +end function onLoad(savedData) if savedData then @@ -478,6 +196,11 @@ function onLoad(savedData) resetChaosTokenStatTracker() getModVersion() math.randomseed(os.time()) + + -- initialization of loadable objects library (delay to let Navigation Overlay build) + Wait.time(function() + WebRequest.get(SOURCE_REPO .. '/library.json', libraryDownloadCallback) + end, 1) end -- Event hook for any object search. When chaos tokens are manipulated while the chaos bag @@ -508,6 +231,19 @@ function tryObjectEnterContainer(container, object) return true end +-- TTS event for objects that enter zones +-- used to detect the "token discard zones" beneath the hand zones +function onObjectEnterZone(zone, enteringObj) + if zone.getName() ~= "TokenDiscardZone" then return end + if tokenChecker.isChaosToken(enteringObj) then return end + + if enteringObj.type == "Tile" and enteringObj.getMemo() and enteringObj.getLock() == false then + local matcolor = playmatApi.getMatColorByPosition(enteringObj.getPosition()) + local trash = guidReferenceApi.getObjectByOwnerAndType(matcolor, "Trash") + trash.putObject(enteringObj) + end +end + --------------------------------------------------------- -- chaos token drawing --------------------------------------------------------- @@ -625,8 +361,8 @@ function handleStatTrackerClick(_, _, isRightClick) if isRightClick then resetChaosTokenStatTracker() else - local squidKing = "Nobody" - local maxSquid = 0 + local squidKing = "Nobody" + local maxSquid = 0 local foundAnyStats = false for key, personalStats in pairs(tokenDrawingStats) do @@ -636,7 +372,9 @@ function handleStatTrackerClick(_, _, isRightClick) playerColor = "White" playerName = "Overall" else - playerColor = playmatApi.getPlayerColor(MAT_GUID_TO_COLOR[key]) + -- get mat color + local matColor = playmatApi.getMatColorByPosition(getObjectFromGUID(key).getPosition()) + playerColor = playmatApi.getPlayerColor(matColor) playerName = Player[playerColor].steam_name or playerColor local playerSquidCount = personalStats["Auto-fail"] @@ -656,8 +394,8 @@ function handleStatTrackerClick(_, _, isRightClick) if totalCount > 0 then foundAnyStats = true printToAll("------------------------------") - printToAll(playerName .. " Stats", playerColor) - + printToAll(playerName .. " Stats", playerColor) + for tokenName, value in pairs(personalStats) do if value ~= 0 then printToAll(tokenName .. ': ' .. tostring(value)) @@ -670,7 +408,7 @@ function handleStatTrackerClick(_, _, isRightClick) -- detect if any player drew tokens if foundAnyStats then printToAll("------------------------------") - printToAll(squidKing .. " is an auto-fail magnet.", {255, 0, 0}) + printToAll(squidKing .. " is an auto-fail magnet.", { 255, 0, 0 }) else printToAll("No tokens have been drawn yet.", "Yellow") end @@ -699,11 +437,11 @@ function createSetupButtons(args) if data ~= nil then local buttonParameters = {} buttonParameters.function_owner = args.object - buttonParameters.position = {0, 0.1, -0.15} - buttonParameters.scale = {0.47, 1, 0.47} + buttonParameters.position = { 0, 0.1, -0.15 } + buttonParameters.scale = { 0.47, 1, 0.47 } buttonParameters.height = 200 buttonParameters.width = 1150 - buttonParameters.color = {0.87, 0.8, 0.7} + buttonParameters.color = { 0.87, 0.8, 0.7 } if data.easy ~= nil then buttonParameters.label = "Easy" @@ -786,7 +524,8 @@ function fillContainer(args) end function getDataValue(storage, key) - local data = getObjectFromGUID(DATA_HELPER_GUID).getTable(storage) + local DATA_HELPER = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") + local data = DATA_HELPER.getTable(storage) if data ~= nil then local value = data[key] if value ~= nil then @@ -831,7 +570,6 @@ function getChaosBagState() end return tokens - end -- respawns the chaos bag with a new state of tokens @@ -860,7 +598,7 @@ function setChaosBagState(tokenList) -- overwrite chaos bag content and respawn it chaosbagData.ContainedObjects = containedObjects chaosbag.destruct() - spawnObjectData({data = chaosbagData}) + spawnObjectData({ data = chaosbagData }) -- remove tokens that are still in play for _, token in pairs(chaosTokens) do @@ -889,7 +627,7 @@ function spawnChaosToken(id) type = 'Custom_Tile', position = { 0.49, 3, 0 }, scale = { 0.81, 1.0, 0.81 }, - rotation = {0, 270, 0}, + rotation = { 0, 270, 0 }, callback_function = function(obj) obj.setName(ID_URL_MAP[id].name) chaosbag.putObject(obj) @@ -939,7 +677,7 @@ function emptyChaosBag() local chaosbag = findChaosBag() for _, object in ipairs(chaosbag.getObjects()) do - chaosbag.takeObject({callback_function = function(item) item.destruct() end}) + chaosbag.takeObject({ callback_function = function(item) item.destruct() end }) end end @@ -955,174 +693,483 @@ end -- Content Importing and XML functions --------------------------------------------------------- -function onClick_refreshList() - local request = WebRequest.get(SOURCE_REPO .. '/library.json', completed_list_update) - requestObj = request - startLuaCoroutine(Global, 'downloadCoroutine') -end - -function onClick_select(player, params) - params = JSON.decode(urldecode(params)) - local url = SOURCE_REPO .. '/' .. params.url - local request = WebRequest.get(url, function (request) complete_obj_download(request, params) end ) - requestObj = request - startLuaCoroutine(Global, 'downloadCoroutine') -end - -function onClick_load() - UI.show('progress_display') - UI.hide('load_button') -end - -function onClick_toggleUi(player, title) - if title == "Navigation Overlay" then - navigationOverlayApi.cycleVisibility(player.color) - return - end - - UI.hide('optionPanel') - UI.hide('load_ui') - - -- when same button is clicked or close window button is pressed, don't open UI - if UI.getValue('title') ~= title and title ~= 'Hidden' then - UI.setValue('title', title) - - if title == "Options" then - UI.show('optionPanel') +-- forwards the requested content type to the update function and sets highlight to clicked tab +---@param tabId String Id of the clicked tab +function onClick_tab(_, _, tabId) + for listId, listContent in pairs(tabIdTable) do + if listId == tabId then + UI.setClass(listId, 'downloadTab activeTab') + contentToShow = listContent else - update_window_content(title) - UI.show('load_ui') + UI.setClass(listId, 'downloadTab') end - else - UI.setValue('title', "Hidden") end + currentListItem = 1 + updateDownloadItemList() +end + +-- click function for the items in the download window +-- updates backgroundcolor for row panel and fontcolor for list item +function onClick_select(_, _, identificationKey) + UI.setAttribute("panel" .. currentListItem, "color", "clear") + UI.setAttribute(contentToShow .. "_" .. currentListItem, "color", "white") + + -- parses the identification key (contentToShow_currentListItem) + if identificationKey then + contentToShow = nil + currentListItem = nil + for str in string.gmatch(identificationKey, "([^_]+)") do + if not contentToShow then + -- grab the first part to know the content type + contentToShow = str + else + -- get the index + currentListItem = tonumber(str) + break + end + end + end + + UI.setAttribute("panel" .. currentListItem, "color", "grey") + UI.setAttribute(contentToShow .. "_" .. currentListItem, "color", "black") + updatePreviewWindow() +end + +-- click function for the download button in the preview window +function onClick_download(player) + local params = library[contentToShow][currentListItem] + params.player = player + placeholder_download(params) +end + +-- the download button on the placeholder objects calls this to directly initiate a download +---@param param Table contains url and guid of replacement object +function placeholder_download(params) + local url = SOURCE_REPO .. '/' .. params.url + requestObj = WebRequest.get(url, function (request) contentDownloadCallback(request, params) end) + startLuaCoroutine(Global, 'downloadCoroutine') end function downloadCoroutine() + -- show progress bar + UI.setAttribute('download_progress', 'active', true) + + -- update progress bar while requestObj do UI.setAttribute('download_progress', 'percentage', requestObj.download_progress * 100) coroutine.yield(0) end + UI.setAttribute('download_progress', 'percentage', 100) + + -- wait 30 frames + for i = 1, 30 do + coroutine.yield(0) + end + + -- hide progress bar + UI.setAttribute('download_progress', 'active', false) + + -- hide download window + if xmlVisibility.downloadWindow then + xmlVisibility.downloadWindow = false + UI.hide('downloadWindow') + end return 1 end -function update_list(objects) - local ui = UI.getXmlTable() - local update_height = find_tag_with_id(ui, 'ui_update_height') - local update_children = find_tag_with_id(update_height.children, 'ui_update_point') +-- spawns a bag that contains every object from the library +function onClick_downloadAll() + broadcastToAll("Download initiated - this will take a few minutes!") - update_children.children = {} + -- hide download window + if xmlVisibility.downloadWindow then + xmlVisibility.downloadWindow = false + UI.hide('downloadWindow') + end - for _, v in ipairs(objects) do - local s = JSON.encode(v); - table.insert(update_children.children, - { tag = 'Text', - value = v.name, - attributes = { onClick = 'onClick_select(' .. urlencode(JSON.encode(v)) .. ')', alignment = 'MiddleLeft' } + startLuaCoroutine(Global, "coroutineDownloadAll") +end + +function coroutineDownloadAll() + local JSON = [[ + { + "Name": "Bag", + "Transform": { + "posX": -39.5, + "posY": 2, + "posZ": -87, + "rotX": 0, + "rotY": 270, + "rotZ": 0, + "scaleX": 1.0, + "scaleY": 1.0, + "scaleZ": 1.0 + }, + "Nickname": "All Downloadable Content", + "Bag": { + "Order": 0 + }, + "ContainedObjects": [ + ]] + + local contained = "" + local downloadedItems = 0 + local skippedItems = 0 + + -- loop through the library to add content + for contentType, objectList in pairs(library) do + broadcastToAll("Downloading " .. contentType .. "...") + for _, params in ipairs(objectList) do + local request = WebRequest.get(SOURCE_REPO .. '/' .. params.url) + local start = os.time() + while true do + if request.is_done then + contained = contained .. request.text .. "," + downloadedItems = downloadedItems + 1 + break + -- time-out if item can't be loaded in 5s + elseif request.is_error or (os.time() - start) > 5 then + skippedItems = skippedItems + 1 + break + end + coroutine.yield(0) + end + end + end + + JSON = JSON .. contained .. "]}" + spawnObjectJSON({json = JSON}) + + broadcastToAll(downloadedItems .. " objects downloaded.", "Green") + broadcastToAll(skippedItems .. " objects had a time-out / error.", "Orange") + return 1 +end + +-- spawns a placeholder box for the selected object +function onClick_spawnPlaceholder() + -- get object references + local item = library[contentToShow][currentListItem] + local dummy = guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlaceholderBoxDummy") + + -- error handling + if not item.boxsize or item.boxsize == "" or not item.boxart or item.boxart == "" then + print("Error loading object.") + return + end + + -- get data for placeholder + local spawnPos = {-39.5, 2, -87} + + local meshTable = { + big = "https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj", + small = "https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj", + wide = "http://pastebin.com/raw.php?i=uWAmuNZ2" + } + + local scaleTable = { + big = {1.00, 0.14, 1.00}, + small = {2.21, 0.46, 2.42}, + wide = {2.00, 0.11, 1.69} + } + + local placeholder = spawnObject({ + type = "Custom_Model", + position = spawnPos, + rotation = {0, 270, 0}, + scale = scaleTable[item.boxsize], + }) + + placeholder.setCustomObject({ + mesh = meshTable[item.boxsize], + diffuse = item.boxart, + material = 3 + }) + + placeholder.setColorTint({1, 1, 1, 71/255}) + placeholder.setName(item.name) + placeholder.setDescription("by " .. (item.author or "Unknown")) + placeholder.setGMNotes(item.url) + placeholder.setLuaScript(dummy.getLuaScript()) + Player.getPlayers()[1].pingTable(spawnPos) + + -- hide download window + if xmlVisibility.downloadWindow then + xmlVisibility.downloadWindow = false + UI.hide('downloadWindow') + end +end + +-- toggles the visibility of the respective UI +---@param player LuaPlayer Player that triggered this +---@param title String Name of the UI to toggle +function onClick_toggleUi(player, title) + if title == "Navigation Overlay" then + navigationOverlayApi.cycleVisibility(player.color) + return + -- hide the playareaGallery if visible + elseif title == "downloadWindow" and xmlVisibility.playareaGallery then + onClick_toggleUi(_, "playareaGallery") + -- hide the downloadWindow if visible + elseif title == "playareaGallery" and xmlVisibility.downloadWindow then + onClick_toggleUi(_, "downloadWindow") + end + + if xmlVisibility[title] then + -- small delay to allow button click sounds to play + Wait.time(function() UI.hide(title) end, 0.1) + else + UI.show(title) + end + xmlVisibility[title] = not xmlVisibility[title] +end + +-- forwards the call to the onClick function +function togglePlayareaGallery() + onClick_toggleUi(_, "playareaGallery") +end + +-- updates the preview window +function updatePreviewWindow() + local item = library[contentToShow][currentListItem] + local tempImage = "http://cloud-3.steamusercontent.com/ugc/2115061845788345842/2CD6ABC551555CCF58F9D0DDB7620197BA398B06/" + + -- set default image if not defined + if item.boxsize == nil or item.boxsize == "" or item.boxart == nil or item.boxart == "" then + item.boxsize = "big" + item.boxart = "http://cloud-3.steamusercontent.com/ugc/762723517667628371/18438B0A0045038A7099648AA3346DFCAA267C66/" + end + + UI.setValue("previewTitle", item.name) + UI.setValue("previewAuthor", "by " .. (item.author or "- Author not found -")) + UI.setValue("previewDescription", item.description or "- Description not found -") + + -- update mask according to size (hardcoded values to align image in mask) + local maskData = {} + if item.boxsize == "big" then + maskData = { + image = "box-cover-mask-big", + width = "870", + height = "435", + offsetXY = "154 60" + } + elseif item.boxsize == "small" then + maskData = { + image = "box-cover-mask-small", + width = "792", + height = "594", + offsetXY = "135 13" + } + elseif item.boxsize == "wide" then + maskData = { + image = "box-cover-mask-wide", + width = "756", + height = "630", + offsetXY = "-190 -70" + } + end + + -- loading empty image as placeholder until real image is loaded + UI.setAttribute("previewArtImage", "image", tempImage) + + -- insert the image itself + UI.setAttribute("previewArtImage", "image", item.boxart) + UI.setAttributes("previewArtMask", maskData) +end + +-- formats the json response from the webrequest into a key-value lua table +-- strips the prefix from the community content items +function formatLibrary(json_response) + library = {} + library["campaigns"] = json_response.campaigns + library["scenarios"] = json_response.scenarios + library["extras"] = json_response.extras + library["fanmadeCampaigns"] = {} + library["fanmadeScenarios"] = {} + library["fanmadePlayerCards"] = {} + + for _, item in ipairs(json_response.community) do + local identifier = nil + for str in string.gmatch(item.name, "([^:]+)") do + if not identifier then + -- grab the first part to know the content type + identifier = str + else + -- update the name without the content type + item.name = str + break + end + end + + if identifier == "Fan Investigators" then + table.insert(library["fanmadePlayerCards"], item) + elseif identifier == "Fan Campaign" then + table.insert(library["fanmadeCampaigns"], item) + elseif identifier == "Fan Scenario" then + table.insert(library["fanmadeScenarios"], item) + end + end +end + +-- updates the window content to the requested content +function updateDownloadItemList() + if not library then return end + + -- addition of list items according to library file + local globalXml = UI.getXmlTable() + local contentList = getXmlTableElementById(globalXml, 'contentList') + + contentList.children = {} + for i, v in ipairs(library[contentToShow]) do + table.insert(contentList.children, + { + tag = "Panel", + attributes = { id = "panel" .. i }, + children = { + tag = 'Text', + value = v.name, + attributes = { + id = contentToShow .. "_" .. i, + onClick = 'onClick_select', + alignment = 'MiddleLeft' + } + } }) end - update_height.attributes.height = #(update_children.children) * 24 - UI.setXmlTable(ui) + contentList.attributes.height = #contentList.children * 27 + UI.setXmlTable(globalXml) + + -- select the first item + Wait.time(onClick_select, 0.2) end -function update_window_content(new_title) - if not library then return end +-- called after the webrequest of downloading an item +-- deletes the placeholder and spawns the downloaded item +function contentDownloadCallback(request, params) + requestObj = nil - if new_title == 'Campaigns' then - update_list(library.campaigns) - elseif new_title == 'Standalone Scenarios' then - update_list(library.scenarios) - elseif new_title == 'Investigators' then - update_list(library.investigators) - elseif new_title == 'Community Content' then - update_list(library.community) - elseif new_title == 'Extras' then - update_list(library.extras) - else - update_list({}) - end -end - -function complete_obj_download(request, params) - assert(request.is_done) + -- error handling if request.is_error or request.response_code ~= 200 then - print('error: ' .. request.error) - else - if pcall(function() - local replaced_object - pcall(function() - if params.replace then - replaced_object = getObjectFromGUID(params.replace) + print('Error: ' .. request.error) + return + end + + -- initiate content spawning + local spawnTable = { json = request.text } + if params.replace then + local replacedObject = getObjectFromGUID(params.replace) + if replacedObject then + spawnTable.position = replacedObject.getPosition() + spawnTable.rotation = replacedObject.getRotation() + spawnTable.scale = replacedObject.getScale() + destroyObject(replacedObject) + end + end + + -- if position is undefined, get empty position + if not spawnTable.position then + spawnTable.rotation = { 0, 270, 0} + + local pos = getValidSpawnPosition() + if pos then + spawnTable.position = pos + else + broadcastToAll("Please make space in the area below the tentacle stand in the upper middle of the table and try again.", "Red") + return + end + end + + -- if spawned from menu, move the camera and/or ping the table + if params.name then + spawnTable["callback_function"] = function(obj) + Wait.time(function() + -- move camera + if params.player then + params.player.lookAt({ + position = obj.getPosition(), + pitch = 65, + yaw = 90, + distance = 65 + }) end - end) - local json = request.text - if replaced_object then - local pos = replaced_object.getPosition() - local rot = replaced_object.getRotation() - destroyObject(replaced_object) - Wait.frames(function() - spawnObjectJSON({json = json, position = pos, rotation = rot}) - end, 1) - else - spawnObjectJSON({json = json}) - end - end) then - print('Object loaded.') - else - print('Error loading object.') + + -- ping object + local pingPlayer = params.player or Player.getPlayers()[1] + pingPlayer.pingTable(obj.getPosition()) + end, 0.1) end end - requestObj = nil - UI.setAttribute('download_progress', 'percentage', 100) -end - --- the download button on the placeholder objects calls this to directly initiate a download --- params is a table with url and guid of replacement object, which happens to match what onClick_select wants -function placeholder_download(params) - onClick_select(nil, JSON.encode(params)) -end - -function completed_list_update(request) - assert(request.is_done) - if request.is_error or request.response_code ~= 200 then - print('error: ' .. request.error) + if pcall(function() spawnObjectJSON(spawnTable) end) then + print('Object loaded.') else - local json_response = nil - if pcall(function () json_response = JSON.decode(request.text) end) then - library = json_response - update_window_content(UI.getValue('title')) - else - print('error parsing downloaded library') - end + print('Error loading object.') end - - requestObj = nil - UI.setAttribute('download_progress', 'percentage', 100) end -function find_tag_with_id(ui, id) - for _, obj in ipairs(ui) do - if obj.attributes and obj.attributes.id and obj.attributes.id == id then return obj end - if obj.children then - local result = find_tag_with_id(obj.children, id) - if result then return result end +-- gets the first empty position to spawn a custom content object safely +function getValidSpawnPosition() + local potentialSpawnPositionX = { 65, 50, 35 } + local potentialSpawnPositionY = 1.5 + local potentialSpawnPositionZ = { 35, 21, 7, -7, -21, -35 } + + for i, posX in ipairs(potentialSpawnPositionX) do + for j, posZ in ipairs(potentialSpawnPositionZ) do + local pos = { + x = posX, + y = potentialSpawnPositionY, + z = posZ, + } + if checkPositionForContentSpawn(pos) then + return pos + end end end return nil end -function urlencode(str) - local str = string.gsub(str, "([^A-Za-z0-9-_.~])", - function (c) return string.format("%%%02X", string.byte(c)) end) - return str +-- checks whether something is in the specified position +-- returns true if empty +function checkPositionForContentSpawn(checkPos) + local search = Physics.cast({ + direction = { 0, 1, 0 }, + max_distance = 0.1, + type = 3, + size = { 0.1, 0.1, 0.1 }, + origin = checkPos + }) + -- first hit is the table surface, additional hits means something is there + return #search == 1 end -function urldecode(str) - local str = string.gsub(str, "%%(%x%x)", - function (h) return string.char(tonumber(h, 16)) end) - return str +-- downloading of the library file +function libraryDownloadCallback(request) + if request.is_error or request.response_code ~= 200 then + print('error: ' .. request.error) + return + end + + local json_response = nil + if pcall(function () json_response = JSON.decode(request.text) end) then + formatLibrary(json_response) + updateDownloadItemList() + else + print('error parsing downloaded library') + end +end + +-- loops through an XML table and returns the specified object +---@param ui Table XmlTable (get this via getXmlTable) +---@param id String Id of the object to return +function getXmlTableElementById(ui, id) + for _, obj in ipairs(ui) do + if obj.attributes and obj.attributes.id and obj.attributes.id == id then return obj end + if obj.children then + local result = getXmlTableElementById(obj.children, id) + if result then return result end + end + end + return nil end --------------------------------------------------------- @@ -1211,7 +1258,8 @@ function applyOptionPanelChange(id, state) optionPanel[id] = state -- update master clue counter - getObjectFromGUID("4a3aa4").setVar("useClickableCounters", state) + local counter = guidReferenceApi.getObjectByOwnerAndType("Mythos", "MasterClueCounter") + counter.setVar("useClickableCounters", state) -- option: Play area snap tags elseif id == "playAreaSnapTags" then @@ -1250,10 +1298,6 @@ function applyOptionPanelChange(id, state) elseif id == "showCYOA" then optionPanel[id] = spawnOrRemoveHelper(state, "CYOA Campaign Guides", {39, 1.3, -20}) - -- option: Show custom playmat images - elseif id == "showCustomPlaymatImages" then - optionPanel[id] = spawnOrRemoveHelper(state, "Custom Playmat Images", {67.5, 1.6, 37}) - -- option: Show displacement tool elseif id == "showDisplacementTool" then optionPanel[id] = spawnOrRemoveHelper(state, "Displacement Tool", {-57, 1.6, 46}) @@ -1280,8 +1324,9 @@ end -- copies the specified tool (by name) from the option panel source bag ---@param name String Name of the object that should be copied ---@param position Table Desired position of the object +---@param rotation Table Desired rotation of the object (defaults to object's rotation) function spawnHelperObject(name, position, rotation) - local sourceBag = getObjectFromGUID("830bd0") + local sourceBag = guidReferenceApi.getObjectByOwnerAndType("Mythos","OptionPanelSource") -- error handling for missing sourceBag if not sourceBag then @@ -1289,7 +1334,7 @@ function spawnHelperObject(name, position, rotation) return end - local spawnTable = {position = position} + local spawnTable = { position = position } -- only overrride rotation if there is one provided (object's rotation used instead) if rotation then @@ -1316,7 +1361,6 @@ function removeHelperObject(name) ["Hand Helper"] = "showHandHelper", ["Search Assistant"] = "showSearchAssistant", ["Displacement Tool"] = "showDisplacementTool", - ["Custom Playmat Images"] = "showCustomPlaymatImages", ["Attachment Helper"] = "showAttachmentHelper", ["CYOA Campaign Guides"] = "showCYOA" } @@ -1363,7 +1407,6 @@ function onClick_defaultSettings() playAreaSnapTags = true, showAttachmentHelper = false, showCleanUpHelper = false, - showCustomPlaymatImages = false, showCYOA = false, showDisplacementTool = false, showDrawButton = false, @@ -1382,7 +1425,6 @@ end -- splash scenario title on setup function titleSplash(scenarioName) if optionPanel['showTitleSplash'] then - -- if there's any ongoing title being displayed, hide it and cancel the waiting function if hideTitleSplashWaitFunctionId then Wait.stop(hideTitleSplashWaitFunctionId) @@ -1422,9 +1464,9 @@ function compareVersion(request) -- global variable to make it accessible for other functions modMeta = JSON.decode(request.text) - -- stop here if on latest version - if MOD_VERSION == modMeta["latestVersion"] then return end - + -- stop here if on latest or newer version + if convertVersionToNumber(MOD_VERSION) >= convertVersionToNumber(modMeta["latestVersion"]) then return end + -- stop here if "don't show again" was clicked for this version before if acknowledgedUpgradeVersions[modMeta["latestVersion"]] then return end @@ -1434,6 +1476,13 @@ function compareVersion(request) Wait.time(function() UI.show("FinnIcon") end, 1) end +-- converts a version number to a string +---@param version String Version number, separated by dots (e.g. 3.3.1) +function convertVersionToNumber(version) + local major, minor, patch = string.match(version, "(%d+)%.(%d+)%.(%d+)") + return major * 100 + minor * 10 + patch +end + -- updates the XML update notification based on the mod metadata function updateNotificationLoading() -- grab data @@ -1446,25 +1495,14 @@ function updateNotificationLoading() highlightText = highlightText .. "\n• " .. entry end end - + -- update the XML UI - UI.setValue("notificationHeader", "New version available: ".. modMeta["latestVersion"]) + UI.setValue("notificationHeader", "New version available: " .. modMeta["latestVersion"]) UI.setValue("releaseHighlightText", highlightText) UI.setAttribute("highlightRow", "preferredHeight", 20*#highlights) UI.setAttribute("updateNotification", "height", 20*#highlights + 125) end --- triggered by clicking on the Finn Icon -function onClick_FinnIcon() - if notificationVisible then - UI.hide("updateNotification") - notificationVisible = false - else - UI.show("updateNotification") - notificationVisible = true - end -end - -- close / don't show again buttons on the update notification function onClick_notification(_, parameter) if parameter == "dontShowAgain" then @@ -1473,17 +1511,177 @@ function onClick_notification(_, parameter) end UI.hide("FinnIcon") UI.hide("updateNotification") + xmlVisibility["updateNotification"] = false +end +end) +__bundle_register("core/NavigationOverlayApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local NavigationOverlayApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getNOHandler() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "NavigationOverlayHandler") + end + + -- Copies the visibility for the Navigation overlay + ---@param startColor String Color of the player to copy from + ---@param targetColor String Color of the targeted player + NavigationOverlayApi.copyVisibility = function(startColor, targetColor) + getNOHandler().call("copyVisibility", { + startColor = startColor, + targetColor = targetColor + }) + end + + -- Changes the Navigation Overlay view ("Full View" --> "Play Areas" --> "Closed" etc.) + ---@param playerColor String Color of the player to update the visibility for + NavigationOverlayApi.cycleVisibility = function(playerColor) + getNOHandler().call("cycleVisibility", playerColor) + end + + return NavigationOverlayApi +end +end) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end + + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") + end + + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) + end + + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) + end + + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) + end + + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi +end +end) +__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local OptionPanelApi = {} + + -- loads saved options + ---@param options Table New options table + OptionPanelApi.loadSettings = function(options) + return Global.call("loadSettings", options) + end + + -- returns option panel table + OptionPanelApi.getOptions = function() + return Global.getTable("optionPanel") + end + + return OptionPanelApi end end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -1508,119 +1706,28 @@ do return TokenArrangerApi end end) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi -end -end) -__bundle_register("core/NavigationOverlayApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local NavigationOverlayApi = {} - local HANDLER_GUID = "797ede" - - -- Copies the visibility for the Navigation overlay - ---@param startColor String Color of the player to copy from - ---@param targetColor String Color of the targeted player - NavigationOverlayApi.copyVisibility = function(startColor, targetColor) - getObjectFromGUID(HANDLER_GUID).call("copyVisibility", { - startColor = startColor, - targetColor = targetColor - }) - end - - -- Changes the Navigation Overlay view ("Full View" --> "Play Areas" --> "Closed" etc.) - ---@param playerColor String Color of the player to update the visibility for - NavigationOverlayApi.cycleVisibility = function(playerColor) - getObjectFromGUID(HANDLER_GUID).call("cycleVisibility", playerColor) - end - - return NavigationOverlayApi -end -end) -__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local TokenSpawnTracker = { } - local SPAWN_TRACKER_GUID = "e3ffc9" - - TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("hasSpawnedTokens", cardGuid) - end - - TokenSpawnTracker.markTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("markTokensSpawned", cardGuid) - end - - TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetTokensSpawned", cardGuid) - end - - TokenSpawnTracker.resetAllAssetAndEvents = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllAssetAndEvents") - end - - TokenSpawnTracker.resetAllLocations = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllLocations") - end - - TokenSpawnTracker.resetAll = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAll") - end - - return TokenSpawnTracker -end -end) __bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local MythosAreaApi = {} - local MYTHOS_AREA_GUID = "9f334f" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end -- returns the chaos token metadata (if provided through scenario reference card) MythosAreaApi.returnTokenData = function() - return getObjectFromGUID(MYTHOS_AREA_GUID).call("returnTokenData") + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") end -- draw an encounter card to the requested position/rotation MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) - getObjectFromGUID(MYTHOS_AREA_GUID).call("drawEncounterCard", { + getMythosArea().call("drawEncounterCard", { pos = pos, rotY = rotY, alwaysFaceUp = alwaysFaceUp @@ -1630,116 +1737,190 @@ do return MythosAreaApi end end) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/SoundCubeApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" + local SoundCubeApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") + -- this table links the name of a trigger effect to its index + local soundIndices = { + ["Vacuum"] = 0, + ["Deep Bell"] = 1, + ["Dark Souls"] = 2 + } + + local function playTriggerEffect(index) + local SoundCube = guidReferenceApi.getObjectByOwnerAndType("Mythos", "SoundCube") + SoundCube.AssetBundle.playTriggerEffect(index) end - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) + -- plays the by name requested sound + ---@param soundName String Name of the sound to play + SoundCubeApi.playSoundByName = function(soundName) + playTriggerEffect(soundIndices[soundName]) end - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) + return SoundCubeApi +end +end) +__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local CHAOS_TOKEN_NAMES = { + ["Elder Sign"] = true, + ["+1"] = true, + ["0"] = true, + ["-1"] = true, + ["-2"] = true, + ["-3"] = true, + ["-4"] = true, + ["-5"] = true, + ["-6"] = true, + ["-7"] = true, + ["-8"] = true, + ["Skull"] = true, + ["Cultist"] = true, + ["Tablet"] = true, + ["Elder Thing"] = true, + ["Auto-fail"] = true, + ["Bless"] = true, + ["Curse"] = true, + ["Frost"] = true + } + + local TokenChecker = {} + + -- returns true if the passed object is a chaos token (by name) + TokenChecker.isChaosToken = function(obj) + if CHAOS_TOKEN_NAMES[obj.getName()] then + return true + else + return false + end end - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) + return TokenChecker +end +end) +__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local TokenSpawnTracker = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getSpawnTracker() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSpawnTracker") end - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) + TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) + return getSpawnTracker().call("hasSpawnedTokens", cardGuid) end - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) + TokenSpawnTracker.markTokensSpawned = function(cardGuid) + return getSpawnTracker().call("markTokensSpawned", cardGuid) end - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") + TokenSpawnTracker.resetTokensSpawned = function(cardGuid) + return getSpawnTracker().call("resetTokensSpawned", cardGuid) end - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) + TokenSpawnTracker.resetAllAssetAndEvents = function() + return getSpawnTracker().call("resetAllAssetAndEvents") end - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) + TokenSpawnTracker.resetAllLocations = function() + return getSpawnTracker().call("resetAllLocations") end - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) + TokenSpawnTracker.resetAll = function() + return getSpawnTracker().call("resetAll") end - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") + return TokenSpawnTracker +end +end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/Global") +end) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") end - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) + return BlessCurseManagerApi +end +end) +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local GUIDReferenceApi = {} + + local function getGuidHandler() + return getObjectFromGUID("123456") end - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) + -- 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 - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image + -- 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 - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) + -- 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 - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi + return GUIDReferenceApi end end) __bundle_register("core/token/TokenManager", function(require, _LOADED, __bundle_register, __bundle_modules) do + local guidReferenceApi = require("core/GUIDReferenceApi") local optionPanelApi = require("core/OptionPanelApi") local playAreaApi = require("core/PlayAreaApi") local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") @@ -1860,15 +2041,10 @@ do ["supply"] = 7 } - -- Source for tokens - local TOKEN_SOURCE_GUID = "124381" - -- Table of data extracted from the token source bag, keyed by the Memo on each token which -- should match the token type keys ("resource", "clue", etc) local tokenTemplates - local DATA_HELPER_GUID = "708279" - local playerCardData local locationData @@ -1966,9 +2142,11 @@ do -- Copy the offsets to make sure we don't change the static values local baseOffsets = offsets offsets = { } + + -- get a vector for the shifting (downwards local to the card) + local shiftDownVector = Vector(0, 0, shiftDown):rotateOver("y", card.getRotation().y) for i, baseOffset in ipairs(baseOffsets) do - offsets[i] = baseOffset - offsets[i][3] = offsets[i][3] + shiftDown + offsets[i] = baseOffset + shiftDownVector end end @@ -2081,8 +2259,8 @@ do if tokenTemplates ~= nil then return end - tokenTemplates = { } - local tokenSource = getObjectFromGUID(TOKEN_SOURCE_GUID) + tokenTemplates = {} + local tokenSource = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSource") for _, tokenTemplate in ipairs(tokenSource.getData().ContainedObjects) do local tokenName = tokenTemplate.Memo tokenTemplates[tokenName] = tokenTemplate @@ -2094,7 +2272,7 @@ do if playerCardData ~= nil then return end - local dataHelper = getObjectFromGUID(DATA_HELPER_GUID) + local dataHelper = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") playerCardData = dataHelper.getTable('PLAYER_CARD_DATA') locationData = dataHelper.getTable('LOCATIONS_DATA') end @@ -2109,18 +2287,16 @@ do if uses == nil then return end -- go through tokens to spawn - local type, token, tokenCount + local tokenCount for i, useInfo in ipairs(uses) do - type = useInfo.type - token = useInfo.token - tokenCount = (useInfo.count or 0) - + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() - if extraUses ~= nil and extraUses[type] ~= nil then - tokenCount = tokenCount + extraUses[type] + tokenCount = (useInfo.count or 0) + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() + if extraUses ~= nil and extraUses[useInfo.type] ~= nil then + tokenCount = tokenCount + extraUses[useInfo.type] end -- Shift each spawned group after the first down so they don't pile on each other - TokenManager.spawnTokenGroup(card, token, tokenCount, (i - 1) * 0.8, type) + TokenManager.spawnTokenGroup(card, useInfo.token, tokenCount, (i - 1) * 0.8, useInfo.type) end + tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -2144,9 +2320,8 @@ do ---@param playerData Table Player card data structure retrieved from the DataHelper. Should be -- the right data for this card. internal.spawnPlayerCardTokensFromDataHelper = function(card, playerData) - token = playerData.tokenType - tokenCount = playerData.tokenCount - --log("Spawning data helper tokens for "..card.getName()..'['..card.getDescription()..']: '..tokenCount.."x "..token) + local token = playerData.tokenType + local tokenCount = playerData.tokenCount TokenManager.spawnTokenGroup(card, token, tokenCount) tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -2179,7 +2354,6 @@ do return 0 end - --log(card.getName() .. ' : ' .. locationData.type .. ' : ' .. locationData.value .. ' : ' .. locationData.clueSide) if ((card.is_face_down and locationData.clueSide == 'back') or (not card.is_face_down and locationData.clueSide == 'front')) then if locationData.type == 'fixed' then @@ -2289,22 +2463,235 @@ do return TokenManager end end) -__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local OptionPanelApi = {} + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - -- loads saved options - ---@param options Table New options table - OptionPanelApi.loadSettings = function(options) - return Global.call("loadSettings", options) + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end end - -- returns option panel table - OptionPanelApi.getOptions = function() - return Global.getTable("optionPanel") + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result end - return OptionPanelApi + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi end end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked.xml b/unpacked.xml index 0a7585f6b..9d7a8fa8e 100644 --- a/unpacked.xml +++ b/unpacked.xml @@ -1,50 +1,36 @@ - - + - + - - - - - - - - + + + Downloadable Content + + + + + + + + + + + + + + + + + + + + + + + + PreviewTitle + by PreviewAuthor + + + + + + + + + + + + + PreviewDescription + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + @@ -310,8 +533,8 @@ - - + + + preferredHeight="50" + tooltipPosition="Left" + tooltipBackgroundColor="rgba(0,0,0,1)"/> @@ -364,14 +589,13 @@ - + - + + onClick="onClick_toggleUi(optionPanel)">Close - - + + @@ -689,10 +901,11 @@ offsetXY="420 -5" height="90" width="90" - onClick="onClick_FinnIcon" + onClick="onClick_toggleUi(updateNotification)" image="FinnIcon" tooltip="Update notification" - tooltipBackgroundColor="rgba(0,0,0,0.8)"/> + tooltipPosition="Right" + tooltipBackgroundColor="rgba(0,0,0,1)"/> - - \ No newline at end of file + + \ No newline at end of file diff --git a/unpacked.yaml b/unpacked.yaml index 7ae073477..c867d62c5 100644 --- a/unpacked.yaml +++ b/unpacked.yaml @@ -1,30 +1,44 @@ CameraStates: - AbsolutePosition: - x: -67.59604 - y: 91.87675 - z: 5.521103 - Distance: 104.699272 + x: -67.6 + y: 91.88 + z: 5.52 + Distance: 104 Position: - x: -22.2649822 + x: -22.26 y: -2.5 - z: 5.25747156 + z: 5.26 Rotation: - x: 64.34372 - y: 90.3332 + x: 64.34 + y: 90.33 z: 0 Zoomed: false - AbsolutePosition: - x: -47.7179832 - y: 86.18371 - z: -6.780735e-06 - Distance: 97.85165 + x: -39.1 + y: 29.7 + z: 0 + Distance: 29.14 Position: - x: -6.36408234 - y: -2.5 - z: -9.483223e-07 + x: -31.54 + y: 1.55 + z: 0 Rotation: - x: 64.99999 - y: 89.99999 + x: 75 + y: 90 + z: 0 + Zoomed: false +- AbsolutePosition: + x: -10.16 + y: 18.95 + z: 0 + Distance: 18 + Position: + x: -5.5 + y: 1.55 + z: 0 + Rotation: + x: 75 + y: 90 z: 0 Zoomed: false ComponentTags: @@ -35,8 +49,6 @@ ComponentTags: normalized: allcardshotfix - displayed: LinkedPhaseTracker normalized: linkedphasetracker - - displayed: chaosBag - normalized: chaosBag - displayed: displacement_excluded normalized: displacement_excluded - displayed: PlayerCard @@ -59,20 +71,14 @@ ComponentTags: normalized: investigator - displayed: chaosBag normalized: chaosbag - - displayed: arkham_setup_memory_object - normalized: arkham_setup_memory_object - displayed: ActionToken normalized: actiontoken - displayed: LargeBox normalized: largebox - - displayed: SoundCube - normalized: soundcube - displayed: CampaignBox normalized: campaignbox - displayed: CameraZoom_ignore normalized: camerazoom_ignore - - displayed: TokenArranger - normalized: tokenarranger CustomUIAssets: - Name: refresh Type: 0 @@ -206,7 +212,16 @@ CustomUIAssets: - Name: FinnIcon Type: 0 URL: http://cloud-3.steamusercontent.com/ugc/2037357792052848566/5DA900C430E97D3DFF2C9B8A3DB1CB2271791FC7/ -Date: Mon Oct 9 14:03:26 CDT 2023 +- Name: box-cover-mask-small + Type: 0 + URL: http://cloud-3.steamusercontent.com/ugc/2115061298536631564/F29C2ED9DD8431A1D1E21C7FFAFF1FFBC0AF0BF3/ +- Name: box-cover-mask-big + Type: 0 + URL: http://cloud-3.steamusercontent.com/ugc/2115061298536631429/D075D2EECE6EE091AD3BEA5800DEF9C7B02B745B/ +- Name: box-cover-mask-wide + Type: 0 + URL: http://cloud-3.steamusercontent.com/ugc/2115061298538827369/A20C2ECB8ECDC1B0AD8B2B38F68CA1C1F5E07D37/ +Date: Sat Nov 18 18:06:45 CST 2023 DecalPallet: - ImageURL: http://cloud-3.steamusercontent.com/ugc/1474319121424323663/BC5570ECF747F1B30224461B576E8B0FE7FA5F33/ Name: Achivement Checkmark @@ -215,7 +230,7 @@ DecalPallet: Name: Victory Display Size: 15 Decals: [] -EpochTime: 1696878206 +EpochTime: 1700352405 GameComplexity: '' GameMode: Arkham Horror LCG - Super Complete Edition GameType: '' @@ -266,7 +281,7 @@ Lighting: LutIndex: 0 ReflectionIntensity: 1 LuaScript: !include 'unpacked.ttslua' -LuaScriptState: '{"acknowledgedUpgradeVersions":[],"optionPanel":{"cardLanguage":"en","playAreaSnapTags":true,"showAttachmentHelper":false,"showCleanUpHelper":false,"showCustomPlaymatImages":false,"showCYOA":false,"showDisplacementTool":false,"showDrawButton":false,"showHandHelper":[],"showSearchAssistant":[],"showTitleSplash":true,"useClueClickers":false,"useResourceCounters":"disabled","useSnapTags":true}}' +LuaScriptState: '{"acknowledgedUpgradeVersions":[],"optionPanel":{"cardLanguage":"en","playAreaSnapTags":true,"showAttachmentHelper":false,"showCleanUpHelper":false,"showCYOA":false,"showDisplacementTool":false,"showDrawButton":false,"showHandHelper":[],"showSearchAssistant":[],"showTitleSplash":true,"useClueClickers":false,"useResourceCounters":"disabled","useSnapTags":true}}' MusicPlayer: AudioLibrary: - Item1: http://cloud-3.steamusercontent.com/ugc/784110538847453001/4481D1CC5684FCF04AB143954DEFE09E94BF5CEB/ @@ -323,6 +338,7 @@ MusicPlayer: RepeatSong: false Note: '' ObjectStates: +- !include 'unpacked/go_game_piece_white GUID Reference Handler 123456.yaml' - !include 'unpacked/HandTrigger 5fe087.yaml' - !include 'unpacked/HandTrigger be2f17.yaml' - !include 'unpacked/HandTrigger 0285cc.yaml' @@ -405,12 +421,11 @@ ObjectStates: - !include 'unpacked/Custom_Model Clue Counter d86b7c.yaml' - !include 'unpacked/Custom_Token Master Clue Counter 4a3aa4.yaml' - !include 'unpacked/Custom_Model_Bag Legacy Assets 7165a9.yaml' -- !include 'unpacked/Custom_Token Playarea 721ba2.yaml' +- !include 'unpacked/Custom_Token Play Area 721ba2.yaml' - !include 'unpacked/Custom_Assetbundle_Bag Barkham Horror 308439.yaml' - !include 'unpacked/Custom_Token Chaos Bag Stat Tracker 766620.yaml' - !include 'unpacked/Custom_Model_Bag Bless tokens afa06b.yaml' - !include 'unpacked/Custom_Model_Bag Curse tokens bd0253.yaml' -- !include 'unpacked/Custom_Tile Token Remover 0a5a29.yaml' - !include 'unpacked/Checker_white Token Spawn Tool 36b4ee.yaml' - !include 'unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8.yaml' - !include 'unpacked/Deck Tarot Deck 77f1e5.yaml' @@ -430,16 +445,15 @@ ObjectStates: - !include 'unpacked/Custom_Tile Data Helper 708279.yaml' - !include 'unpacked/Custom_Token BlessCurse Manager 5933fb.yaml' - !include 'unpacked/Notecard d8d357.yaml' -- !include 'unpacked/Checker_black Arkham Deck Cutter 445115.yaml' - !include 'unpacked/ScriptingTrigger a2f932.yaml' - !include 'unpacked/Custom_Model Edge of the Earth 895eaa.yaml' - !include 'unpacked/Custom_Model The Dream-Eaters a16a1a.yaml' - !include 'unpacked/Custom_Model Return to The Circle Undone 757324.yaml' -- !include 'unpacked/Custom_Tile Playermat 4 Red 0840d5.yaml' -- !include 'unpacked/Custom_Tile Playermat 3 Green 383d8b.yaml' - !include 'unpacked/Custom_Token Other Doom in Play 652ff3.yaml' - !include 'unpacked/Custom_Tile Playermat 1 White 8b081b.yaml' - !include 'unpacked/Custom_Tile Playermat 2 Orange bd0ff4.yaml' +- !include 'unpacked/Custom_Tile Playermat 3 Green 383d8b.yaml' +- !include 'unpacked/Custom_Tile Playermat 4 Red 0840d5.yaml' - !include 'unpacked/Custom_Tile Neutral 2691e1.yaml' - !include 'unpacked/Custom_Tile Neutral 748245.yaml' - !include 'unpacked/Custom_Tile Neutral 271b17.yaml' @@ -480,15 +494,17 @@ ObjectStates: - !include 'unpacked/Custom_Tile Player Cards 2d30ee.yaml' - !include 'unpacked/Custom_Tile Token Remover 39b175.yaml' - !include 'unpacked/Custom_Tile Token Remover 2ba7a5.yaml' +- !include 'unpacked/Custom_Tile Token Remover 0a5a29.yaml' +- !include 'unpacked/ScriptingTrigger TokenDiscardZone 457de3.yaml' +- !include 'unpacked/ScriptingTrigger TokenDiscardZone 457de4.yaml' +- !include 'unpacked/ScriptingTrigger TokenDiscardZone 457de5.yaml' +- !include 'unpacked/ScriptingTrigger TokenDiscardZone 457de6.yaml' - !include 'unpacked/Custom_Tile Decoration - Map 6161b4.yaml' - !include 'unpacked/Custom_Model_Bag Rulebooks, Guides and Tablets fcfa7f.yaml' - !include 'unpacked/BlockRectangle Table Divider 612072.yaml' - !include 'unpacked/BlockRectangle Table Divider 975c39.yaml' - !include 'unpacked/BlockRectangle Table Divider 75937e.yaml' - !include 'unpacked/BlockRectangle Table Divider 8646eb.yaml' -- !include 'unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators - ed4ca7.yaml' -- !include 'unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c.yaml' - !include 'unpacked/Custom_Model Decoration - Ammo 0a3b03.yaml' - !include 'unpacked/Custom_Model Decoration - Ammo b43845.yaml' - !include 'unpacked/Custom_Model Decoration - Ammo d35ee9.yaml' @@ -497,13 +513,15 @@ ObjectStates: - !include 'unpacked/Bag OptionPanel Source 830bd0.yaml' - !include 'unpacked/Custom_Assetbundle SoundCube 3c988f.yaml' - !include 'unpacked/go_game_piece_white Game Key Handler fce69c.yaml' +- !include 'unpacked/Custom_Tile Token Spawning Reference f8b3a7.yaml' - !include 'unpacked/3DText d628cc.yaml' - !include 'unpacked/go_game_piece_black Navigation Overlay Handler 797ede.yaml' - !include 'unpacked/Custom_Tile Campaign ImporterExporter 334ee3.yaml' - !include 'unpacked/Custom_Token Token Arranger 022907.yaml' - !include 'unpacked/Custom_Token Chaos Bag Manager 023240.yaml' -- !include 'unpacked/Notecard Arkham SCE 3.3.0 - 1092023 - Page 1 964222.yaml' -- !include 'unpacked/Custom_Model Souls of Darkness a94e6b.yaml' +- !include 'unpacked/BlockRectangle Placeholder Box Dummy a93466.yaml' +- !include 'unpacked/Custom_Model Baldur''s Gate III 695abd.yaml' +- !include 'unpacked/Notecard Arkham SCE 3.4.0 - 11182023 - Page 1 964222.yaml' PlayArea: 1 PlayerCounts: - 0 @@ -511,7 +529,7 @@ PlayerCounts: PlayingTime: - 0 - 0 -SaveName: Arkham SCE - 3.3.0 +SaveName: Arkham SCE - 3.4.0 Sky: Sky_Museum SkyURL: https://i.imgur.com/GkQqaOF.jpg SnapPoints: diff --git a/unpacked/3DText d628cc.yaml b/unpacked/3DText d628cc.yaml index 7baa8f239..37b7a7a2a 100644 --- a/unpacked/3DText d628cc.yaml +++ b/unpacked/3DText d628cc.yaml @@ -36,7 +36,7 @@ Tooltip: true Transform: posX: -19.5 posY: 1.7 - posZ: -84 + posZ: -87 rotX: 90 rotY: 90 rotZ: 0 diff --git a/unpacked/Bag All Player Cards 15bb07.ttslua b/unpacked/Bag All Player Cards 15bb07.ttslua index a7d10a90a..5964e108c 100644 --- a/unpacked/Bag All Player Cards 15bb07.ttslua +++ b/unpacked/Bag All Player Cards 15bb07.ttslua @@ -41,9 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/AllCardsBag") -end) __bundle_register("playercards/AllCardsBag", function(require, _LOADED, __bundle_register, __bundle_modules) local cardIdIndex = { } local classAndLevelIndex = { } @@ -400,4 +397,7 @@ function isBasicWeakness(cardMetadata) and cardMetadata.basicWeaknessCount > 0 end end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/AllCardsBag") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07.yaml b/unpacked/Bag All Player Cards 15bb07.yaml index cbdb60a06..a69ae36a7 100644 --- a/unpacked/Bag All Player Cards 15bb07.yaml +++ b/unpacked/Bag All Player Cards 15bb07.yaml @@ -21,11 +21,17 @@ ContainedObjects: - !include 'Bag All Player Cards 15bb07/Card Monterey Jack 46b145.yaml' - !include 'Bag All Player Cards 15bb07/Card If it bleeds... acf2b0.yaml' - !include 'Bag All Player Cards 15bb07/Card Beat Cop (2) 7001be.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Ad Hoc c9fb2f.yaml' +- !include 'Bag All Player Cards 15bb07/Card Hasty Repairs 0821d5.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Wilson Richards ceb426.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Wilson Richards 54eab5.yaml' - !include 'Bag All Player Cards 15bb07/Card Hard Times 876557.yaml' - !include 'Bag All Player Cards 15bb07/Card Pete''s Guitar 876557.yaml' - !include 'Bag All Player Cards 15bb07/Card Ashcan Pete (Parallel Front) 5294c3.yaml' - !include 'Bag All Player Cards 15bb07/Card Ashcan Pete (Parallel Back) 5294c3.yaml' - !include 'Bag All Player Cards 15bb07/Card Ashcan Pete (Parallel) 5294c3.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Eldritch Tongue e8765a.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom False Surrender adf28e.yaml' - !include 'Bag All Player Cards 15bb07/CardCustom The Necronomicon 5b2e10.yaml' - !include 'Bag All Player Cards 15bb07/Card Roland''s .38 Special 4edb91.yaml' - !include 'Bag All Player Cards 15bb07/Card Stubborn Detective 4ea68b.yaml' @@ -140,6 +146,7 @@ ContainedObjects: - !include 'Bag All Player Cards 15bb07/Card Accursed Fate 85e7d9.yaml' - !include 'Bag All Player Cards 15bb07/Card On Your Own (3) 2ebdf1.yaml' - !include 'Bag All Player Cards 15bb07/Card Zoey''s Cross 66d810.yaml' +- !include 'Bag All Player Cards 15bb07/Card Zoey''s Cross 66d811.yaml' - !include 'Bag All Player Cards 15bb07/Card Dig Deep (4) 734b45.yaml' - !include 'Bag All Player Cards 15bb07/Card Dream-Enhancing Serum 98c5af.yaml' - !include 'Bag All Player Cards 15bb07/Card The Gold Pocket Watch (4) 62d930.yaml' @@ -380,6 +387,7 @@ ContainedObjects: - !include 'Bag All Player Cards 15bb07/Card Streetwise (3) d7dbac.yaml' - !include 'Bag All Player Cards 15bb07/Card Try and Try Again (1) 3dc82f.yaml' - !include 'Bag All Player Cards 15bb07/Card Smite the Wicked 58f534.yaml' +- !include 'Bag All Player Cards 15bb07/Card Smite the Wicked 58f535.yaml' - !include 'Bag All Player Cards 15bb07/Card Gravedigger''s Shovel (2) 96a440.yaml' - !include 'Bag All Player Cards 15bb07/Card Fine Print 39452d.yaml' - !include 'Bag All Player Cards 15bb07/Card Voice of Ra 0988b2.yaml' @@ -740,6 +748,7 @@ ContainedObjects: - !include 'Bag All Player Cards 15bb07/Card Waveworn Idol 591284.yaml' - !include 'Bag All Player Cards 15bb07/Card Take Heart cc6e4d.yaml' - !include 'Bag All Player Cards 15bb07/Card Olive McBride 9683d0.yaml' +- !include 'Bag All Player Cards 15bb07/Card Olive McBride 9683d2.yaml' - !include 'Bag All Player Cards 15bb07/Card Counterpunch 20645e.yaml' - !include 'Bag All Player Cards 15bb07/Card Harmony Restored (2) 7885cf.yaml' - !include 'Bag All Player Cards 15bb07/Card Glory 273584.yaml' @@ -1105,6 +1114,9 @@ ContainedObjects: - !include 'Bag All Player Cards 15bb07/Card Preston Fairmont 5e6298.yaml' - !include 'Bag All Player Cards 15bb07/Card Diana Stanley 32b091.yaml' - !include 'Bag All Player Cards 15bb07/Card Zoey Samaras 98a0e1.yaml' +- !include 'Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel) 98a0e2.yaml' +- !include 'Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel Back) 98a0e4.yaml' +- !include 'Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel Front) 98a0e3.yaml' - !include 'Bag All Player Cards 15bb07/Card Jim Culver ca079b.yaml' - !include 'Bag All Player Cards 15bb07/Card Joe Diamond 6dc626.yaml' - !include 'Bag All Player Cards 15bb07/Card Agnes Baker (Parallel Back) 909f30.yaml' @@ -1562,6 +1574,27 @@ ContainedObjects: - !include 'Bag All Player Cards 15bb07/Card Wrong Place, Right Time d5944e.yaml' - !include 'Bag All Player Cards 15bb07/Card Sparrow Mask 975d79.yaml' - !include 'Bag All Player Cards 15bb07/Card Pitchfork 45a724.yaml' +- !include 'Bag All Player Cards 15bb07/Card Jim''s Trumpet 7dfd5f.yaml' +- !include 'Bag All Player Cards 15bb07/Card Jim Culver (Parallel) 72bf31.yaml' +- !include 'Bag All Player Cards 15bb07/Card Jim Culver (Parallel Front) c5fc80.yaml' +- !include 'Bag All Player Cards 15bb07/Card Vengeful Shade 73bc8e.yaml' +- !include 'Bag All Player Cards 15bb07/Card Final Rhapsody 561775.yaml' +- !include 'Bag All Player Cards 15bb07/Card Jim Culver (Parallel Back) aba863.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom The Beyond 37ab47.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Devil 2a0ba5.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Alessandra Zorzi cea425.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Alessandra Zorzi 54eaa5.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Zamacona 541ba9.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Wicked Athame c9fb1f.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Beguile 019526.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Ofuda 860c1e.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom I''ll Pay You Back! 40e1ca.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Occult Reliquary acd0c2.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Grift df75d7.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Control Variable 133868.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Blackmail File de456d.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Speak to the Dead c763aa.yaml' +- !include 'Bag All Player Cards 15bb07/CardCustom Accursed e91c5e.yaml' Description: '' DragSelectable: true GMNotes: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card .35 Winchester (Taboo) 22d821.yaml b/unpacked/Bag All Player Cards 15bb07/Card .35 Winchester (Taboo) 22d821.yaml index 3900d4c7d..87246b011 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card .35 Winchester (Taboo) 22d821.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card .35 Winchester (Taboo) 22d821.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card A Watchful Peace (3) (Taboo) 25b73a.yaml b/unpacked/Bag All Player Cards 15bb07/Card A Watchful Peace (3) (Taboo) 25b73a.yaml index 9b0e1bf2c..908ede546 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card A Watchful Peace (3) (Taboo) 25b73a.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card A Watchful Peace (3) (Taboo) 25b73a.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Ace in the Hole (3) (Taboo) e92f21.yaml b/unpacked/Bag All Player Cards 15bb07/Card Ace in the Hole (3) (Taboo) e92f21.yaml index fdfeff8d0..f8ed60134 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Ace in the Hole (3) (Taboo) e92f21.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Ace in the Hole (3) (Taboo) e92f21.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card All In (5) (Taboo) 5db655.yaml b/unpacked/Bag All Player Cards 15bb07/Card All In (5) (Taboo) 5db655.yaml index f3cca92c4..b7d406d2c 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card All In (5) (Taboo) 5db655.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card All In (5) (Taboo) 5db655.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Ancient Covenant (2) (Taboo) e01cc7.yaml b/unpacked/Bag All Player Cards 15bb07/Card Ancient Covenant (2) (Taboo) e01cc7.yaml index 8d373ad21..493ef5d8a 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Ancient Covenant (2) (Taboo) e01cc7.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Ancient Covenant (2) (Taboo) e01cc7.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Banish (1) (Taboo) 1a3b10.yaml b/unpacked/Bag All Player Cards 15bb07/Card Banish (1) (Taboo) 1a3b10.yaml index 68c926ec2..adaae15b5 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Banish (1) (Taboo) 1a3b10.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Banish (1) (Taboo) 1a3b10.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Black Market (2) (Taboo) 4d085b.yaml b/unpacked/Bag All Player Cards 15bb07/Card Black Market (2) (Taboo) 4d085b.yaml index ad0ac38da..9ee8a2e79 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Black Market (2) (Taboo) 4d085b.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Black Market (2) (Taboo) 4d085b.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Burn After Reading (1) (Taboo) 2ced40.yaml b/unpacked/Bag All Player Cards 15bb07/Card Burn After Reading (1) (Taboo) 2ced40.yaml index 42da2088e..3e9490cea 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Burn After Reading (1) (Taboo) 2ced40.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Burn After Reading (1) (Taboo) 2ced40.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Counterspell (2) (Taboo) 9c9177.yaml b/unpacked/Bag All Player Cards 15bb07/Card Counterspell (2) (Taboo) 9c9177.yaml index 50d2b53ca..7b7272ded 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Counterspell (2) (Taboo) 9c9177.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Counterspell (2) (Taboo) 9c9177.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Crisis of Identity (Taboo) 17cab7.yaml b/unpacked/Bag All Player Cards 15bb07/Card Crisis of Identity (Taboo) 17cab7.yaml index 3e7bfb1d2..1414d0b11 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Crisis of Identity (Taboo) 17cab7.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Crisis of Identity (Taboo) 17cab7.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Crystalline Elder Sign (3) 949ca2.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Crystalline Elder Sign (3) 949ca2.ttslua index 9fa2e62e8..27433a4df 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Crystalline Elder Sign (3) 949ca2.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Crystalline Elder Sign (3) 949ca2.ttslua @@ -280,12 +280,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -313,11 +314,15 @@ end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -325,30 +330,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -430,6 +435,36 @@ do 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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/CrystallineElderSign3") end) diff --git a/unpacked/Bag All Player Cards 15bb07/Card Cyclopean Hammer (5) (Taboo) 42336b.yaml b/unpacked/Bag All Player Cards 15bb07/Card Cyclopean Hammer (5) (Taboo) 42336b.yaml index 96d505d3c..e60798559 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Cyclopean Hammer (5) (Taboo) 42336b.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Cyclopean Hammer (5) (Taboo) 42336b.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Daredevil (Taboo) cd1e54.yaml b/unpacked/Bag All Player Cards 15bb07/Card Daredevil (Taboo) cd1e54.yaml index 4e0ee784d..013ba727f 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Daredevil (Taboo) cd1e54.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Daredevil (Taboo) cd1e54.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Dark Prophecy (Taboo) 448db7.yaml b/unpacked/Bag All Player Cards 15bb07/Card Dark Prophecy (Taboo) 448db7.yaml index 4a9e7107e..cffab9773 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Dark Prophecy (Taboo) 448db7.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Dark Prophecy (Taboo) 448db7.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Dark Ritual 272e6c.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Dark Ritual 272e6c.ttslua index 421a0049a..dda4e6ff6 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Dark Ritual 272e6c.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Dark Ritual 272e6c.ttslua @@ -41,50 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi -end -end) __bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local ChaosBagApi = {} @@ -161,6 +117,36 @@ do 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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/DarkRitual") end) @@ -404,12 +390,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -434,4 +421,52 @@ do return TokenArrangerApi end end) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +end +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card David Renfield (Taboo) 4c7c54.yaml b/unpacked/Bag All Player Cards 15bb07/Card David Renfield (Taboo) 4c7c54.yaml index 30aaa1e57..adf236f63 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card David Renfield (Taboo) 4c7c54.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card David Renfield (Taboo) 4c7c54.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Day of Reckoning e701af.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Day of Reckoning e701af.ttslua index 868b22929..821bb672e 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Day of Reckoning e701af.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Day of Reckoning e701af.ttslua @@ -41,16 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/cards/DayofReckoning") -end) -__bundle_register("playercards/cards/DayofReckoning", function(require, _LOADED, __bundle_register, __bundle_modules) -VALID_TOKENS = { - ["Elder Sign"] = true -} - -require("playercards/CardsThatSealTokens") -end) __bundle_register("playercards/CardsThatSealTokens", function(require, _LOADED, __bundle_register, __bundle_modules) --[[ Library for cards that seal tokens This file is used to add sealing option to cards' context menu. @@ -282,12 +272,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -315,11 +306,15 @@ end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -327,30 +322,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -432,4 +427,44 @@ do 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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/cards/DayofReckoning") +end) +__bundle_register("playercards/cards/DayofReckoning", function(require, _LOADED, __bundle_register, __bundle_modules) +VALID_TOKENS = { + ["Elder Sign"] = true +} + +require("playercards/CardsThatSealTokens") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Deck of Possibilities fefdfa.yaml b/unpacked/Bag All Player Cards 15bb07/Card Deck of Possibilities fefdfa.yaml index dc68a8a5a..a71634382 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Deck of Possibilities fefdfa.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Deck of Possibilities fefdfa.yaml @@ -12,7 +12,7 @@ CustomDeck: '2664': BackIsHidden: true BackURL: http://cloud-3.steamusercontent.com/ugc/1874087305860121579/39578AC78E34DAA169AB4DE4246BB1E002528B8C/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/1874087305860119704/FCC908E5C313759E9E478D5952C74179DF80ADA8/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2021605474902965618/1DA915D6106D951592457701CBA262B73CBEDE6B/ NumHeight: 5 NumWidth: 7 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Delve Too Deep (Taboo) ca5603.yaml b/unpacked/Bag All Player Cards 15bb07/Card Delve Too Deep (Taboo) ca5603.yaml index 48942946c..b05c094c1 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Delve Too Deep (Taboo) ca5603.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Delve Too Deep (Taboo) ca5603.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Double or Nothing (Taboo) 9aa0de.yaml b/unpacked/Bag All Player Cards 15bb07/Card Double or Nothing (Taboo) 9aa0de.yaml index a19a048ae..1a657a0ba 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Double or Nothing (Taboo) 9aa0de.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Double or Nothing (Taboo) 9aa0de.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Dr. Milan Christopher (Taboo) 2a6fd1.yaml b/unpacked/Bag All Player Cards 15bb07/Card Dr. Milan Christopher (Taboo) 2a6fd1.yaml index 2f798d737..660e2bfd3 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Dr. Milan Christopher (Taboo) 2a6fd1.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Dr. Milan Christopher (Taboo) 2a6fd1.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Drawing Thin (Taboo) 49361a.yaml b/unpacked/Bag All Player Cards 15bb07/Card Drawing Thin (Taboo) 49361a.yaml index 87cd6bba0..76a1ad093 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Drawing Thin (Taboo) 49361a.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Drawing Thin (Taboo) 49361a.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Elusive (Taboo) 3c046a.yaml b/unpacked/Bag All Player Cards 15bb07/Card Elusive (Taboo) 3c046a.yaml index a5cefa489..ba5889ad3 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Elusive (Taboo) 3c046a.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Elusive (Taboo) 3c046a.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Emergency Cache (3) 408cb5.yaml b/unpacked/Bag All Player Cards 15bb07/Card Emergency Cache (3) 408cb5.yaml index 219bc7e2b..b6dbc4c5b 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Emergency Cache (3) 408cb5.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Emergency Cache (3) 408cb5.yaml @@ -19,9 +19,10 @@ CustomDeck: UniqueBack: false Description: '' DragSelectable: true -GMNotes: "{\r\n \"id\": \"03239\",\r\n \"type\": \"Event\",\r\n \"class\": \"Neutral\",\r\n - \ \"cost\": 0,\r\n \"level\": 3,\r\n \"traits\": \"Supply.\",\r\n \"cycle\": - \"The Path to Carcosa\"\r\n}\r" +GMNotes: "{\n \"id\": \"03239\",\n \"type\": \"Event\",\n \"class\": \"Neutral\",\n + \ \"cost\": 0,\n \"level\": 3,\n \"traits\": \"Supply.\",\n \"uses\": [\n {\n + \ \"count\": 4,\n \"type\": \"Supply\",\n \"token\": \"resource\"\n + \ }\n ],\n \"cycle\": \"The Path to Carcosa\"\n}" GUID: 408cb5 Grid: true GridProjection: false diff --git a/unpacked/Bag All Player Cards 15bb07/Card Eon Chart (1) (Taboo) 389610.yaml b/unpacked/Bag All Player Cards 15bb07/Card Eon Chart (1) (Taboo) 389610.yaml index 868fe98fa..9b5670fa9 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Eon Chart (1) (Taboo) 389610.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Eon Chart (1) (Taboo) 389610.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Eon Chart (4) (Taboo) 41c449.yaml b/unpacked/Bag All Player Cards 15bb07/Card Eon Chart (4) (Taboo) 41c449.yaml index f53ec7cbc..79c6a6287 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Eon Chart (4) (Taboo) 41c449.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Eon Chart (4) (Taboo) 41c449.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Eucatastrophe (3) (Taboo) 8be540.yaml b/unpacked/Bag All Player Cards 15bb07/Card Eucatastrophe (3) (Taboo) 8be540.yaml index 4c7045319..a19281cd5 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Eucatastrophe (3) (Taboo) 8be540.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Eucatastrophe (3) (Taboo) 8be540.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Family Inheritance 394603.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Family Inheritance 394603.ttslua index e54e729ad..06784874e 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Family Inheritance 394603.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Family Inheritance 394603.ttslua @@ -41,12 +41,208 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__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) +__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local OptionPanelApi = {} + + -- loads saved options + ---@param options Table New options table + OptionPanelApi.loadSettings = function(options) + return Global.call("loadSettings", options) + end + + -- returns option panel table + OptionPanelApi.getOptions = function() + return Global.getTable("optionPanel") + end + + return OptionPanelApi +end +end) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end + + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") + end + + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) + end + + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) + end + + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) + end + + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi +end +end) +__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local TokenSpawnTracker = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getSpawnTracker() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSpawnTracker") + end + + TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) + return getSpawnTracker().call("hasSpawnedTokens", cardGuid) + end + + TokenSpawnTracker.markTokensSpawned = function(cardGuid) + return getSpawnTracker().call("markTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetTokensSpawned = function(cardGuid) + return getSpawnTracker().call("resetTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetAllAssetAndEvents = function() + return getSpawnTracker().call("resetAllAssetAndEvents") + end + + TokenSpawnTracker.resetAllLocations = function() + return getSpawnTracker().call("resetAllLocations") + end + + TokenSpawnTracker.resetAll = function() + return getSpawnTracker().call("resetAll") + end + + return TokenSpawnTracker +end +end) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/FamilyInheritance") end) __bundle_register("playercards/cards/FamilyInheritance", function(require, _LOADED, __bundle_register, __bundle_modules) -local tokenManager = require("core/token/TokenManager") local playmatApi = require("playermat/PlaymatApi") +local tokenManager = require("core/token/TokenManager") local clickableResourceCounter = nil local foundTokens = 0 @@ -63,8 +259,8 @@ function searchSelf() for _, obj in ipairs(searchArea(self.getPosition(), { 2.5, 0.5, 3.5 })) do local obj = obj.hit_object - if obj.getCustomObject().image == - "http://cloud-3.steamusercontent.com/ugc/1758068501357192910/11DDDC7EF621320962FDCF3AE3211D5EDC3D1573/" then + local image = obj.getCustomObject().image + if image == "http://cloud-3.steamusercontent.com/ugc/1758068501357192910/11DDDC7EF621320962FDCF3AE3211D5EDC3D1573/" then foundTokens = foundTokens + math.abs(obj.getQuantity()) obj.destruct() elseif obj.getMemo() == "resourceCounter" then @@ -94,7 +290,7 @@ end function takeAll(playerColor) searchSelf() local matColor = playmatApi.getMatColorByPosition(self.getPosition()) - playmatApi.gainResources(foundTokens, matColor) + playmatApi.updateCounter(matColor, "ResourceCounter", _, foundTokens) if clickableResourceCounter then clickableResourceCounter.call("updateVal", 0) @@ -124,6 +320,7 @@ end end) __bundle_register("core/token/TokenManager", function(require, _LOADED, __bundle_register, __bundle_modules) do + local guidReferenceApi = require("core/GUIDReferenceApi") local optionPanelApi = require("core/OptionPanelApi") local playAreaApi = require("core/PlayAreaApi") local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") @@ -244,15 +441,10 @@ do ["supply"] = 7 } - -- Source for tokens - local TOKEN_SOURCE_GUID = "124381" - -- Table of data extracted from the token source bag, keyed by the Memo on each token which -- should match the token type keys ("resource", "clue", etc) local tokenTemplates - local DATA_HELPER_GUID = "708279" - local playerCardData local locationData @@ -350,9 +542,11 @@ do -- Copy the offsets to make sure we don't change the static values local baseOffsets = offsets offsets = { } + + -- get a vector for the shifting (downwards local to the card) + local shiftDownVector = Vector(0, 0, shiftDown):rotateOver("y", card.getRotation().y) for i, baseOffset in ipairs(baseOffsets) do - offsets[i] = baseOffset - offsets[i][3] = offsets[i][3] + shiftDown + offsets[i] = baseOffset + shiftDownVector end end @@ -465,8 +659,8 @@ do if tokenTemplates ~= nil then return end - tokenTemplates = { } - local tokenSource = getObjectFromGUID(TOKEN_SOURCE_GUID) + tokenTemplates = {} + local tokenSource = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSource") for _, tokenTemplate in ipairs(tokenSource.getData().ContainedObjects) do local tokenName = tokenTemplate.Memo tokenTemplates[tokenName] = tokenTemplate @@ -478,7 +672,7 @@ do if playerCardData ~= nil then return end - local dataHelper = getObjectFromGUID(DATA_HELPER_GUID) + local dataHelper = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") playerCardData = dataHelper.getTable('PLAYER_CARD_DATA') locationData = dataHelper.getTable('LOCATIONS_DATA') end @@ -493,18 +687,16 @@ do if uses == nil then return end -- go through tokens to spawn - local type, token, tokenCount + local tokenCount for i, useInfo in ipairs(uses) do - type = useInfo.type - token = useInfo.token - tokenCount = (useInfo.count or 0) - + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() - if extraUses ~= nil and extraUses[type] ~= nil then - tokenCount = tokenCount + extraUses[type] + tokenCount = (useInfo.count or 0) + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() + if extraUses ~= nil and extraUses[useInfo.type] ~= nil then + tokenCount = tokenCount + extraUses[useInfo.type] end -- Shift each spawned group after the first down so they don't pile on each other - TokenManager.spawnTokenGroup(card, token, tokenCount, (i - 1) * 0.8, type) + TokenManager.spawnTokenGroup(card, useInfo.token, tokenCount, (i - 1) * 0.8, useInfo.type) end + tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -528,9 +720,8 @@ do ---@param playerData Table Player card data structure retrieved from the DataHelper. Should be -- the right data for this card. internal.spawnPlayerCardTokensFromDataHelper = function(card, playerData) - token = playerData.tokenType - tokenCount = playerData.tokenCount - --log("Spawning data helper tokens for "..card.getName()..'['..card.getDescription()..']: '..tokenCount.."x "..token) + local token = playerData.tokenType + local tokenCount = playerData.tokenCount TokenManager.spawnTokenGroup(card, token, tokenCount) tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -563,7 +754,6 @@ do return 0 end - --log(card.getName() .. ' : ' .. locationData.type .. ' : ' .. locationData.value .. ' : ' .. locationData.clueSide) if ((card.is_face_down and locationData.clueSide == 'back') or (not card.is_face_down and locationData.clueSide == 'front')) then if locationData.type == 'fixed' then @@ -675,387 +865,233 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi end end) -__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local OptionPanelApi = {} - - -- loads saved options - ---@param options Table New options table - OptionPanelApi.loadSettings = function(options) - return Global.call("loadSettings", options) - end - - -- returns option panel table - OptionPanelApi.getOptions = function() - return Global.getTable("optionPanel") - end - - return OptionPanelApi -end -end) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" - - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") - end - - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) - end - - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) - end - - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) - end - - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) - end - - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) - end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") - end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi -end -end) -__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local TokenSpawnTracker = { } - local SPAWN_TRACKER_GUID = "e3ffc9" - - TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("hasSpawnedTokens", cardGuid) - end - - TokenSpawnTracker.markTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("markTokensSpawned", cardGuid) - end - - TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetTokensSpawned", cardGuid) - end - - TokenSpawnTracker.resetAllAssetAndEvents = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllAssetAndEvents") - end - - TokenSpawnTracker.resetAllLocations = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllLocations") - end - - TokenSpawnTracker.resetAll = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAll") - end - - return TokenSpawnTracker -end -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Favor of the Moon (1) 542a70.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Favor of the Moon (1) 542a70.ttslua index cbf312d9e..21e3565e1 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Favor of the Moon (1) 542a70.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Favor of the Moon (1) 542a70.ttslua @@ -41,139 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi -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.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("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/cards/FavoroftheMoon1") -end) -__bundle_register("playercards/cards/FavoroftheMoon1", function(require, _LOADED, __bundle_register, __bundle_modules) -VALID_TOKENS = { - ["Curse"] = true -} - -SHOW_SINGLE_RELEASE = true -KEEP_OPEN = true - -require("playercards/CardsThatSealTokens") -end) __bundle_register("playercards/CardsThatSealTokens", function(require, _LOADED, __bundle_register, __bundle_modules) --[[ Library for cards that seal tokens This file is used to add sealing option to cards' context menu. @@ -405,12 +272,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -435,4 +303,171 @@ do return TokenArrangerApi end end) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +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.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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/cards/FavoroftheMoon1") +end) +__bundle_register("playercards/cards/FavoroftheMoon1", function(require, _LOADED, __bundle_register, __bundle_modules) +VALID_TOKENS = { + ["Curse"] = true +} + +SHOW_SINGLE_RELEASE = true +KEEP_OPEN = true + +require("playercards/CardsThatSealTokens") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Favor of the Sun (1) 1e6a06.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Favor of the Sun (1) 1e6a06.ttslua index 6b3666146..9e543b480 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Favor of the Sun (1) 1e6a06.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Favor of the Sun (1) 1e6a06.ttslua @@ -41,83 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local TokenArrangerApi = {} - - -- 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) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] - 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) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi -end -end) __bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local ChaosBagApi = {} @@ -194,6 +117,36 @@ do 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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/FavoroftheSun1") end) @@ -435,4 +388,86 @@ function putTokenAway(guid) end end end) +__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 Variant 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 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) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +end +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Final Rhapsody 561775.yaml b/unpacked/Bag All Player Cards 15bb07/Card Final Rhapsody 561775.yaml new file mode 100644 index 000000000..657731a9c --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Final Rhapsody 561775.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 847001 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8470': + BackIsHidden: false + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2149964195986880793/517FBB4FF8F72900B9E123DB865BCAD625F6506C/ + NumHeight: 2 + NumWidth: 2 + Type: 0 + UniqueBack: false +Description: Advanced +DragSelectable: true +GMNotes: "{\n \"id\": \"90051\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n + \ \"traits\": \"Endtimes.\",\n \"weakness\": true,\n \"cycle\": \"The Dunwich + Legacy\"\n}" +GUID: '561775' +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Final Rhapsody +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 78.42 + posY: 3.19 + posZ: 23.54 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Flamethrower (5) (Taboo) 62ceb5.yaml b/unpacked/Bag All Player Cards 15bb07/Card Flamethrower (5) (Taboo) 62ceb5.yaml index 4b44dca8a..91904eebe 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Flamethrower (5) (Taboo) 62ceb5.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Flamethrower (5) (Taboo) 62ceb5.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) (Taboo) 453fd1.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) (Taboo) 453fd1.ttslua new file mode 100644 index 000000000..d08d3b16b --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) (Taboo) 453fd1.ttslua @@ -0,0 +1,473 @@ +-- 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/cards/FluteoftheOuterGods4", function(require, _LOADED, __bundle_register, __bundle_modules) +VALID_TOKENS = { + ["Curse"] = true +} + +SHOW_SINGLE_RELEASE = true +KEEP_OPEN = true + +require("playercards/CardsThatSealTokens") +end) +__bundle_register("playercards/CardsThatSealTokens", function(require, _LOADED, __bundle_register, __bundle_modules) +--[[ Library for cards that seal tokens +This file is used to add sealing option to cards' context menu. +Valid options (set before requiring this file): + +UPDATE_ON_HOVER --@type: boolean + - automatically updates the context menu options when the card is hovered + - the "Read Bag" function reads the content of the chaos bag to update the context menu + - example usage: "Unrelenting" (to only display valid tokens) + +KEEP_OPEN --@type: boolean +- meant for cards that seal single tokens multiple times (one by one) +- makes the context menu stay open after selecting an option +- example usage: "Unrelenting" + +SHOW_SINGLE_RELEASE --@type: boolean + - enables an entry in the context menu + - this entry allows releasing a single token + - example usage: "Holy Spear" (to keep the other tokens and just release one) + +SHOW_MULTI_RELEASE --@type: number (amount of tokens to release at once) + - enables an entry in the context menu + - this entry allows releasing of multiple tokens at once + - example usage: "Nephthys" (to release 3 bless tokens at once) + +SHOW_MULTI_SEAL --@type: number (amount of tokens to seal at once) + - enables an entry in the context menu + - this entry allows sealing of multiple tokens at once + - example usage: "Holy Spear" (to seal two bless tokens at once) + +VALID_TOKENS --@type: table ([tokenName] = true) + - this table defines which tokens should be abled to be sealed + - needs to be defined for each card -> even if empty + - example usage: "The Chthonian Stone" + > VALID_TOKENS = { + > ["Skull"] = true, + > ["Cultist"] = true, + > ["Tablet"] = true, + > ["Elder Thing"] = true, + > } + +INVALID_TOKENS --@type: table ([tokenName] = true) + - this table defines which tokens are invalid for sealing + - only needs to be defined if needed + - usually combined with empty "VALID_TOKENS" table + - example usage: "Protective Incantation" (not allowed to seal Auto-fail) + +---------------------------------------------------------- +Example 1: Crystalline Elder Sign +This card can only seal the "+1" or "Elder Sign" token, +it does not need specific options for multi-sealing or releasing. +Thus it should be implemented like this: + > VALID_TOKENS = { + > ["+1"] = true, + > ["Elder Sign"] = true + > } + > require... +---------------------------------------------------------- +Example 2: Holy Spear +This card features the following abilities (just listing the relevant parts): +- releasing a single bless token +- sealing two bless tokens +Thus it should be implemented like this: + > VALID_TOKENS = { + > ["Bless"] = true + > } + > SHOW_SINGLE_RELEASE = true + > SHOW_MULTI_SEAL = 2 + > require... +----------------------------------------------------------]] + +local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi") +local chaosBagApi = require("chaosbag/ChaosBagApi") +local tokenArrangerApi = require("accessories/TokenArrangerApi") + +local sealedTokens = {} +local ID_URL_MAP = {} +local tokensInBag = {} + +function onSave() return JSON.encode(sealedTokens) end + +function onLoad(savedData) + sealedTokens = JSON.decode(savedData) or {} + ID_URL_MAP = chaosBagApi.getIdUrlMap() + generateContextMenu() + self.addTag("CardThatSeals") +end + +-- builds the context menu +function generateContextMenu() + -- conditional single or multi release options + if SHOW_SINGLE_RELEASE then + self.addContextMenuItem("Release token", releaseOneToken) + elseif SHOW_MULTI_RELEASE then + self.addContextMenuItem("Release " .. SHOW_MULTI_RELEASE .. " token(s)", releaseMultipleTokens) + else + self.addContextMenuItem("Release token(s)", releaseAllTokens) + end + + -- main context menu options to seal tokens + for _, map in pairs(ID_URL_MAP) do + if (VALID_TOKENS[map.name] ~= nil) or (UPDATE_ON_HOVER and tokensInBag[map.name] and not INVALID_TOKENS[map.name]) then + if not SHOW_MULTI_SEAL then + self.addContextMenuItem("Seal " .. map.name, function(playerColor) + sealToken(map.name, playerColor) + end, KEEP_OPEN) + else + self.addContextMenuItem("Seal " .. SHOW_MULTI_SEAL .. " " .. map.name, function(playerColor) + readBag() + local allowed = true + local notFound + + for name, _ in pairs(VALID_TOKENS) do + if (tokensInBag[name] or 0) < SHOW_MULTI_SEAL then + allowed = false + notFound = name + end + end + + if allowed then + for i = 1, SHOW_MULTI_SEAL do + sealToken(map.name, playerColor) + end + else + printToColor("Not enough " .. notFound .. " tokens in the chaos bag.", playerColor) + end + end) + end + end + end +end + +-- generates a list of chaos tokens that is in the chaos bag +function readBag() + local chaosbag = chaosBagApi.findChaosBag() + tokensInBag = {} + + for _, token in ipairs(chaosbag.getObjects()) do + tokensInBag[token.name] = (tokensInBag[token.name] or 0) + 1 + end +end + +-- native event from TTS - used to update the context menu for cards like "Unrelenting" +function onHover() + if UPDATE_ON_HOVER then + readBag() + self.clearContextMenu() + generateContextMenu() + end +end + +-- seals the named token on this card +function sealToken(name, playerColor) + if not chaosBagApi.canTouchChaosTokens() then return end + local chaosbag = chaosBagApi.findChaosBag() + for i, obj in ipairs(chaosbag.getObjects()) do + if obj.name == name then + chaosbag.takeObject({ + position = self.getPosition() + Vector(0, 0.5 + 0.1 * #sealedTokens, 0), + rotation = self.getRotation(), + index = i - 1, + smooth = false, + callback_function = function(token) + local guid = token.getGUID() + table.insert(sealedTokens, guid) + tokenArrangerApi.layout() + if name == "Bless" or name == "Curse" then + blessCurseManagerApi.sealedToken(name, guid) + end + end + }) + return + end + end + printToColor(name .. " token not found in chaos bag", playerColor) +end + +-- release the last sealed token +function releaseOneToken(playerColor) + if not chaosBagApi.canTouchChaosTokens() then return end + if #sealedTokens == 0 then + printToColor("No sealed token(s) found", playerColor) + else + printToColor("Releasing token", playerColor) + putTokenAway(table.remove(sealedTokens)) + end +end + +-- release multiple tokens at once +function releaseMultipleTokens(playerColor) + if SHOW_MULTI_RELEASE <= #sealedTokens then + for i = 1, SHOW_MULTI_RELEASE do + putTokenAway(table.remove(sealedTokens)) + end + printToColor("Releasing " .. SHOW_MULTI_RELEASE .. " tokens", playerColor) + else + printToColor("Not enough tokens sealed.", playerColor) + end +end + +-- releases all sealed tokens +function releaseAllTokens(playerColor) + if not chaosBagApi.canTouchChaosTokens() then return end + if #sealedTokens == 0 then + printToColor("No sealed token(s) found", playerColor) + else + printToColor("Releasing token(s)", playerColor) + for _, guid in ipairs(sealedTokens) do + putTokenAway(guid) + end + sealedTokens = {} + end +end + +-- returns the token (referenced by GUID) to the chaos bag +function putTokenAway(guid) + local token = getObjectFromGUID(guid) + if not token then return end + + local name = token.getName() + local chaosbag = chaosBagApi.findChaosBag() + chaosbag.putObject(token) + tokenArrangerApi.layout() + if name == "Bless" or name == "Curse" then + blessCurseManagerApi.releasedToken(name, guid) + end +end +end) +__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 Variant 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 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) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +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.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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/cards/FluteoftheOuterGods4") +end) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) (Taboo) 453fd1.yaml b/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) (Taboo) 453fd1.yaml index fb12c710b..bebb941f7 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) (Taboo) 453fd1.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) (Taboo) 453fd1.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 @@ -31,7 +31,7 @@ HideWhenFaceDown: true IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: false -LuaScript: '' +LuaScript: !include 'Card Flute of the Outer Gods (4) (Taboo) 453fd1.ttslua' LuaScriptState: '' MeasureMovement: false Name: Card diff --git a/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) 3cc1e2.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) 3cc1e2.ttslua index 69c1e5171..536914556 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) 3cc1e2.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Flute of the Outer Gods (4) 3cc1e2.ttslua @@ -41,47 +41,18 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local TokenArrangerApi = {} - - -- 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) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] - 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) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -89,30 +60,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -194,6 +165,36 @@ do 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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/FluteoftheOuterGods4") end) @@ -435,4 +436,38 @@ function putTokenAway(guid) end end end) +__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 Variant 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 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Geared Up (Taboo) 83af5e.yaml b/unpacked/Bag All Player Cards 15bb07/Card Geared Up (Taboo) 83af5e.yaml index 5ac106fe9..016dee0f7 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Geared Up (Taboo) 83af5e.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Geared Up (Taboo) 83af5e.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Gené Beauregard (3) (Taboo) d300bf.yaml b/unpacked/Bag All Player Cards 15bb07/Card Gené Beauregard (3) (Taboo) d300bf.yaml index f4c2132ae..3dbba17b6 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Gené Beauregard (3) (Taboo) d300bf.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Gené Beauregard (3) (Taboo) d300bf.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Hallow (3) (Taboo) 175810.yaml b/unpacked/Bag All Player Cards 15bb07/Card Hallow (3) (Taboo) 175810.yaml index 4148f7bed..69fa6a31b 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Hallow (3) (Taboo) 175810.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Hallow (3) (Taboo) 175810.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Hasty Repairs 0821d5.yaml b/unpacked/Bag All Player Cards 15bb07/Card Hasty Repairs 0821d5.yaml new file mode 100644 index 000000000..95828a9f2 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Hasty Repairs 0821d5.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 910300 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '9103': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2223150865961116492/B9D47B63A4285734AC59208BA2F5509EF4B8C138/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10003\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n + \ \"traits\": \"Blunder.\",\n \"weakness\": true,\n \"cycle\": \"The Feast of + Hemlock Vale\"\n}" +GUID: 0821d5 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Hasty Repairs +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 10.69 + posY: 2.44 + posZ: 43.88 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Holy Spear (5) 28289a.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Holy Spear (5) 28289a.ttslua index 3fd0d711c..c30c1e04e 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Holy Spear (5) 28289a.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Holy Spear (5) 28289a.ttslua @@ -41,6 +41,160 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +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.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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/HolySpear5") end) @@ -285,12 +439,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -315,124 +470,4 @@ do return TokenArrangerApi end end) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi -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.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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Hospital Debts 47d6c9.yaml b/unpacked/Bag All Player Cards 15bb07/Card Hospital Debts 47d6c9.yaml index ec654038a..4b2be40a1 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Hospital Debts 47d6c9.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Hospital Debts 47d6c9.yaml @@ -19,9 +19,10 @@ CustomDeck: UniqueBack: false Description: Signature DragSelectable: true -GMNotes: "{\r\n \"id\": \"01011\",\r\n \"alternate_ids\": [\r\n \"01511\"\r\n - \ ],\r\n \"type\": \"Treachery\",\r\n \"class\": \"Neutral\",\r\n \"traits\": - \"Task.\",\r\n \"weakness\": true,\r\n \"cycle\": \"Core\"\r\n}\r" +GMNotes: "{\n \"id\": \"01011\",\n \"alternate_ids\": [\n \"01511\"\n ],\n \"type\": + \"Treachery\",\n \"class\": \"Neutral\",\n \"traits\": \"Task.\",\n \"weakness\": + true,\n \"uses\": [\n {\n \"count\": 0,\n \"type\": \"Resource\",\n + \ \"token\": \"resource\"\n }\n ],\n \"cycle\": \"Core\"\n}" GUID: 47d6c9 Grid: true GridProjection: false diff --git a/unpacked/Bag All Player Cards 15bb07/Card Hypnotic Gaze (Taboo) 47d782.yaml b/unpacked/Bag All Player Cards 15bb07/Card Hypnotic Gaze (Taboo) 47d782.yaml index e91cd3b72..8f5db4eb8 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Hypnotic Gaze (Taboo) 47d782.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Hypnotic Gaze (Taboo) 47d782.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Interrogate (Taboo) a6726e.yaml b/unpacked/Bag All Player Cards 15bb07/Card Interrogate (Taboo) a6726e.yaml index 135bcaf8f..64846e734 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Interrogate (Taboo) a6726e.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Interrogate (Taboo) a6726e.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Jeremiah Kirby (Taboo) a03cd7.yaml b/unpacked/Bag All Player Cards 15bb07/Card Jeremiah Kirby (Taboo) a03cd7.yaml index a1aa57198..eadbf59ba 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Jeremiah Kirby (Taboo) a03cd7.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Jeremiah Kirby (Taboo) a03cd7.yaml @@ -12,12 +12,12 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 UniqueBack: false -Description: arctic Archaeologist +Description: Arctic Archaeologist DragSelectable: true GMNotes: "{\n \"id\": \"08032-t\",\n \"type\": \"Asset\",\n \"class\": \"Seeker\",\n \ \"cost\": 4,\n \"level\": 0,\n \"traits\": \"Ally. Miskatonic. Wayfarer.\",\n diff --git a/unpacked/Bag All Player Cards 15bb07/Card Jewel of Aureolus (3) (Taboo) 5f4d1c.yaml b/unpacked/Bag All Player Cards 15bb07/Card Jewel of Aureolus (3) (Taboo) 5f4d1c.yaml index d84230499..599457256 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Jewel of Aureolus (3) (Taboo) 5f4d1c.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Jewel of Aureolus (3) (Taboo) 5f4d1c.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Jim Culver (Parallel Back) aba863.yaml b/unpacked/Bag All Player Cards 15bb07/Card Jim Culver (Parallel Back) aba863.yaml new file mode 100644 index 000000000..b6e0a1f5e --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Jim Culver (Parallel Back) aba863.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 846805 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8468': + BackIsHidden: false + BackURL: http://cloud-3.steamusercontent.com/ugc/2149964195987018702/54C63785F3AA474F635F58BC506C86A318432BD7/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/1656727981627737050/3CFF9E3825033909543AD1CF843361D9243538EE/ + NumHeight: 2 + NumWidth: 4 + Type: 0 + UniqueBack: true +Description: The Musician +DragSelectable: true +GMNotes: "{\n \"id\": \"02004-pb\",\n \"type\": \"Investigator\",\n \"class\": + \"Mystic\",\n \"traits\": \"Performer.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": + 3,\n \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"The Dunwich Legacy\"\n}" +GUID: aba863 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Jim Culver (Parallel Back) +SidewaysCard: true +Snap: true +Sticky: true +Tags: +- Investigator +- PlayerCard +Tooltip: true +Transform: + posX: 82.21 + posY: 3.19 + posZ: 18.46 + rotX: 0 + rotY: 180 + rotZ: 0 + scaleX: 1.15 + scaleY: 1 + scaleZ: 1.15 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Jim Culver (Parallel Front) c5fc80.yaml b/unpacked/Bag All Player Cards 15bb07/Card Jim Culver (Parallel Front) c5fc80.yaml new file mode 100644 index 000000000..a403a3ee6 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Jim Culver (Parallel Front) c5fc80.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 846905 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8469': + BackIsHidden: false + BackURL: http://cloud-3.steamusercontent.com/ugc/1656727981627737648/F371339538812F68E38AAC0D520C525250DAC5C0/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2149964195987018793/0AED4BF62C4FF3206778AD36FDB9C8E482CD3F9E/ + NumHeight: 2 + NumWidth: 4 + Type: 0 + UniqueBack: true +Description: The Musician +DragSelectable: true +GMNotes: "{\n \"id\": \"02004-pf\",\n \"type\": \"Investigator\",\n \"class\": + \"Mystic\",\n \"traits\": \"Performer. Cursed.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": + 3,\n \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"The Dunwich Legacy\"\n}" +GUID: c5fc80 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Jim Culver (Parallel Front) +SidewaysCard: true +Snap: true +Sticky: true +Tags: +- Investigator +- PlayerCard +Tooltip: true +Transform: + posX: 82.09 + posY: 3.19 + posZ: 22.48 + rotX: 0 + rotY: 180 + rotZ: 0 + scaleX: 1.15 + scaleY: 1 + scaleZ: 1.15 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Jim Culver (Parallel) 72bf31.yaml b/unpacked/Bag All Player Cards 15bb07/Card Jim Culver (Parallel) 72bf31.yaml new file mode 100644 index 000000000..2fb477150 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Jim Culver (Parallel) 72bf31.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 846700 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8467': + BackIsHidden: false + BackURL: http://cloud-3.steamusercontent.com/ugc/2149964195987018702/54C63785F3AA474F635F58BC506C86A318432BD7/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2149964195987018793/0AED4BF62C4FF3206778AD36FDB9C8E482CD3F9E/ + NumHeight: 2 + NumWidth: 4 + Type: 0 + UniqueBack: true +Description: The Musician +DragSelectable: true +GMNotes: "{\n \"id\": \"02004-p\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n + \ \"traits\": \"Performer. Cursed.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": + 3,\n \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"The Dunwich Legacy\"\n}" +GUID: 72bf31 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Jim Culver (Parallel) +SidewaysCard: true +Snap: true +Sticky: true +Tags: +- Investigator +- PlayerCard +Tooltip: true +Transform: + posX: 82.18 + posY: 3.19 + posZ: 26.39 + rotX: 0 + rotY: 180 + rotZ: 0 + scaleX: 1.15 + scaleY: 1 + scaleZ: 1.15 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Jim's Trumpet 03c6a7.yaml b/unpacked/Bag All Player Cards 15bb07/Card Jim's Trumpet 03c6a7.yaml index 3f5086a4b..d85c1974a 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Jim's Trumpet 03c6a7.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Jim's Trumpet 03c6a7.yaml @@ -17,7 +17,7 @@ CustomDeck: NumWidth: 10 Type: 0 UniqueBack: false -Description: '' +Description: The Dead Listen DragSelectable: true GMNotes: "{\r\n \"id\": \"02012\",\r\n \"type\": \"Asset\",\r\n \"class\": \"Neutral\",\r\n \ \"cost\": 2,\r\n \"traits\": \"Item. Instrument. Relic.\",\r\n \"willpowerIcons\": diff --git a/unpacked/Bag All Player Cards 15bb07/Card Jim's Trumpet 7dfd5f.yaml b/unpacked/Bag All Player Cards 15bb07/Card Jim's Trumpet 7dfd5f.yaml new file mode 100644 index 000000000..f6ccc0899 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Jim's Trumpet 7dfd5f.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 847000 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8470': + BackIsHidden: false + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2149964195986880793/517FBB4FF8F72900B9E123DB865BCAD625F6506C/ + NumHeight: 2 + NumWidth: 2 + Type: 0 + UniqueBack: false +Description: The Dead Speak (Advanced) +DragSelectable: true +GMNotes: "{\n \"id\": \"90050\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n + \ \"cost\": 2,\n \"traits\": \"Item. Instrument. Relic.\",\n \"willpowerIcons\": + 2,\n \"wildIcons\": 2,\n \"cycle\": \"The Dunwich Legacy\"\n}" +GUID: 7dfd5f +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Jim's Trumpet +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 78.51 + posY: 3.23 + posZ: 27.01 + rotX: 359 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Key of Ys (5) (Taboo) 9451ee.yaml b/unpacked/Bag All Player Cards 15bb07/Card Key of Ys (5) (Taboo) 9451ee.yaml index 9320c64bc..27464f0f3 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Key of Ys (5) (Taboo) 9451ee.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Key of Ys (5) (Taboo) 9451ee.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Knowledge is Power (Taboo) 0dd658.yaml b/unpacked/Bag All Player Cards 15bb07/Card Knowledge is Power (Taboo) 0dd658.yaml index b4e800747..3de9f5b16 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Knowledge is Power (Taboo) 0dd658.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Knowledge is Power (Taboo) 0dd658.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Mr. Rook (Taboo) 522279.yaml b/unpacked/Bag All Player Cards 15bb07/Card Mr. Rook (Taboo) 522279.yaml index 69bdf124d..3f147cc05 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Mr. Rook (Taboo) 522279.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Mr. Rook (Taboo) 522279.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Nephthys (4) 5659d1.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Nephthys (4) 5659d1.ttslua index 9097e8b1f..003136164 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Nephthys (4) 5659d1.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Nephthys (4) 5659d1.ttslua @@ -41,6 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/cards/Nephthys4") +end) __bundle_register("playercards/cards/Nephthys4", function(require, _LOADED, __bundle_register, __bundle_modules) VALID_TOKENS = { ["Bless"] = true @@ -281,12 +284,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -314,11 +318,15 @@ end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -326,30 +334,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -431,7 +439,34 @@ do return ChaosBagApi end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/cards/Nephthys4") +__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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Olive McBride 9683d2.yaml b/unpacked/Bag All Player Cards 15bb07/Card Olive McBride 9683d2.yaml new file mode 100644 index 000000000..f51a75c42 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Olive McBride 9683d2.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 91200 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '912': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2195002645140651764/97A66D51D85628992E10826FF866E96E310FB177/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: Tried Everything Once +DragSelectable: true +GMNotes: "{\n \"id\": \"10097\",\n \"type\": \"Asset\",\n \"class\": \"Mystic\",\n + \ \"cost\": 2,\n \"level\": 2,\n \"traits\": \"Ally. Witch.\",\n \"willpowerIcons\": + 2,\n \"cycle\": \"The Feast of Hemlock Vale\"\n}" +GUID: 9683d2 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Olive McBride +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 9.13 + posY: 3.79 + posZ: -16.72 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Pathfinder (1) (Taboo) 305e37.yaml b/unpacked/Bag All Player Cards 15bb07/Card Pathfinder (1) (Taboo) 305e37.yaml index e20f22044..0c8e61864 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Pathfinder (1) (Taboo) 305e37.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Pathfinder (1) (Taboo) 305e37.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Pendant of the Queen (Taboo) 02b9b9.yaml b/unpacked/Bag All Player Cards 15bb07/Card Pendant of the Queen (Taboo) 02b9b9.yaml index 8fece2c85..52c5f98e7 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Pendant of the Queen (Taboo) 02b9b9.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Pendant of the Queen (Taboo) 02b9b9.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Persuasion (Taboo) 821d99.yaml b/unpacked/Bag All Player Cards 15bb07/Card Persuasion (Taboo) 821d99.yaml index ef596eddf..2a31b9aa5 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Persuasion (Taboo) 821d99.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Persuasion (Taboo) 821d99.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Power Word (Taboo) dc1962.yaml b/unpacked/Bag All Player Cards 15bb07/Card Power Word (Taboo) dc1962.yaml index e44190c85..a2c603b51 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Power Word (Taboo) dc1962.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Power Word (Taboo) dc1962.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Power Word Upgrade Sheet (Taboo) ebce85.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Power Word Upgrade Sheet (Taboo) ebce85.ttslua index fd3bc1f67..181ce4206 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Power Word Upgrade Sheet (Taboo) ebce85.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Power Word Upgrade Sheet (Taboo) ebce85.ttslua @@ -41,6 +41,72 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/customizable/PowerWordUpgradeSheetTaboo") +end) +__bundle_register("playercards/customizable/PowerWordUpgradeSheetTaboo", function(require, _LOADED, __bundle_register, __bundle_modules) +-- Customizable Cards: Power Word (Taboo) + +-- Color information for buttons +boxSize = 38 + +-- static values +xInitial = -0.933 +xOffset = 0.069 + +customizations = { + [1] = { + checkboxes = { + posZ = -0.905, + count = 1, + } + }, + [2] = { + checkboxes = { + posZ = -0.6, + count = 1, + } + }, + [3] = { + checkboxes = { + posZ = -0.42, + count = 1, + } + }, + [4] = { + checkboxes = { + posZ = -0.12, + count = 1, + } + }, + [5] = { + checkboxes = { + posZ = 0.18, + count = 2, + }, + }, + [6] = { + checkboxes = { + posZ = 0.38, + count = 3, + } + }, + [7] = { + checkboxes = { + posZ = 0.675, + count = 3, + }, + }, + [8] = { + checkboxes = { + posZ = 0.875, + count = 3, + }, + }, +} + +require("playercards/customizable/UpgradeSheetLibrary") +end) __bundle_register("playercards/customizable/UpgradeSheetLibrary", function(require, _LOADED, __bundle_register, __bundle_modules) -- Common code for handling customizable card upgrade sheets -- Define UI elements in the base card file, then include this @@ -491,295 +557,263 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/customizable/PowerWordUpgradeSheetTaboo") -end) -__bundle_register("playercards/customizable/PowerWordUpgradeSheetTaboo", function(require, _LOADED, __bundle_register, __bundle_modules) --- Customizable Cards: Power Word (Taboo) +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local GUIDReferenceApi = {} --- Color information for buttons -boxSize = 38 + local function getGuidHandler() + return getObjectFromGUID("123456") + end --- static values -xInitial = -0.933 -xOffset = 0.069 + -- 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 -customizations = { - [1] = { - checkboxes = { - posZ = -0.905, - count = 1, - } - }, - [2] = { - checkboxes = { - posZ = -0.6, - count = 1, - } - }, - [3] = { - checkboxes = { - posZ = -0.42, - count = 1, - } - }, - [4] = { - checkboxes = { - posZ = -0.12, - count = 1, - } - }, - [5] = { - checkboxes = { - posZ = 0.18, - count = 2, - }, - }, - [6] = { - checkboxes = { - posZ = 0.38, - count = 3, - } - }, - [7] = { - checkboxes = { - posZ = 0.675, - count = 3, - }, - }, - [8] = { - checkboxes = { - posZ = 0.875, - count = 3, - }, - }, -} + -- 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 -require("playercards/customizable/UpgradeSheetLibrary") + -- 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Prophesiae Profana (5) (Taboo) 957c32.yaml b/unpacked/Bag All Player Cards 15bb07/Card Prophesiae Profana (5) (Taboo) 957c32.yaml index 4f37c48a7..aafe62942 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Prophesiae Profana (5) (Taboo) 957c32.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Prophesiae Profana (5) (Taboo) 957c32.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Protective Incantation (1) 0fd4ae.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Protective Incantation (1) 0fd4ae.ttslua index 609903efa..49bea8de0 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Protective Incantation (1) 0fd4ae.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Protective Incantation (1) 0fd4ae.ttslua @@ -41,162 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local TokenArrangerApi = {} - - -- 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) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] - 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) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi -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.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("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/cards/ProtectiveIncantation1") -end) __bundle_register("playercards/cards/ProtectiveIncantation1", function(require, _LOADED, __bundle_register, __bundle_modules) VALID_TOKENS = {} @@ -436,4 +280,195 @@ function putTokenAway(guid) end end end) +__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 Variant 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 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) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +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.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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/cards/ProtectiveIncantation1") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Quick Thinking (Taboo) 4a49ea.yaml b/unpacked/Bag All Player Cards 15bb07/Card Quick Thinking (Taboo) 4a49ea.yaml index 00f805234..c217a8beb 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Quick Thinking (Taboo) 4a49ea.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Quick Thinking (Taboo) 4a49ea.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Radiant Smite (1) 92c295.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Radiant Smite (1) 92c295.ttslua index 9f6d103f5..5b1591dbd 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Radiant Smite (1) 92c295.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Radiant Smite (1) 92c295.ttslua @@ -41,6 +41,160 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +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.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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/RadiantSmite1") end) @@ -284,12 +438,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -314,124 +469,4 @@ do return TokenArrangerApi end end) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi -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.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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Research Notes (Taboo) 085c08.yaml b/unpacked/Bag All Player Cards 15bb07/Card Research Notes (Taboo) 085c08.yaml index c4a05affe..5e26dd4ec 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Research Notes (Taboo) 085c08.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Research Notes (Taboo) 085c08.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Rite of Equilibrium (5) (Taboo) 2286b4.yaml b/unpacked/Bag All Player Cards 15bb07/Card Rite of Equilibrium (5) (Taboo) 2286b4.yaml index 6d601fa58..018fd3bd8 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Rite of Equilibrium (5) (Taboo) 2286b4.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Rite of Equilibrium (5) (Taboo) 2286b4.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Rite of Sanctification 974743.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Rite of Sanctification 974743.ttslua index 32547f173..76656b00f 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Rite of Sanctification 974743.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Rite of Sanctification 974743.ttslua @@ -41,159 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local TokenArrangerApi = {} - - -- 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) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] - 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) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi -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.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("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/RiteofSanctification") end) @@ -434,4 +281,192 @@ function putTokenAway(guid) end end end) +__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 Variant 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 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) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +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.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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Ritual Candles (Taboo) 7dc746.yaml b/unpacked/Bag All Player Cards 15bb07/Card Ritual Candles (Taboo) 7dc746.yaml index fb316dc03..1e3c9ceeb 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Ritual Candles (Taboo) 7dc746.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Ritual Candles (Taboo) 7dc746.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Runic Axe (Taboo) 3e3b99.yaml b/unpacked/Bag All Player Cards 15bb07/Card Runic Axe (Taboo) 3e3b99.yaml index a53a55e31..dc6f2f1c4 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Runic Axe (Taboo) 3e3b99.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Runic Axe (Taboo) 3e3b99.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Runic Axe Upgrade Sheet (Taboo) 4d729b.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Runic Axe Upgrade Sheet (Taboo) 4d729b.ttslua index 5142bb161..5fa06488d 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Runic Axe Upgrade Sheet (Taboo) 4d729b.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Runic Axe Upgrade Sheet (Taboo) 4d729b.ttslua @@ -41,6 +41,267 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/customizable/RunicAxeUpgradeSheetTaboo") end) @@ -555,231 +816,4 @@ function maybeUpdateServitorSlotDisplay() }) end end) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlaymatApi = { } - local internal = { } - - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end - end - - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi -end -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) 84a7df.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) 84a7df.ttslua new file mode 100644 index 000000000..eb7edf910 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) 84a7df.ttslua @@ -0,0 +1,436 @@ +-- 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/cards/ScrollofSecrets", function(require, _LOADED, __bundle_register, __bundle_modules) +-- this script is shared between the lvl 0 and lvl 3 versions of Scroll of Secrets +local mythosAreaApi = require("core/MythosAreaApi") +local playmatApi = require("playermat/PlaymatApi") + +-- get class via metadata and create context menu accordingly +function onLoad() + local notes = JSON.decode(self.getGMNotes()) + if notes then + createContextMenu(notes.id) + else + print("Missing metadata for Scroll of Secrets!") + end +end + +function createContextMenu(id) + if id == "05116" or id == "05116-t" then + -- lvl 0: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + elseif id == "05188" or id == "05188-t" then + -- seeker lvl 3: draw 3 cards from the bottom + self.addContextMenuItem("Draw bottom card(s)", function(playerColor) contextFunc(playerColor, 3) end) + elseif id == "05189" or id == "05189-t" then + -- mystic lvl 3: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + end +end + +function contextFunc(playerColor, amount) + local options = { "Encounter Deck" } + + -- check for players with a deck and only display them as option + for _, color in ipairs(Player.getAvailableColors()) do + local matColor = playmatApi.getMatColor(color) + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + + if deckAreaObjects.draw or deckAreaObjects.topCard then + table.insert(options, color) + end + end + + -- show the target selection dialog + Player[playerColor].showOptionsDialog("Select target deck", options, _, function(owner) drawCardsFromBottom(playerColor, owner, amount) end) +end + +function drawCardsFromBottom(playerColor, owner, amount) + -- variable initialization + local deck = nil + local deckSize = 1 + local deckAreaObjects = {} + + -- get the respective deck + if owner == "Encounter Deck" then + deck = mythosAreaApi.getEncounterDeck() + else + local matColor = playmatApi.getMatColor(owner) + deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + deck = deckAreaObjects.draw + end + + -- error handling + if not deck then + printToColor("Couldn't find deck!", playerColor) + return + end + + -- set deck size if there is actually a deck and not just a card + if deck.type == "Deck" then + deckSize = #deck.getObjects() + end + + -- proceed according to deck size + if deckSize > amount then + for i = 1, amount do + local card = deck.takeObject({ top = false, flip = true }) + card.deal(1, playerColor) + end + else + -- deal the whole deck + deck.deal(amount, playerColor) + + if deckSize < amount then + -- Norman Withers handling + if deckAreaObjects.topCard then + deckAreaObjects.topCard.deal(1, playerColor) + deckSize = deckSize + 1 + end + + -- warning message for player + if deckSize < amount then + printToColor("Deck didn't contain enough cards.", playerColor) + end + end + end + printToColor("Handle the drawn cards according to the ability text on 'Scroll of Secrets'.", playerColor) +end +end) +__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local MythosAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end + + -- returns the chaos token metadata (if provided through scenario reference card) + MythosAreaApi.returnTokenData = function() + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") + end + + -- draw an encounter card to the requested position/rotation + MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) + getMythosArea().call("drawEncounterCard", { + pos = pos, + rotY = rotY, + alwaysFaceUp = alwaysFaceUp + }) + end + + return MythosAreaApi +end +end) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/cards/ScrollofSecrets") +end) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) 84a7df.yaml b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) 84a7df.yaml index 8d0b400b8..83b81a1b4 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) 84a7df.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) 84a7df.yaml @@ -12,18 +12,17 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 UniqueBack: false Description: '' DragSelectable: true -GMNotes: "{\n \"id\": \"05189-t\",\n \"type\": \"Asset\",\n \"class\": \"Mystic\",\n - \ \"cost\": 1,\n \"level\": 3,\n \"traits\": \"Item. Tome.\",\n \"willpowerIcons\": - 1,\n \"intellectIcons\": 1,\n \"uses\": [\n {\n \"count\": 4,\n \"type\": - \"Secret\",\n \"token\": \"resource\"\n }\n ],\n \"cycle\": \"The Circle - Undone\"\n}" +GMNotes: "{\n \"id\": \"05188-t\",\n \"type\": \"Asset\",\n \"class\": \"Seeker\",\n + \ \"cost\": 1,\n \"level\": 3,\n \"traits\": \"Item. Tome.\",\n \"intellectIcons\": + 2,\n \"uses\": [\n {\n \"count\": 3,\n \"type\": \"Secret\",\n \"token\": + \"resource\"\n }\n ],\n \"cycle\": \"The Circle Undone\"\n}" GUID: 84a7df Grid: true GridProjection: false @@ -32,7 +31,7 @@ HideWhenFaceDown: true IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: false -LuaScript: '' +LuaScript: !include 'Card Scroll of Secrets (3) (Taboo) 84a7df.ttslua' LuaScriptState: '' MeasureMovement: false Name: Card diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) c127f1.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) c127f1.ttslua new file mode 100644 index 000000000..b76b9c5a5 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) c127f1.ttslua @@ -0,0 +1,436 @@ +-- 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("playercards/cards/ScrollofSecrets") +end) +__bundle_register("playercards/cards/ScrollofSecrets", function(require, _LOADED, __bundle_register, __bundle_modules) +-- this script is shared between the lvl 0 and lvl 3 versions of Scroll of Secrets +local mythosAreaApi = require("core/MythosAreaApi") +local playmatApi = require("playermat/PlaymatApi") + +-- get class via metadata and create context menu accordingly +function onLoad() + local notes = JSON.decode(self.getGMNotes()) + if notes then + createContextMenu(notes.id) + else + print("Missing metadata for Scroll of Secrets!") + end +end + +function createContextMenu(id) + if id == "05116" or id == "05116-t" then + -- lvl 0: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + elseif id == "05188" or id == "05188-t" then + -- seeker lvl 3: draw 3 cards from the bottom + self.addContextMenuItem("Draw bottom card(s)", function(playerColor) contextFunc(playerColor, 3) end) + elseif id == "05189" or id == "05189-t" then + -- mystic lvl 3: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + end +end + +function contextFunc(playerColor, amount) + local options = { "Encounter Deck" } + + -- check for players with a deck and only display them as option + for _, color in ipairs(Player.getAvailableColors()) do + local matColor = playmatApi.getMatColor(color) + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + + if deckAreaObjects.draw or deckAreaObjects.topCard then + table.insert(options, color) + end + end + + -- show the target selection dialog + Player[playerColor].showOptionsDialog("Select target deck", options, _, function(owner) drawCardsFromBottom(playerColor, owner, amount) end) +end + +function drawCardsFromBottom(playerColor, owner, amount) + -- variable initialization + local deck = nil + local deckSize = 1 + local deckAreaObjects = {} + + -- get the respective deck + if owner == "Encounter Deck" then + deck = mythosAreaApi.getEncounterDeck() + else + local matColor = playmatApi.getMatColor(owner) + deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + deck = deckAreaObjects.draw + end + + -- error handling + if not deck then + printToColor("Couldn't find deck!", playerColor) + return + end + + -- set deck size if there is actually a deck and not just a card + if deck.type == "Deck" then + deckSize = #deck.getObjects() + end + + -- proceed according to deck size + if deckSize > amount then + for i = 1, amount do + local card = deck.takeObject({ top = false, flip = true }) + card.deal(1, playerColor) + end + else + -- deal the whole deck + deck.deal(amount, playerColor) + + if deckSize < amount then + -- Norman Withers handling + if deckAreaObjects.topCard then + deckAreaObjects.topCard.deal(1, playerColor) + deckSize = deckSize + 1 + end + + -- warning message for player + if deckSize < amount then + printToColor("Deck didn't contain enough cards.", playerColor) + end + end + end + printToColor("Handle the drawn cards according to the ability text on 'Scroll of Secrets'.", playerColor) +end +end) +__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local MythosAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end + + -- returns the chaos token metadata (if provided through scenario reference card) + MythosAreaApi.returnTokenData = function() + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") + end + + -- draw an encounter card to the requested position/rotation + MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) + getMythosArea().call("drawEncounterCard", { + pos = pos, + rotY = rotY, + alwaysFaceUp = alwaysFaceUp + }) + end + + return MythosAreaApi +end +end) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) c127f1.yaml b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) c127f1.yaml index d4e3482b1..dee95f2fa 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) c127f1.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) (Taboo) c127f1.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 @@ -32,7 +32,7 @@ HideWhenFaceDown: true IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: false -LuaScript: '' +LuaScript: !include 'Card Scroll of Secrets (3) (Taboo) c127f1.ttslua' LuaScriptState: '' MeasureMovement: false Name: Card diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 0b12ac.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 0b12ac.ttslua new file mode 100644 index 000000000..b76b9c5a5 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 0b12ac.ttslua @@ -0,0 +1,436 @@ +-- 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("playercards/cards/ScrollofSecrets") +end) +__bundle_register("playercards/cards/ScrollofSecrets", function(require, _LOADED, __bundle_register, __bundle_modules) +-- this script is shared between the lvl 0 and lvl 3 versions of Scroll of Secrets +local mythosAreaApi = require("core/MythosAreaApi") +local playmatApi = require("playermat/PlaymatApi") + +-- get class via metadata and create context menu accordingly +function onLoad() + local notes = JSON.decode(self.getGMNotes()) + if notes then + createContextMenu(notes.id) + else + print("Missing metadata for Scroll of Secrets!") + end +end + +function createContextMenu(id) + if id == "05116" or id == "05116-t" then + -- lvl 0: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + elseif id == "05188" or id == "05188-t" then + -- seeker lvl 3: draw 3 cards from the bottom + self.addContextMenuItem("Draw bottom card(s)", function(playerColor) contextFunc(playerColor, 3) end) + elseif id == "05189" or id == "05189-t" then + -- mystic lvl 3: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + end +end + +function contextFunc(playerColor, amount) + local options = { "Encounter Deck" } + + -- check for players with a deck and only display them as option + for _, color in ipairs(Player.getAvailableColors()) do + local matColor = playmatApi.getMatColor(color) + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + + if deckAreaObjects.draw or deckAreaObjects.topCard then + table.insert(options, color) + end + end + + -- show the target selection dialog + Player[playerColor].showOptionsDialog("Select target deck", options, _, function(owner) drawCardsFromBottom(playerColor, owner, amount) end) +end + +function drawCardsFromBottom(playerColor, owner, amount) + -- variable initialization + local deck = nil + local deckSize = 1 + local deckAreaObjects = {} + + -- get the respective deck + if owner == "Encounter Deck" then + deck = mythosAreaApi.getEncounterDeck() + else + local matColor = playmatApi.getMatColor(owner) + deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + deck = deckAreaObjects.draw + end + + -- error handling + if not deck then + printToColor("Couldn't find deck!", playerColor) + return + end + + -- set deck size if there is actually a deck and not just a card + if deck.type == "Deck" then + deckSize = #deck.getObjects() + end + + -- proceed according to deck size + if deckSize > amount then + for i = 1, amount do + local card = deck.takeObject({ top = false, flip = true }) + card.deal(1, playerColor) + end + else + -- deal the whole deck + deck.deal(amount, playerColor) + + if deckSize < amount then + -- Norman Withers handling + if deckAreaObjects.topCard then + deckAreaObjects.topCard.deal(1, playerColor) + deckSize = deckSize + 1 + end + + -- warning message for player + if deckSize < amount then + printToColor("Deck didn't contain enough cards.", playerColor) + end + end + end + printToColor("Handle the drawn cards according to the ability text on 'Scroll of Secrets'.", playerColor) +end +end) +__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local MythosAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end + + -- returns the chaos token metadata (if provided through scenario reference card) + MythosAreaApi.returnTokenData = function() + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") + end + + -- draw an encounter card to the requested position/rotation + MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) + getMythosArea().call("drawEncounterCard", { + pos = pos, + rotY = rotY, + alwaysFaceUp = alwaysFaceUp + }) + end + + return MythosAreaApi +end +end) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 0b12ac.yaml b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 0b12ac.yaml index e4cde45c4..33e768faa 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 0b12ac.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 0b12ac.yaml @@ -31,7 +31,7 @@ HideWhenFaceDown: true IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: false -LuaScript: '' +LuaScript: !include 'Card Scroll of Secrets (3) 0b12ac.ttslua' LuaScriptState: '' MeasureMovement: false Name: Card diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 194d88.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 194d88.ttslua new file mode 100644 index 000000000..b76b9c5a5 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 194d88.ttslua @@ -0,0 +1,436 @@ +-- 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("playercards/cards/ScrollofSecrets") +end) +__bundle_register("playercards/cards/ScrollofSecrets", function(require, _LOADED, __bundle_register, __bundle_modules) +-- this script is shared between the lvl 0 and lvl 3 versions of Scroll of Secrets +local mythosAreaApi = require("core/MythosAreaApi") +local playmatApi = require("playermat/PlaymatApi") + +-- get class via metadata and create context menu accordingly +function onLoad() + local notes = JSON.decode(self.getGMNotes()) + if notes then + createContextMenu(notes.id) + else + print("Missing metadata for Scroll of Secrets!") + end +end + +function createContextMenu(id) + if id == "05116" or id == "05116-t" then + -- lvl 0: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + elseif id == "05188" or id == "05188-t" then + -- seeker lvl 3: draw 3 cards from the bottom + self.addContextMenuItem("Draw bottom card(s)", function(playerColor) contextFunc(playerColor, 3) end) + elseif id == "05189" or id == "05189-t" then + -- mystic lvl 3: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + end +end + +function contextFunc(playerColor, amount) + local options = { "Encounter Deck" } + + -- check for players with a deck and only display them as option + for _, color in ipairs(Player.getAvailableColors()) do + local matColor = playmatApi.getMatColor(color) + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + + if deckAreaObjects.draw or deckAreaObjects.topCard then + table.insert(options, color) + end + end + + -- show the target selection dialog + Player[playerColor].showOptionsDialog("Select target deck", options, _, function(owner) drawCardsFromBottom(playerColor, owner, amount) end) +end + +function drawCardsFromBottom(playerColor, owner, amount) + -- variable initialization + local deck = nil + local deckSize = 1 + local deckAreaObjects = {} + + -- get the respective deck + if owner == "Encounter Deck" then + deck = mythosAreaApi.getEncounterDeck() + else + local matColor = playmatApi.getMatColor(owner) + deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + deck = deckAreaObjects.draw + end + + -- error handling + if not deck then + printToColor("Couldn't find deck!", playerColor) + return + end + + -- set deck size if there is actually a deck and not just a card + if deck.type == "Deck" then + deckSize = #deck.getObjects() + end + + -- proceed according to deck size + if deckSize > amount then + for i = 1, amount do + local card = deck.takeObject({ top = false, flip = true }) + card.deal(1, playerColor) + end + else + -- deal the whole deck + deck.deal(amount, playerColor) + + if deckSize < amount then + -- Norman Withers handling + if deckAreaObjects.topCard then + deckAreaObjects.topCard.deal(1, playerColor) + deckSize = deckSize + 1 + end + + -- warning message for player + if deckSize < amount then + printToColor("Deck didn't contain enough cards.", playerColor) + end + end + end + printToColor("Handle the drawn cards according to the ability text on 'Scroll of Secrets'.", playerColor) +end +end) +__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local MythosAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end + + -- returns the chaos token metadata (if provided through scenario reference card) + MythosAreaApi.returnTokenData = function() + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") + end + + -- draw an encounter card to the requested position/rotation + MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) + getMythosArea().call("drawEncounterCard", { + pos = pos, + rotY = rotY, + alwaysFaceUp = alwaysFaceUp + }) + end + + return MythosAreaApi +end +end) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 194d88.yaml b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 194d88.yaml index 75071330c..b52cc0800 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 194d88.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (3) 194d88.yaml @@ -32,7 +32,7 @@ HideWhenFaceDown: true IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: false -LuaScript: '' +LuaScript: !include 'Card Scroll of Secrets (3) 194d88.ttslua' LuaScriptState: '' MeasureMovement: false Name: Card diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (Taboo) b383b8.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (Taboo) b383b8.ttslua new file mode 100644 index 000000000..eb7edf910 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (Taboo) b383b8.ttslua @@ -0,0 +1,436 @@ +-- 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/cards/ScrollofSecrets", function(require, _LOADED, __bundle_register, __bundle_modules) +-- this script is shared between the lvl 0 and lvl 3 versions of Scroll of Secrets +local mythosAreaApi = require("core/MythosAreaApi") +local playmatApi = require("playermat/PlaymatApi") + +-- get class via metadata and create context menu accordingly +function onLoad() + local notes = JSON.decode(self.getGMNotes()) + if notes then + createContextMenu(notes.id) + else + print("Missing metadata for Scroll of Secrets!") + end +end + +function createContextMenu(id) + if id == "05116" or id == "05116-t" then + -- lvl 0: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + elseif id == "05188" or id == "05188-t" then + -- seeker lvl 3: draw 3 cards from the bottom + self.addContextMenuItem("Draw bottom card(s)", function(playerColor) contextFunc(playerColor, 3) end) + elseif id == "05189" or id == "05189-t" then + -- mystic lvl 3: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + end +end + +function contextFunc(playerColor, amount) + local options = { "Encounter Deck" } + + -- check for players with a deck and only display them as option + for _, color in ipairs(Player.getAvailableColors()) do + local matColor = playmatApi.getMatColor(color) + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + + if deckAreaObjects.draw or deckAreaObjects.topCard then + table.insert(options, color) + end + end + + -- show the target selection dialog + Player[playerColor].showOptionsDialog("Select target deck", options, _, function(owner) drawCardsFromBottom(playerColor, owner, amount) end) +end + +function drawCardsFromBottom(playerColor, owner, amount) + -- variable initialization + local deck = nil + local deckSize = 1 + local deckAreaObjects = {} + + -- get the respective deck + if owner == "Encounter Deck" then + deck = mythosAreaApi.getEncounterDeck() + else + local matColor = playmatApi.getMatColor(owner) + deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + deck = deckAreaObjects.draw + end + + -- error handling + if not deck then + printToColor("Couldn't find deck!", playerColor) + return + end + + -- set deck size if there is actually a deck and not just a card + if deck.type == "Deck" then + deckSize = #deck.getObjects() + end + + -- proceed according to deck size + if deckSize > amount then + for i = 1, amount do + local card = deck.takeObject({ top = false, flip = true }) + card.deal(1, playerColor) + end + else + -- deal the whole deck + deck.deal(amount, playerColor) + + if deckSize < amount then + -- Norman Withers handling + if deckAreaObjects.topCard then + deckAreaObjects.topCard.deal(1, playerColor) + deckSize = deckSize + 1 + end + + -- warning message for player + if deckSize < amount then + printToColor("Deck didn't contain enough cards.", playerColor) + end + end + end + printToColor("Handle the drawn cards according to the ability text on 'Scroll of Secrets'.", playerColor) +end +end) +__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local MythosAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end + + -- returns the chaos token metadata (if provided through scenario reference card) + MythosAreaApi.returnTokenData = function() + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") + end + + -- draw an encounter card to the requested position/rotation + MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) + getMythosArea().call("drawEncounterCard", { + pos = pos, + rotY = rotY, + alwaysFaceUp = alwaysFaceUp + }) + end + + return MythosAreaApi +end +end) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/cards/ScrollofSecrets") +end) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (Taboo) b383b8.yaml b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (Taboo) b383b8.yaml index 6c6ed0c56..a7882ee4c 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (Taboo) b383b8.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets (Taboo) b383b8.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 @@ -31,7 +31,7 @@ HideWhenFaceDown: true IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: false -LuaScript: '' +LuaScript: !include 'Card Scroll of Secrets (Taboo) b383b8.ttslua' LuaScriptState: '' MeasureMovement: false Name: Card diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets 230835.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets 230835.ttslua new file mode 100644 index 000000000..b76b9c5a5 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets 230835.ttslua @@ -0,0 +1,436 @@ +-- 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("playercards/cards/ScrollofSecrets") +end) +__bundle_register("playercards/cards/ScrollofSecrets", function(require, _LOADED, __bundle_register, __bundle_modules) +-- this script is shared between the lvl 0 and lvl 3 versions of Scroll of Secrets +local mythosAreaApi = require("core/MythosAreaApi") +local playmatApi = require("playermat/PlaymatApi") + +-- get class via metadata and create context menu accordingly +function onLoad() + local notes = JSON.decode(self.getGMNotes()) + if notes then + createContextMenu(notes.id) + else + print("Missing metadata for Scroll of Secrets!") + end +end + +function createContextMenu(id) + if id == "05116" or id == "05116-t" then + -- lvl 0: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + elseif id == "05188" or id == "05188-t" then + -- seeker lvl 3: draw 3 cards from the bottom + self.addContextMenuItem("Draw bottom card(s)", function(playerColor) contextFunc(playerColor, 3) end) + elseif id == "05189" or id == "05189-t" then + -- mystic lvl 3: draw 1 card from the bottom + self.addContextMenuItem("Draw bottom card", function(playerColor) contextFunc(playerColor, 1) end) + end +end + +function contextFunc(playerColor, amount) + local options = { "Encounter Deck" } + + -- check for players with a deck and only display them as option + for _, color in ipairs(Player.getAvailableColors()) do + local matColor = playmatApi.getMatColor(color) + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + + if deckAreaObjects.draw or deckAreaObjects.topCard then + table.insert(options, color) + end + end + + -- show the target selection dialog + Player[playerColor].showOptionsDialog("Select target deck", options, _, function(owner) drawCardsFromBottom(playerColor, owner, amount) end) +end + +function drawCardsFromBottom(playerColor, owner, amount) + -- variable initialization + local deck = nil + local deckSize = 1 + local deckAreaObjects = {} + + -- get the respective deck + if owner == "Encounter Deck" then + deck = mythosAreaApi.getEncounterDeck() + else + local matColor = playmatApi.getMatColor(owner) + deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + deck = deckAreaObjects.draw + end + + -- error handling + if not deck then + printToColor("Couldn't find deck!", playerColor) + return + end + + -- set deck size if there is actually a deck and not just a card + if deck.type == "Deck" then + deckSize = #deck.getObjects() + end + + -- proceed according to deck size + if deckSize > amount then + for i = 1, amount do + local card = deck.takeObject({ top = false, flip = true }) + card.deal(1, playerColor) + end + else + -- deal the whole deck + deck.deal(amount, playerColor) + + if deckSize < amount then + -- Norman Withers handling + if deckAreaObjects.topCard then + deckAreaObjects.topCard.deal(1, playerColor) + deckSize = deckSize + 1 + end + + -- warning message for player + if deckSize < amount then + printToColor("Deck didn't contain enough cards.", playerColor) + end + end + end + printToColor("Handle the drawn cards according to the ability text on 'Scroll of Secrets'.", playerColor) +end +end) +__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local MythosAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end + + -- returns the chaos token metadata (if provided through scenario reference card) + MythosAreaApi.returnTokenData = function() + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") + end + + -- draw an encounter card to the requested position/rotation + MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) + getMythosArea().call("drawEncounterCard", { + pos = pos, + rotY = rotY, + alwaysFaceUp = alwaysFaceUp + }) + end + + return MythosAreaApi +end +end) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets 230835.yaml b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets 230835.yaml index 4408c5e4c..6e751c240 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets 230835.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Scroll of Secrets 230835.yaml @@ -31,7 +31,7 @@ HideWhenFaceDown: true IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: false -LuaScript: '' +LuaScript: !include 'Card Scroll of Secrets 230835.ttslua' LuaScriptState: '' MeasureMovement: false Name: Card diff --git a/unpacked/Bag All Player Cards 15bb07/Card Seal of the Seventh Sign (5) 9cbac1.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Seal of the Seventh Sign (5) 9cbac1.ttslua index c5eb8367d..d42ba11aa 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Seal of the Seventh Sign (5) 9cbac1.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Seal of the Seventh Sign (5) 9cbac1.ttslua @@ -41,6 +41,16 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/cards/SealoftheSeventhSign5") +end) +__bundle_register("playercards/cards/SealoftheSeventhSign5", function(require, _LOADED, __bundle_register, __bundle_modules) +VALID_TOKENS = { + ["Auto-fail"] = true +} + +require("playercards/CardsThatSealTokens") +end) __bundle_register("playercards/CardsThatSealTokens", function(require, _LOADED, __bundle_register, __bundle_modules) --[[ Library for cards that seal tokens This file is used to add sealing option to cards' context menu. @@ -272,12 +282,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -305,11 +316,15 @@ end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -317,30 +332,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -422,14 +437,34 @@ do return ChaosBagApi end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/cards/SealoftheSeventhSign5") -end) -__bundle_register("playercards/cards/SealoftheSeventhSign5", function(require, _LOADED, __bundle_register, __bundle_modules) -VALID_TOKENS = { - ["Auto-fail"] = true -} +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local GUIDReferenceApi = {} -require("playercards/CardsThatSealTokens") + 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Serpents of Yig 678391.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Serpents of Yig 678391.ttslua index 2bb48902f..e4aa75a29 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Serpents of Yig 678391.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Serpents of Yig 678391.ttslua @@ -41,126 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi -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.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("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/SerpentsofYig") end) @@ -402,12 +282,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -432,4 +313,158 @@ do return TokenArrangerApi end end) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +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.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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Shards of the Void (3) b10a71.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Shards of the Void (3) b10a71.ttslua index 9eb2692ab..270cea590 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Shards of the Void (3) b10a71.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Shards of the Void (3) b10a71.ttslua @@ -284,12 +284,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -317,11 +318,15 @@ end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -329,30 +334,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -434,4 +439,34 @@ do 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Sharpshooter (3) (Taboo) 77b1e7.yaml b/unpacked/Bag All Player Cards 15bb07/Card Sharpshooter (3) (Taboo) 77b1e7.yaml index 3073ef1a5..87e64dc57 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Sharpshooter (3) (Taboo) 77b1e7.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Sharpshooter (3) (Taboo) 77b1e7.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Shed a Light (Taboo) 44292c.yaml b/unpacked/Bag All Player Cards 15bb07/Card Shed a Light (Taboo) 44292c.yaml index b44f2587a..f3429c584 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Shed a Light (Taboo) 44292c.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Shed a Light (Taboo) 44292c.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Shield of Faith (2) 06abe0.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Shield of Faith (2) 06abe0.ttslua index 063e2e883..e8fc135b9 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Shield of Faith (2) 06abe0.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Shield of Faith (2) 06abe0.ttslua @@ -41,6 +41,112 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/cards/ShieldofFaith2") end) @@ -285,12 +391,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -318,11 +425,15 @@ end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -330,109 +441,33 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi 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.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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Short Supply e5f541.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Short Supply e5f541.ttslua index e18b54253..f12f969b7 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Short Supply e5f541.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Short Supply e5f541.ttslua @@ -41,8 +41,11 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/cards/ShortSupply") +end) __bundle_register("playercards/cards/ShortSupply", function(require, _LOADED, __bundle_register, __bundle_modules) -local playmatAPI = require("playermat/PlaymatApi") +local playmatApi = require("playermat/PlaymatApi") function onLoad() self.addContextMenuItem("Discard 10 cards", shortSupply) @@ -50,11 +53,12 @@ end -- called by context menu entry function shortSupply(color) - local matColor = playmatAPI.getMatColorByPosition(self.getPosition()) + local matColor = playmatApi.getMatColorByPosition(self.getPosition()) -- get draw deck and discard position - local drawDeck = playmatAPI.getDrawDeck(matColor) - local discardPos = playmatAPI.getDiscardPosition(matColor) + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + local drawDeck = deckAreaObjects.draw + local discardPos = playmatApi.getDiscardPosition(matColor) -- error handling if discardPos == nil then @@ -65,7 +69,7 @@ function shortSupply(color) if drawDeck == nil then broadcastToColor("Deck not found!", color, "Yellow") return - elseif drawDeck.tag ~= "Deck" then + elseif drawDeck.type ~= "Deck" then broadcastToColor("Deck only contains a single card!", color, "Yellow") return end @@ -79,232 +83,263 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/cards/ShortSupply") +__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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Signum Crucis (2) (Taboo) 750b7a.yaml b/unpacked/Bag All Player Cards 15bb07/Card Signum Crucis (2) (Taboo) 750b7a.yaml index 0f52614a1..f8366b64f 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Signum Crucis (2) (Taboo) 750b7a.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Signum Crucis (2) (Taboo) 750b7a.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Sleight of Hand (Taboo) 0d84b2.yaml b/unpacked/Bag All Player Cards 15bb07/Card Sleight of Hand (Taboo) 0d84b2.yaml index 269be8bd9..353b99df7 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Sleight of Hand (Taboo) 0d84b2.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Sleight of Hand (Taboo) 0d84b2.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Smite the Wicked 58f535.yaml b/unpacked/Bag All Player Cards 15bb07/Card Smite the Wicked 58f535.yaml new file mode 100644 index 000000000..e7e508b51 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Smite the Wicked 58f535.yaml @@ -0,0 +1,54 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 853101 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8531': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115062479282090841/27F874D8E240CE62A38A47DDFAAF58D3BD4D0C42/ + NumHeight: 2 + NumWidth: 2 + Type: 0 + UniqueBack: false +Description: Advanced +DragSelectable: true +GMNotes: "{\n \"id\": \"90061\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n + \ \"traits\": \"Task.\",\n \"weakness\": true,\n \"cycle\": \"Path of the Righteous\"\n}" +GUID: 58f535 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Smite the Wicked +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 9.01 + posY: 3.99 + posZ: -16.7 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Springfield M1903 (4) (Taboo) 23f8ec.yaml b/unpacked/Bag All Player Cards 15bb07/Card Springfield M1903 (4) (Taboo) 23f8ec.yaml index d6e601fe7..ea6cbc3fc 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Springfield M1903 (4) (Taboo) 23f8ec.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Springfield M1903 (4) (Taboo) 23f8ec.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Strange Solution (4) (Taboo) 1be7f1.yaml b/unpacked/Bag All Player Cards 15bb07/Card Strange Solution (4) (Taboo) 1be7f1.yaml index cf3139cbc..c2efff002 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Strange Solution (4) (Taboo) 1be7f1.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Strange Solution (4) (Taboo) 1be7f1.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Telescopic Sight (3) (Taboo) 43cb9f.yaml b/unpacked/Bag All Player Cards 15bb07/Card Telescopic Sight (3) (Taboo) 43cb9f.yaml index ad6f025d6..313a0ccc5 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Telescopic Sight (3) (Taboo) 43cb9f.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Telescopic Sight (3) (Taboo) 43cb9f.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card The Chthonian Stone (3) a775ad.ttslua b/unpacked/Bag All Player Cards 15bb07/Card The Chthonian Stone (3) a775ad.ttslua index e44dbba99..73e6a14f4 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card The Chthonian Stone (3) a775ad.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card The Chthonian Stone (3) a775ad.ttslua @@ -285,12 +285,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -318,11 +319,15 @@ end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -330,30 +335,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -435,4 +440,34 @@ do 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card The Chthonian Stone fc4ce8.ttslua b/unpacked/Bag All Player Cards 15bb07/Card The Chthonian Stone fc4ce8.ttslua index 3d9b5aa98..b6620696b 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card The Chthonian Stone fc4ce8.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card The Chthonian Stone fc4ce8.ttslua @@ -285,12 +285,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -318,11 +319,15 @@ end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -330,30 +335,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -435,4 +440,34 @@ do 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card The Codex of Ages df9809.ttslua b/unpacked/Bag All Player Cards 15bb07/Card The Codex of Ages df9809.ttslua index a0db05d36..891156efe 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card The Codex of Ages df9809.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card The Codex of Ages df9809.ttslua @@ -41,157 +41,34 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local TokenArrangerApi = {} + local 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 Variant Parameter to pass - local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] - if tokenArranger ~= nil then - tokenArranger.call(functionName, argument) - end + local function getGuidHandler() + return getObjectFromGUID("123456") end - -- updates the token modifiers with the provided data - ---@param tokenData Table Contains the chaos token metadata - TokenArrangerApi.onTokenDataChanged = function(fullData) - callIfExistent("onTokenDataChanged", fullData) + -- 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 - -- deletes already laid out tokens - TokenArrangerApi.deleteCopiedTokens = function() - callIfExistent("deleteCopiedTokens") + -- 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 - -- updates the laid out tokens - TokenArrangerApi.layout = function() - Wait.time(function() callIfExistent("layout") end, 0.1) + -- 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 TokenArrangerApi -end -end) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi -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.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 + return GUIDReferenceApi end end) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) @@ -432,4 +309,162 @@ function putTokenAway(guid) end end end) +__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 Variant 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 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) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +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.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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card The Necronomicon (5) (Taboo) 4b7a8e.yaml b/unpacked/Bag All Player Cards 15bb07/Card The Necronomicon (5) (Taboo) 4b7a8e.yaml index 76002f99d..c09b0aa0a 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card The Necronomicon (5) (Taboo) 4b7a8e.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card The Necronomicon (5) (Taboo) 4b7a8e.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Three Aces (1) (Taboo) baa553.yaml b/unpacked/Bag All Player Cards 15bb07/Card Three Aces (1) (Taboo) baa553.yaml index af38cb68d..be6fad121 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Three Aces (1) (Taboo) baa553.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Three Aces (1) (Taboo) baa553.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Uncanny Growth 6543e6.yaml b/unpacked/Bag All Player Cards 15bb07/Card Uncanny Growth 6543e6.yaml index 3ab488b06..ee5a55e9c 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Uncanny Growth 6543e6.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Uncanny Growth 6543e6.yaml @@ -20,8 +20,8 @@ CustomDeck: Description: '' DragSelectable: true GMNotes: "{\n \"id\": \"10045\",\n \"type\": \"Event\",\n \"class\": \"Seeker\",\n - \ \"cost\": 1,\n \"level\": 0,\n \"traits\": \"Insight. Science.\",\n \"cycle\": - \"The Feast of Hemlock Vale\"\n}" + \ \"cost\": 1,\n \"traits\": \"Insight. Science.\",\n \"cycle\": \"The Feast of + Hemlock Vale\"\n}" GUID: 6543e6 Grid: true GridProjection: false diff --git a/unpacked/Bag All Player Cards 15bb07/Card Unrelenting (1) 45386d.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Unrelenting (1) 45386d.ttslua index 1f7cb75c8..15c0319d3 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Unrelenting (1) 45386d.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Unrelenting (1) 45386d.ttslua @@ -286,12 +286,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -319,11 +320,15 @@ end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -331,30 +336,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -436,4 +441,34 @@ do 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Vengeful Shade 73bc8e.yaml b/unpacked/Bag All Player Cards 15bb07/Card Vengeful Shade 73bc8e.yaml new file mode 100644 index 000000000..c9081f196 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Vengeful Shade 73bc8e.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 847002 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8470': + BackIsHidden: false + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2149964195986880793/517FBB4FF8F72900B9E123DB865BCAD625F6506C/ + NumHeight: 2 + NumWidth: 2 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"90053\",\n \"type\": \"Enemy\",\n \"class\": \"Neutral\",\n + \ \"traits\": \"Monster. Geist\",\n \"weakness\": true,\n \"cycle\": \"Laid to + Rest\"\n}" +GUID: 73bc8e +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Vengeful Shade +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 78.45 + posY: 3.19 + posZ: 20.55 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Voice of Ra (Taboo) b06042.yaml b/unpacked/Bag All Player Cards 15bb07/Card Voice of Ra (Taboo) b06042.yaml index 49de10cf0..e3b1e8518 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Voice of Ra (Taboo) b06042.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Voice of Ra (Taboo) b06042.yaml @@ -12,7 +12,7 @@ CustomDeck: '3': BackIsHidden: true BackURL: https://i.imgur.com/EcbhVuh.jpg/ - FaceURL: http://cloud-3.steamusercontent.com/ugc/2021607899142908284/92DF67E4310BCDFAD6C4BB12D31155DBF6B07A25/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115061845812962486/A68B8BF7E4862F21369DAC4A37D813EC664EAC34/ NumHeight: 6 NumWidth: 10 Type: 0 diff --git a/unpacked/Bag All Player Cards 15bb07/Card Well Connected (3) 170127.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Well Connected (3) 170127.ttslua index 574b1391f..1222a8ab8 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Well Connected (3) 170127.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Well Connected (3) 170127.ttslua @@ -41,308 +41,323 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/cards/WellConnected") -end) __bundle_register("playercards/cards/WellConnected", function(require, _LOADED, __bundle_register, __bundle_modules) -- this script is shared between both the level 0 and the upgraded level 3 version of the card local playmatApi = require("playermat/PlaymatApi") -local display = false -local count = 0 -local modValue = 5 -- level 0 Well Connected -local loopId = nil - -local b_display = { - click_function = "toggleCounter", - function_owner = self, - position = {0.88,0.5,-1.33}, - font_size = 150, - width = 175, - height = 175 +local modValue, loopId +local buttonParameters = { + click_function = "toggleCounter", + tooltip = "disable counter", + function_owner = self, + position = { 0.88, 0.5, -1.33 }, + font_size = 150, + width = 175, + height = 175 } -function onLoad(saved_data) - local notes = JSON.decode(self.getGMNotes()) +function onSave() return JSON.encode({ loopId = loopId }) end - if notes.id == "54006" then -- hardcoded card id for upgraded Well Connected (3) - modValue = 4 -- Well Connected (3) +function onLoad(savedData) + -- use metadata to detect level and adjust modValue accordingly + if JSON.decode(self.getGMNotes()).level == 0 then + modValue = 5 + else + modValue = 4 + end + + if savedData ~= "" then + local loadedData = JSON.decode(savedData) + if loadedData.loopId then + self.createButton(buttonParameters) + loopId = Wait.time(updateDisplay, 2, -1) end + end - if saved_data != '' then - local loaded_data = JSON.decode(saved_data) - display = not loaded_data.saved_display - - self.clearButtons() - toggleCounter() - end - - self.addContextMenuItem('Toggle Counter', toggleCounter) -end - -function onSave() - return JSON.encode({saved_display = display}) + self.addContextMenuItem("Toggle Counter", toggleCounter) end function toggleCounter() - display = not display - - if display then - createUpdateDisplay() - loopId = Wait.time(|| createUpdateDisplay(), 2, -1) - else - if loopId ~= nil then - Wait.stop(loopId) - end - - self.clearButtons() - loopId = nil - end + if loopId ~= nil then + Wait.stop(loopId) + loopId = nil + self.clearButtons() + else + self.createButton(buttonParameters) + updateDisplay() + loopId = Wait.time(updateDisplay, 2, -1) + end end -function createUpdateDisplay() - count = math.max(math.floor(getPlayerResources() / modValue), 0) - - b_display.label = tostring(count) - - if loopId == nil then - self.createButton(b_display) - else - self.editButton(b_display) - end -end - -function getPlayerResources() - local matColor = playmatApi.getMatColorByPosition(self.getPosition()) - - return playmatApi.getResourceCount(matColor) +function updateDisplay() + local matColor = playmatApi.getMatColorByPosition(self.getPosition()) + local resources = playmatApi.getCounterValue(matColor, "ResourceCounter") + local count = tostring(math.floor(resources / modValue)) + self.editButton({ index = 0, label = count }) end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/cards/WellConnected") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Well Connected 66b7d5.ttslua b/unpacked/Bag All Player Cards 15bb07/Card Well Connected 66b7d5.ttslua index 574b1391f..63f6a9df6 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Well Connected 66b7d5.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/Card Well Connected 66b7d5.ttslua @@ -48,301 +48,316 @@ __bundle_register("playercards/cards/WellConnected", function(require, _LOADED, -- this script is shared between both the level 0 and the upgraded level 3 version of the card local playmatApi = require("playermat/PlaymatApi") -local display = false -local count = 0 -local modValue = 5 -- level 0 Well Connected -local loopId = nil - -local b_display = { - click_function = "toggleCounter", - function_owner = self, - position = {0.88,0.5,-1.33}, - font_size = 150, - width = 175, - height = 175 +local modValue, loopId +local buttonParameters = { + click_function = "toggleCounter", + tooltip = "disable counter", + function_owner = self, + position = { 0.88, 0.5, -1.33 }, + font_size = 150, + width = 175, + height = 175 } -function onLoad(saved_data) - local notes = JSON.decode(self.getGMNotes()) +function onSave() return JSON.encode({ loopId = loopId }) end - if notes.id == "54006" then -- hardcoded card id for upgraded Well Connected (3) - modValue = 4 -- Well Connected (3) +function onLoad(savedData) + -- use metadata to detect level and adjust modValue accordingly + if JSON.decode(self.getGMNotes()).level == 0 then + modValue = 5 + else + modValue = 4 + end + + if savedData ~= "" then + local loadedData = JSON.decode(savedData) + if loadedData.loopId then + self.createButton(buttonParameters) + loopId = Wait.time(updateDisplay, 2, -1) end + end - if saved_data != '' then - local loaded_data = JSON.decode(saved_data) - display = not loaded_data.saved_display - - self.clearButtons() - toggleCounter() - end - - self.addContextMenuItem('Toggle Counter', toggleCounter) -end - -function onSave() - return JSON.encode({saved_display = display}) + self.addContextMenuItem("Toggle Counter", toggleCounter) end function toggleCounter() - display = not display - - if display then - createUpdateDisplay() - loopId = Wait.time(|| createUpdateDisplay(), 2, -1) - else - if loopId ~= nil then - Wait.stop(loopId) - end - - self.clearButtons() - loopId = nil - end + if loopId ~= nil then + Wait.stop(loopId) + loopId = nil + self.clearButtons() + else + self.createButton(buttonParameters) + updateDisplay() + loopId = Wait.time(updateDisplay, 2, -1) + end end -function createUpdateDisplay() - count = math.max(math.floor(getPlayerResources() / modValue), 0) - - b_display.label = tostring(count) - - if loopId == nil then - self.createButton(b_display) - else - self.editButton(b_display) - end -end - -function getPlayerResources() - local matColor = playmatApi.getMatColorByPosition(self.getPosition()) - - return playmatApi.getResourceCount(matColor) +function updateDisplay() + local matColor = playmatApi.getMatColorByPosition(self.getPosition()) + local resources = playmatApi.getCounterValue(matColor, "ResourceCounter") + local count = tostring(math.floor(resources / modValue)) + self.editButton({ index = 0, label = count }) end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/Card Wendy Adams (Parallel Front) 61503e.yaml b/unpacked/Bag All Player Cards 15bb07/Card Wendy Adams (Parallel Front) 61503e.yaml index aa36967fa..5528dfce9 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Wendy Adams (Parallel Front) 61503e.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Wendy Adams (Parallel Front) 61503e.yaml @@ -19,9 +19,10 @@ CustomDeck: UniqueBack: true Description: The Urchin DragSelectable: true -GMNotes: "{\r\n \"id\": \"01005-pf\",\r\n \"type\": \"Investigator\",\r\n \"class\": - \"Survivor\",\r\n \"traits\": \"Drifter.\",\r\n \"willpowerIcons\": 4,\r\n \"intellectIcons\": - 3,\r\n \"combatIcons\": 1,\r\n \"agilityIcons\": 4,\r\n \"cycle\": \"Core\"\r\n}\r" +GMNotes: "{\n \"id\": \"01005-pf\",\n \"type\": \"Investigator\",\n \"class\": + \"Survivor\",\n \"traits\": \"Drifter. Blessed. Cursed.\",\n \"willpowerIcons\": + 4,\n \"intellectIcons\": 3,\n \"combatIcons\": 1,\n \"agilityIcons\": 4,\n \"cycle\": + \"Core\"\n}" GUID: 61503e Grid: true GridProjection: false diff --git a/unpacked/Bag All Player Cards 15bb07/Card Wendy Adams (Parallel) fd91ea.yaml b/unpacked/Bag All Player Cards 15bb07/Card Wendy Adams (Parallel) fd91ea.yaml index e0800e721..630f0c0e2 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Wendy Adams (Parallel) fd91ea.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Wendy Adams (Parallel) fd91ea.yaml @@ -19,9 +19,9 @@ CustomDeck: UniqueBack: true Description: The Urchin DragSelectable: true -GMNotes: "{\r\n \"id\": \"01005-p\",\r\n \"type\": \"Investigator\",\r\n \"class\": - \"Survivor\",\r\n \"traits\": \"Drifter.\",\r\n \"willpowerIcons\": 4,\r\n \"intellectIcons\": - 3,\r\n \"combatIcons\": 1,\r\n \"agilityIcons\": 4,\r\n \"cycle\": \"Core\"\r\n}\r" +GMNotes: "{\n \"id\": \"01005-p\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n + \ \"traits\": \"Drifter. Blessed. Cursed.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": + 3,\n \"combatIcons\": 1,\n \"agilityIcons\": 4,\n \"cycle\": \"Core\"\n}" GUID: fd91ea Grid: true GridProjection: false diff --git a/unpacked/Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel Back) 98a0e4.yaml b/unpacked/Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel Back) 98a0e4.yaml new file mode 100644 index 000000000..1e5e56491 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel Back) 98a0e4.yaml @@ -0,0 +1,57 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 773502 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '7735': + BackIsHidden: true + BackURL: http://cloud-3.steamusercontent.com/ugc/2115062479282091065/71F159724883E9587669DB96B16A5E047DA5B6FA/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/1656727981627737050/3CFF9E3825033909543AD1CF843361D9243538EE/ + NumHeight: 2 + NumWidth: 4 + Type: 0 + UniqueBack: true +Description: The Chef +DragSelectable: true +GMNotes: "{\n \"id\": \"02001-pb\",\n \"type\": \"Investigator\",\n \"class\": + \"Guardian\",\n \"traits\": \"Believer. Hunter.\",\n \"willpowerIcons\": 4,\n + \ \"intellectIcons\": 2,\n \"combatIcons\": 4,\n \"agilityIcons\": 2,\n \"cycle\": + \"Path of the Righteous\"\n}" +GUID: 98a0e4 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Zoey Samaras (Parallel Back) +SidewaysCard: true +Snap: true +Sticky: true +Tags: +- Investigator +- PlayerCard +Tooltip: true +Transform: + posX: 18.45 + posY: 1.59 + posZ: -73.09 + rotX: 0 + rotY: 180 + rotZ: 0 + scaleX: 1.15 + scaleY: 1 + scaleZ: 1.15 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel Front) 98a0e3.yaml b/unpacked/Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel Front) 98a0e3.yaml new file mode 100644 index 000000000..55e30d91d --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel Front) 98a0e3.yaml @@ -0,0 +1,57 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 773602 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '7736': + BackIsHidden: true + BackURL: http://cloud-3.steamusercontent.com/ugc/1656727981627737648/F371339538812F68E38AAC0D520C525250DAC5C0/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115062479282091273/DA3424FFAA9F826D8DCD2F3AB75C220309C5101F/ + NumHeight: 2 + NumWidth: 4 + Type: 0 + UniqueBack: true +Description: The Chef +DragSelectable: true +GMNotes: "{\n \"id\": \"02001-pf\",\n \"type\": \"Investigator\",\n \"class\": + \"Guardian\",\n \"traits\": \"Believer. Hunter.\",\n \"willpowerIcons\": 4,\n + \ \"intellectIcons\": 2,\n \"combatIcons\": 4,\n \"agilityIcons\": 2,\n \"cycle\": + \"Path of the Righteous\"\n}" +GUID: 98a0e3 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Zoey Samaras (Parallel Front) +SidewaysCard: true +Snap: true +Sticky: true +Tags: +- Investigator +- PlayerCard +Tooltip: true +Transform: + posX: 18.45 + posY: 1.59 + posZ: -73.09 + rotX: 0 + rotY: 180 + rotZ: 0 + scaleX: 1.15 + scaleY: 1 + scaleZ: 1.15 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel) 98a0e2.yaml b/unpacked/Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel) 98a0e2.yaml new file mode 100644 index 000000000..1bf816447 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Zoey Samaras (Parallel) 98a0e2.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 773402 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '7734': + BackIsHidden: true + BackURL: http://cloud-3.steamusercontent.com/ugc/2115062479282091065/71F159724883E9587669DB96B16A5E047DA5B6FA/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115062479282091273/DA3424FFAA9F826D8DCD2F3AB75C220309C5101F/ + NumHeight: 2 + NumWidth: 4 + Type: 0 + UniqueBack: true +Description: The Chef +DragSelectable: true +GMNotes: "{\n \"id\": \"02001-p\",\n \"type\": \"Investigator\",\n \"class\": \"Guardian\",\n + \ \"traits\": \"Believer. Hunter.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": + 2,\n \"combatIcons\": 4,\n \"agilityIcons\": 2,\n \"cycle\": \"Path of the Righteous\"\n}" +GUID: 98a0e2 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Zoey Samaras (Parallel) +SidewaysCard: true +Snap: true +Sticky: true +Tags: +- Investigator +- PlayerCard +Tooltip: true +Transform: + posX: 18.45 + posY: 1.59 + posZ: -73.09 + rotX: 0 + rotY: 180 + rotZ: 0 + scaleX: 1.15 + scaleY: 1 + scaleZ: 1.15 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/Card Zoey's Cross 66d810.yaml b/unpacked/Bag All Player Cards 15bb07/Card Zoey's Cross 66d810.yaml index 3afedc783..8123ee0c2 100644 --- a/unpacked/Bag All Player Cards 15bb07/Card Zoey's Cross 66d810.yaml +++ b/unpacked/Bag All Player Cards 15bb07/Card Zoey's Cross 66d810.yaml @@ -17,7 +17,7 @@ CustomDeck: NumWidth: 10 Type: 0 UniqueBack: false -Description: '' +Description: Symbol of Righteousness DragSelectable: true GMNotes: "{\r\n \"id\": \"02006\",\r\n \"type\": \"Asset\",\r\n \"class\": \"Neutral\",\r\n \ \"cost\": 1,\r\n \"traits\": \"Item. Charm.\",\r\n \"combatIcons\": 2,\r\n \"wildIcons\": diff --git a/unpacked/Bag All Player Cards 15bb07/Card Zoey's Cross 66d811.yaml b/unpacked/Bag All Player Cards 15bb07/Card Zoey's Cross 66d811.yaml new file mode 100644 index 000000000..8969989a6 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/Card Zoey's Cross 66d811.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 853100 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8531': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2115062479282090841/27F874D8E240CE62A38A47DDFAAF58D3BD4D0C42/ + NumHeight: 2 + NumWidth: 2 + Type: 0 + UniqueBack: false +Description: Symbol of Conviction (Advanced) +DragSelectable: true +GMNotes: "{\n \"id\": \"90060\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n + \ \"cost\": 1,\n \"traits\": \"Item. Charm.\",\n \"combatIcons\": 2,\n \"wildIcons\": + 1,\n \"cycle\": \"Path of the Righteous\"\n}" +GUID: 66d811 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Card +Nickname: Zoey's Cross +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 8.97 + posY: 4.11 + posZ: -16.69 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Accursed e91c5e.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Accursed e91c5e.yaml new file mode 100644 index 000000000..b5d0638f1 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Accursed e91c5e.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 100 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '1': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009070977509/27A8CCF2BC48CAD909180D64177E86B8232F66C6/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10095\",\n \"type\": \"Skill\",\n \"class\": \"Mystic\",\n + \ \"level\": 0,\n \"traits\": \"Innate. Cursed.\",\n \"wildIcons\": 1,\n \"cycle\": + \"The Feast of Hemlock Vale\"\n}" +GUID: e91c5e +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Accursed +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: 6.5 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Ad Hoc c9fb2f.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Ad Hoc c9fb2f.yaml new file mode 100644 index 000000000..281da8670 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Ad Hoc c9fb2f.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 9100 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '91': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2223150865961116295/72473371D0DB68709B4B1B9343A748510A1BB30A/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10002\",\n \"type\": \"Event\",\n \"class\": \"Neutral\",\n + \ \"cost\": 2,\n \"traits\": \"Improvised. Upgrade.\",\n \"wildIcons\": 2,\n \"cycle\": + \"The Feast of Hemlock Vale\"\n}" +GUID: c9fb2f +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Ad Hoc +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: -7.16 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Alchemical Distillation Upgrade Sheet 156166.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Alchemical Distillation Upgrade Sheet 156166.ttslua index 7005e02b7..50d9657f8 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Alchemical Distillation Upgrade Sheet 156166.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Alchemical Distillation Upgrade Sheet 156166.ttslua @@ -551,229 +551,263 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Alessandra Zorzi 54eaa5.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Alessandra Zorzi 54eaa5.yaml new file mode 100644 index 000000000..714537ff8 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Alessandra Zorzi 54eaa5.yaml @@ -0,0 +1,57 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 1100 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '11': + BackIsHidden: true + BackURL: http://cloud-3.steamusercontent.com/ugc/2172484009071330094/3AEFB558D789BC525F50DCC0217FA17627EB91BF/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009071330266/6DD06B74E6DD4F473AB47C39DD17DF9FAD8B1455/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: The Countess +DragSelectable: true +GMNotes: "{\n \"id\": \"10009\",\n \"type\": \"Investigator\",\n \"class\": \"Rogue\",\n + \ \"traits\": \"Drifter. Socialite.\",\n \"willpowerIcons\": 3,\n \"intellectIcons\": + 4,\n \"combatIcons\": 2,\n \"agilityIcons\": 4,\n \"cycle\": \"The Feast of Hemlock + Vale\"\n}" +GUID: 54eaa5 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Alessandra Zorzi +SidewaysCard: true +Snap: true +Sticky: true +Tags: +- Investigator +- PlayerCard +Tooltip: true +Transform: + posX: 9.23 + posY: 3.55 + posZ: 2.42 + rotX: 0 + rotY: 180 + rotZ: 0 + scaleX: 1.15 + scaleY: 1 + scaleZ: 1.15 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Alessandra Zorzi cea425.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Alessandra Zorzi cea425.yaml new file mode 100644 index 000000000..ede5698a5 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Alessandra Zorzi cea425.yaml @@ -0,0 +1,53 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 847400 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8474': + BackIsHidden: true + BackURL: http://cloud-3.steamusercontent.com/ugc/2172484009071330401/BD2BC1B3E8367C3EFE3AEB90170E46F1C617BBFC/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009071330650/87864D232E414AF361F6559398AE0C3F40E02760/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10009-m\",\n \"type\": \"Minicard\"\n}" +GUID: cea425 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Alessandra Zorzi +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Minicard +Tooltip: true +Transform: + posX: 5.76 + posY: 3.65 + posZ: 15.39 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 0.6 + scaleY: 1 + scaleZ: 0.6 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Beguile 019526.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Beguile 019526.yaml new file mode 100644 index 000000000..7d8b79289 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Beguile 019526.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 200 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '2': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009071331078/3553DC91D67F802BAFFE9F674DBE991C2D439867/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10010\",\n \"type\": \"Event\",\n \"class\": \"Neutral\",\n + \ \"cost\": 2,\n \"traits\": \"Trick.\",\n \"wildIcons\": 1,\n \"cycle\": \"The + Feast of Hemlock Vale\"\n}" +GUID: 019526 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Beguile +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 9.32 + posY: 3.55 + posZ: -0.84 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Blackmail File de456d.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Blackmail File de456d.yaml new file mode 100644 index 000000000..7de6b8b3d --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Blackmail File de456d.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 9400 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '94': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2195002645128569861/7143A7BF20E37A069E170A21D77C16C91D81374D/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10064\",\n \"type\": \"Asset\",\n \"class\": \"Rogue\",\n + \ \"cost\": 2,\n \"level\": 0,\n \"traits\": \"Item. Tome. Illicit.\",\n \"willpowerIcons\": + 1,\n \"cycle\": \"The Feast of Hemlock Vale\"\n}" +GUID: de456d +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Blackmail File +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: -7.16 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Control Variable 133868.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Control Variable 133868.yaml new file mode 100644 index 000000000..5b59466d9 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Control Variable 133868.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 300 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '3': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009070977979/A629DD5733453F892F57514EC5950E087486896F/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10046\",\n \"type\": \"Event\",\n \"class\": \"Seeker\",\n + \ \"cost\": 1,\n \"level\": 0,\n \"traits\": \"Insight. Science. Cursed.\",\n + \ \"willpowerIcons\": 1,\n \"intellectIcons\": 1,\n \"cycle\": \"The Feast of + Hemlock Vale\"\n}" +GUID: '133868' +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Control Variable +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: 4.22 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Custom Modifications Upgrade Sheet 4104bf.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Custom Modifications Upgrade Sheet 4104bf.ttslua index 7a2b0afa0..47a789f3c 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Custom Modifications Upgrade Sheet 4104bf.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Custom Modifications Upgrade Sheet 4104bf.ttslua @@ -41,9 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/customizable/CustomModificationsUpgradeSheet") -end) __bundle_register("playercards/customizable/CustomModificationsUpgradeSheet", function(require, _LOADED, __bundle_register, __bundle_modules) -- Customizable Cards: Custom Modifications @@ -545,229 +542,266 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/customizable/CustomModificationsUpgradeSheet") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Damning Testimony Upgrade Sheet dc4a62.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Damning Testimony Upgrade Sheet dc4a62.ttslua index 1bdb9a27a..e92e04dc1 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Damning Testimony Upgrade Sheet dc4a62.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Damning Testimony Upgrade Sheet dc4a62.ttslua @@ -41,231 +41,34 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local GUIDReferenceApi = {} - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end + local function getGuidHandler() + return getObjectFromGUID("123456") end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") + -- 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 the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" + -- 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 the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") + -- 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 - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi + return GUIDReferenceApi end end) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) @@ -769,4 +572,235 @@ function maybeUpdateServitorSlotDisplay() }) end end) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +end +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Devil 2a0ba5.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Devil 2a0ba5.yaml new file mode 100644 index 000000000..41506f9e0 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Devil 2a0ba5.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 400 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '4': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009070978111/18BFD42CF7BACCF65559E63F576AF35920520FDB/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: Friend or Foe? +DragSelectable: true +GMNotes: "{\n \"id\": \"10119\",\n \"type\": \"Asset\",\n \"class\": \"Survivor\",\n + \ \"cost\": 1,\n \"level\": 2,\n \"traits\": \"Ally. Creature. Cursed.\",\n \"agilityIcons\": + 1,\n \"cycle\": \"The Feast of Hemlock Vale\"\n}" +GUID: 2a0ba5 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: '"Devil"' +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: -9.43 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Eldritch Tongue e8765a.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Eldritch Tongue e8765a.yaml new file mode 100644 index 000000000..2c05b644f --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Eldritch Tongue e8765a.yaml @@ -0,0 +1,57 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 100 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '1': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009099794816/E5700422279C3B3100E11698F95F7FF2403C6362/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10128\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n + \ \"cost\": 2,\n \"level\": 0,\n \"traits\": \"Ritual.\",\n \"willpowerIcons\": + 1,\n \"uses\": [\n {\n \"count\": 4,\n \"type\": \"Charge\",\n \"token\": + \"resource\"\n }\n ],\n \"cycle\": \"The Feast of Hemlock Vale\"\n}" +GUID: e8765a +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Eldritch Tongue +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 13 + posY: 3.5 + posZ: 6 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Empirical Hypothesis Upgrade Sheet 0c46a7.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Empirical Hypothesis Upgrade Sheet 0c46a7.ttslua index 7b0ddfa55..869df2fca 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Empirical Hypothesis Upgrade Sheet 0c46a7.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Empirical Hypothesis Upgrade Sheet 0c46a7.ttslua @@ -41,9 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/customizable/EmpiricalHypothesisUpgradeSheet") -end) __bundle_register("playercards/customizable/EmpiricalHypothesisUpgradeSheet", function(require, _LOADED, __bundle_register, __bundle_modules) -- Customizable Cards: Empirical Hypothesis @@ -556,229 +553,266 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/customizable/EmpiricalHypothesisUpgradeSheet") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom False Surrender adf28e.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom False Surrender adf28e.yaml new file mode 100644 index 000000000..ad79604b6 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom False Surrender adf28e.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 100 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '1': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009099794971/0D542175146E0E2FBBBDCC8110B32A573FDBB03E/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10070\",\n \"type\": \"Event\",\n \"class\": \"Rogue\",\n + \ \"cost\": 1,\n \"level\": 0,\n \"traits\": \"Tactic. Trick.\",\n \"willpowerIcons\": + 1,\n \"intellectIcons\": 1,\n \"cycle\": \"The Feast of Hemlock Vale\"\n}" +GUID: adf28e +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: False Surrender +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: 6.5 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Friends in Low Places Upgrade Sheet 9fb3b9.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Friends in Low Places Upgrade Sheet 9fb3b9.ttslua index 5ffa7e6d8..cf525a664 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Friends in Low Places Upgrade Sheet 9fb3b9.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Friends in Low Places Upgrade Sheet 9fb3b9.ttslua @@ -41,6 +41,267 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/customizable/FriendsinLowPlacesUpgradeSheet") end) @@ -72,16 +333,16 @@ customizations = { checkboxes = { posZ = -0.44, count = 2, + }, + textField = { + position = { 0.6295, 0.25, -0.44 }, + width = 290 } }, [4] = { checkboxes = { posZ = -0.05, count = 2, - }, - textField = { - position = { 0.6295, 0.25, -0.44 }, - width = 290 } }, [5] = { @@ -559,231 +820,4 @@ function maybeUpdateServitorSlotDisplay() }) end end) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlaymatApi = { } - local internal = { } - - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end - end - - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi -end -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Grift df75d7.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Grift df75d7.yaml new file mode 100644 index 000000000..d6921bec2 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Grift df75d7.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 500 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '5': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009099857520/D9FD0353EAE4B1CEB3A3F220C26B09543FD71BD3/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10071\",\n \"type\": \"Event\",\n \"class\": \"Rogue\",\n + \ \"cost\": 0,\n \"level\": 0,\n \"traits\": \"Trick. Illicit.\",\n \"intellectIcons\": + 1,\n \"agilityIcons\": 1,\n \"cycle\": \"The Feast of Hemlock Vale\"\n}" +GUID: df75d7 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Grift +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: -0.33 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Grizzled Upgrade Sheet ef8f08.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Grizzled Upgrade Sheet ef8f08.ttslua index 561ae8726..09c3927f1 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Grizzled Upgrade Sheet ef8f08.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Grizzled Upgrade Sheet ef8f08.ttslua @@ -41,68 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/customizable/GrizzledUpgradeSheet") -end) -__bundle_register("playercards/customizable/GrizzledUpgradeSheet", function(require, _LOADED, __bundle_register, __bundle_modules) --- Customizable Cards: Grizzled - --- Color information for buttons and input boxes -boxSize = 40 -inputFontsize = 50 - --- static values -xInitial = -0.933 -xOffset = 0.075 - -customizations = { - [1] = { - textField = { - position = { 0.3, 0.25, -0.91 }, - width = 600 - } - }, - [2] = { - checkboxes = { - posZ = -0.71, - count = 1, - }, - textField = { - position = { 0.005, 0.25, -0.58 }, - width = 875 - } - }, - [3] = { - checkboxes = { - posZ = -0.458, - count = 2, - }, - textField = { - position = { 0.005, 0.25, -0.32 }, - width = 875 - } - }, - [4] = { - checkboxes = { - posZ = -0.205, - count = 3, - } - }, - [5] = { - checkboxes = { - posZ = 0.362, - count = 4, - }, - }, - [6] = { - checkboxes = { - posZ = 0.82, - count = 5, - }, - }, -} -require("playercards/customizable/UpgradeSheetLibrary") -end) __bundle_register("playercards/customizable/UpgradeSheetLibrary", function(require, _LOADED, __bundle_register, __bundle_modules) -- Common code for handling customizable card upgrade sheets -- Define UI elements in the base card file, then include this @@ -553,229 +491,325 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/customizable/GrizzledUpgradeSheet") +end) +__bundle_register("playercards/customizable/GrizzledUpgradeSheet", function(require, _LOADED, __bundle_register, __bundle_modules) +-- Customizable Cards: Grizzled + +-- Color information for buttons and input boxes +boxSize = 40 +inputFontsize = 50 + +-- static values +xInitial = -0.933 +xOffset = 0.075 + +customizations = { + [1] = { + textField = { + position = { 0.3, 0.25, -0.91 }, + width = 600 + } + }, + [2] = { + checkboxes = { + posZ = -0.71, + count = 1, + }, + textField = { + position = { 0.005, 0.25, -0.58 }, + width = 875 + } + }, + [3] = { + checkboxes = { + posZ = -0.458, + count = 2, + }, + textField = { + position = { 0.005, 0.25, -0.32 }, + width = 875 + } + }, + [4] = { + checkboxes = { + posZ = -0.205, + count = 3, + } + }, + [5] = { + checkboxes = { + posZ = 0.362, + count = 4, + }, + }, + [6] = { + checkboxes = { + posZ = 0.82, + count = 5, + }, + }, +} +require("playercards/customizable/UpgradeSheetLibrary") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Honed Instinct Upgrade Sheet ba0e34.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Honed Instinct Upgrade Sheet ba0e34.ttslua index f968f6285..de3ad688b 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Honed Instinct Upgrade Sheet ba0e34.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Honed Instinct Upgrade Sheet ba0e34.ttslua @@ -41,6 +41,36 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/customizable/HonedInstinctUpgradeSheet") end) @@ -557,228 +587,232 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi end end) diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Hospital Debts bd323d.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Hospital Debts bd323d.yaml index 5a31ca138..e646a7de1 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Hospital Debts bd323d.yaml +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Hospital Debts bd323d.yaml @@ -19,9 +19,10 @@ CustomDeck: UniqueBack: false Description: Advanced DragSelectable: true -GMNotes: "{\r\n \"id\": \"90010\",\r\n \"type\": \"Treachery\",\r\n \"class\": - \"Neutral\",\r\n \"traits\": \"Task.\",\r\n \"weakness\": true,\r\n \"cycle\": - \"Standalone\"\r\n}\r" +GMNotes: "{\n \"id\": \"90010\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n + \ \"traits\": \"Task.\",\n \"weakness\": true,\n \"uses\": [\n {\n \"count\": + 0,\n \"type\": \"Resource\",\n \"token\": \"resource\"\n }\n ],\n + \ \"cycle\": \"Standalone\"\n}" GUID: bd323d Grid: true GridProjection: false diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Hunter's Armor Upgrade Sheet d2d01b.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Hunter's Armor Upgrade Sheet d2d01b.ttslua index 9bd3c1667..3e4a98332 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Hunter's Armor Upgrade Sheet d2d01b.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Hunter's Armor Upgrade Sheet d2d01b.ttslua @@ -41,6 +41,36 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/customizable/HuntersArmorUpgradeSheet") end) @@ -550,228 +580,232 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi end end) diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Hyperphysical Shotcaster Upgrade Sheet a4eec2.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Hyperphysical Shotcaster Upgrade Sheet a4eec2.ttslua index 90cc82bb8..77e929005 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Hyperphysical Shotcaster Upgrade Sheet a4eec2.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Hyperphysical Shotcaster Upgrade Sheet a4eec2.ttslua @@ -41,233 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlaymatApi = { } - local internal = { } - - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end - end - - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi -end -end) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/customizable/HyperphysicalShotcasterUpgradeSheet") end) @@ -776,4 +549,265 @@ function maybeUpdateServitorSlotDisplay() }) end end) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom I'll Pay You Back! 40e1ca.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom I'll Pay You Back! 40e1ca.yaml new file mode 100644 index 000000000..625cc52ed --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom I'll Pay You Back! 40e1ca.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 600 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '6': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009070978340/8858A9F24148B2C04A3ED876597BD966FEE114EC/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10072\",\n \"type\": \"Event\",\n \"class\": \"Rogue\",\n + \ \"cost\": 0,\n \"level\": 0,\n \"traits\": \"Gambit. Trick.\",\n \"willpowerIcons\": + 1,\n \"agilityIcons\": 1,\n \"cycle\": \"The Feast of Hemlock Vale\"\n}" +GUID: 40e1ca +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: '"I''ll Pay You Back!"' +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: -2.6 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Living Ink Upgrade Sheet 19a05b.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Living Ink Upgrade Sheet 19a05b.ttslua index fcb1b2068..130e42f6c 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Living Ink Upgrade Sheet 19a05b.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Living Ink Upgrade Sheet 19a05b.ttslua @@ -560,229 +560,263 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Makeshift Trap Upgrade Sheet 64dfce.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Makeshift Trap Upgrade Sheet 64dfce.ttslua index 4e51cac14..970eddc85 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Makeshift Trap Upgrade Sheet 64dfce.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Makeshift Trap Upgrade Sheet 64dfce.ttslua @@ -41,6 +41,66 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/customizable/MakeshiftTrapUpgradeSheet") +end) +__bundle_register("playercards/customizable/MakeshiftTrapUpgradeSheet", function(require, _LOADED, __bundle_register, __bundle_modules) +-- Customizable Cards: Makeshift Trap + +-- Color information for buttons +boxSize = 39 + +-- static values +xInitial = -0.935 +xOffset = 0.0735 + +customizations = { + [1] = { + checkboxes = { + posZ = -0.889, + count = 1, + } + }, + [2] = { + checkboxes = { + posZ = -0.655, + count = 1, + } + }, + [3] = { + checkboxes = { + posZ = -0.325, + count = 2, + } + }, + [4] = { + checkboxes = { + posZ = -0.085, + count = 2, + } + }, + [5] = { + checkboxes = { + posZ = 0.252, + count = 2, + }, + }, + [6] = { + checkboxes = { + posZ = 0.585, + count = 3, + } + }, + [7] = { + checkboxes = { + posZ = 0.927, + count = 4, + }, + }, +} + +require("playercards/customizable/UpgradeSheetLibrary") +end) __bundle_register("playercards/customizable/UpgradeSheetLibrary", function(require, _LOADED, __bundle_register, __bundle_modules) -- Common code for handling customizable card upgrade sheets -- Define UI elements in the base card file, then include this @@ -491,289 +551,263 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/customizable/MakeshiftTrapUpgradeSheet") -end) -__bundle_register("playercards/customizable/MakeshiftTrapUpgradeSheet", function(require, _LOADED, __bundle_register, __bundle_modules) --- Customizable Cards: Makeshift Trap +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local GUIDReferenceApi = {} --- Color information for buttons -boxSize = 39 + local function getGuidHandler() + return getObjectFromGUID("123456") + end --- static values -xInitial = -0.935 -xOffset = 0.0735 + -- 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 -customizations = { - [1] = { - checkboxes = { - posZ = -0.889, - count = 1, - } - }, - [2] = { - checkboxes = { - posZ = -0.655, - count = 1, - } - }, - [3] = { - checkboxes = { - posZ = -0.325, - count = 2, - } - }, - [4] = { - checkboxes = { - posZ = -0.085, - count = 2, - } - }, - [5] = { - checkboxes = { - posZ = 0.252, - count = 2, - }, - }, - [6] = { - checkboxes = { - posZ = 0.585, - count = 3, - } - }, - [7] = { - checkboxes = { - posZ = 0.927, - count = 4, - }, - }, -} + -- 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 -require("playercards/customizable/UpgradeSheetLibrary") + -- 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Occult Reliquary acd0c2.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Occult Reliquary acd0c2.yaml new file mode 100644 index 000000000..8347aadaa --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Occult Reliquary acd0c2.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 700 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '7': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009070978467/E0468E7962843128806C87A8C14BDCA5EF46A2D8/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: Dubious Source +DragSelectable: true +GMNotes: "{\n \"id\": \"10132\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n + \ \"level\": 3,\n \"traits\": \"Boon. Pact.\",\n \"permanent\": true,\n \"cycle\": + \"The Feast of Hemlock Vale\"\n}" +GUID: acd0c2 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Occult Reliquary +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: 1.95 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Ofuda 860c1e.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Ofuda 860c1e.yaml new file mode 100644 index 000000000..45e55a04d --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Ofuda 860c1e.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 800 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009070978580/2878CF06EFC74C7701A21D5CABB22901293285A4/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10022\",\n \"type\": \"Asset\",\n \"class\": \"Guardian\",\n + \ \"cost\": 2,\n \"level\": 0,\n \"traits\": \"Item. Charm. Blessed.\",\n \"willpowerIcons\": + 1,\n \"cycle\": \"The Feast of Hemlock Vale\"\n}" +GUID: 860c1e +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Ofuda +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: -4.88 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Pocket Multi Tool Upgrade Sheet d706e7.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Pocket Multi Tool Upgrade Sheet d706e7.ttslua index b685dfe00..d29d2b2e3 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Pocket Multi Tool Upgrade Sheet d706e7.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Pocket Multi Tool Upgrade Sheet d706e7.ttslua @@ -41,6 +41,267 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/customizable/PocketMultiToolUpgradeSheet") end) @@ -548,231 +809,4 @@ function maybeUpdateServitorSlotDisplay() }) end end) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlaymatApi = { } - local internal = { } - - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end - end - - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi -end -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Power Word Upgrade Sheet 0d9481.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Power Word Upgrade Sheet 0d9481.ttslua index fe790fa9d..9ed1558ba 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Power Word Upgrade Sheet 0d9481.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Power Word Upgrade Sheet 0d9481.ttslua @@ -557,229 +557,263 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Runic Axe Upgrade Sheet be427d.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Runic Axe Upgrade Sheet be427d.ttslua index ef65ab8b5..d9e2f16fb 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Runic Axe Upgrade Sheet be427d.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Runic Axe Upgrade Sheet be427d.ttslua @@ -557,229 +557,263 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Speak to the Dead c763aa.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Speak to the Dead c763aa.yaml new file mode 100644 index 000000000..d019285ab --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Speak to the Dead c763aa.yaml @@ -0,0 +1,57 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 9200 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '92': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2195002645128570001/1519803ABED2FA378473CDEDA000B057BB06A63B/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10091\",\n \"type\": \"Asset\",\n \"class\": \"Mystic\",\n + \ \"cost\": 1,\n \"level\": 0,\n \"traits\": \"Talent. Ritual.\",\n \"uses\": + [\n {\n \"count\": 6,\n \"type\": \"Offering\",\n \"token\": \"resource\"\n + \ }\n ],\n \"willpowerIcons\": 1,\n \"cycle\": \"The Feast of Hemlock Vale\"\n}" +GUID: c763aa +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Speak to the Dead +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: -7.16 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Summoned Servitor Upgrade Sheet 5397a6.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom Summoned Servitor Upgrade Sheet 5397a6.ttslua index 80612e132..6ddc931fc 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom Summoned Servitor Upgrade Sheet 5397a6.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Summoned Servitor Upgrade Sheet 5397a6.ttslua @@ -41,6 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/customizable/SummonedServitorUpgradeSheet") +end) __bundle_register("playercards/customizable/SummonedServitorUpgradeSheet", function(require, _LOADED, __bundle_register, __bundle_modules) -- Customizable Cards: Summoned Servitor @@ -566,232 +569,263 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/customizable/SummonedServitorUpgradeSheet") +__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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom The Beyond 37ab47.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom The Beyond 37ab47.yaml new file mode 100644 index 000000000..32addf725 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom The Beyond 37ab47.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 847100 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8471': + BackIsHidden: true + BackURL: http://cloud-3.steamusercontent.com/ugc/2149964195986881059/864F6EBBD2900ED6D145B8AF12F2F8C180375C83/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2149964195986880989/13172BC914A0D729B4EFD9845FA9FDFCAB6F77F7/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: Bleak Netherworld +DragSelectable: true +GMNotes: "{\n \"id\": \"90052\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n + \ \"permanent\": true,\n \"startsInPlay\": true,\n \"cycle\": \"Laid to Rest\"\n}" +GUID: 37ab47 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: The Beyond +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 78.53 + posY: 3.19 + posZ: 17.89 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom The Raven Quill Upgrade Sheet 23b96a.ttslua b/unpacked/Bag All Player Cards 15bb07/CardCustom The Raven Quill Upgrade Sheet 23b96a.ttslua index 16a445b0c..95080a915 100644 --- a/unpacked/Bag All Player Cards 15bb07/CardCustom The Raven Quill Upgrade Sheet 23b96a.ttslua +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom The Raven Quill Upgrade Sheet 23b96a.ttslua @@ -41,304 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlaymatApi = { } - local internal = { } - - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end - end - - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/customizable/TheRavenQuillUpgradeSheet") -end) -__bundle_register("playercards/customizable/TheRavenQuillUpgradeSheet", function(require, _LOADED, __bundle_register, __bundle_modules) --- Customizable Cards: The Raven Quill - --- Color information for buttons and input boxes -boxSize = 37 -inputFontsize = 38 - --- static values -xInitial = -0.935 -xOffset = 0.0705 - -customizations = { - [1] = { - textField = { - position = { 0.5, 0.25, -0.905 }, - width = 425 - } - }, - [2] = { - checkboxes = { - posZ = -0.72, - count = 1, - } - }, - [3] = { - checkboxes = { - posZ = -0.52, - count = 1, - } - }, - [4] = { - checkboxes = { - posZ = -0.305, - count = 2, - } - }, - [5] = { - checkboxes = { - posZ = -0.105, - count = 2, - }, - textField = { - position = { 0.125, 0.25, 0 }, - width = 775 - } - }, - [6] = { - checkboxes = { - posZ = 0.1, - count = 2, - } - }, - [7] = { - checkboxes = { - posZ = 0.4, - count = 3, - } - }, - [8] = { - checkboxes = { - posZ = 0.695, - count = 4, - } - }, -} - -require("playercards/customizable/UpgradeSheetLibrary") -end) __bundle_register("playercards/customizable/UpgradeSheetLibrary", function(require, _LOADED, __bundle_register, __bundle_modules) -- Common code for handling customizable card upgrade sheets -- Define UI elements in the base card file, then include this @@ -787,4 +489,336 @@ function maybeUpdateServitorSlotDisplay() }) end end) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/customizable/TheRavenQuillUpgradeSheet") +end) +__bundle_register("playercards/customizable/TheRavenQuillUpgradeSheet", function(require, _LOADED, __bundle_register, __bundle_modules) +-- Customizable Cards: The Raven Quill + +-- Color information for buttons and input boxes +boxSize = 37 +inputFontsize = 38 + +-- static values +xInitial = -0.935 +xOffset = 0.0705 + +customizations = { + [1] = { + textField = { + position = { 0.5, 0.25, -0.905 }, + width = 425 + } + }, + [2] = { + checkboxes = { + posZ = -0.72, + count = 1, + } + }, + [3] = { + checkboxes = { + posZ = -0.52, + count = 1, + } + }, + [4] = { + checkboxes = { + posZ = -0.305, + count = 2, + } + }, + [5] = { + checkboxes = { + posZ = -0.105, + count = 2, + }, + textField = { + position = { 0.125, 0.25, 0 }, + width = 775 + } + }, + [6] = { + checkboxes = { + posZ = 0.1, + count = 2, + } + }, + [7] = { + checkboxes = { + posZ = 0.4, + count = 3, + } + }, + [8] = { + checkboxes = { + posZ = 0.695, + count = 4, + } + }, +} + +require("playercards/customizable/UpgradeSheetLibrary") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Wicked Athame c9fb1f.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Wicked Athame c9fb1f.yaml new file mode 100644 index 000000000..fcf0b8bed --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Wicked Athame c9fb1f.yaml @@ -0,0 +1,56 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 900 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '9': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009070978691/AE0143320D2C6CE35BCF1BFE50ABBCAA82546854/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: Cursed Blade +DragSelectable: true +GMNotes: "{\n \"id\": \"10092\",\n \"type\": \"Asset\",\n \"class\": \"Mystic\",\n + \ \"cost\": 2,\n \"level\": 0,\n \"traits\": \"Item. Weapon. Melee. Cursed.\",\n + \ \"combatIcons\": 1,\n \"cycle\": \"The Feast of Hemlock Vale\"\n}" +GUID: c9fb1f +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Wicked Athame +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Asset +- PlayerCard +Tooltip: true +Transform: + posX: 13.08 + posY: 3.55 + posZ: -7.16 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Wilson Richards 54eab5.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Wilson Richards 54eab5.yaml new file mode 100644 index 000000000..afaa0ff6f --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Wilson Richards 54eab5.yaml @@ -0,0 +1,57 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 11300 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '113': + BackIsHidden: true + BackURL: http://cloud-3.steamusercontent.com/ugc/2223150865961116635/ECA77BE1E295589069A336225ED260173BCF349F/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2223150865961116782/ACC14C3F0BA423DF4AE2CDA71BE8B0044ED0DEF0/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: The Handyman +DragSelectable: true +GMNotes: "{\n \"id\": \"10001\",\n \"type\": \"Investigator\",\n \"class\": \"Guardian\",\n + \ \"traits\": \"Drifter.\",\n \"willpowerIcons\": 3,\n \"intellectIcons\": 3,\n + \ \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"The Feast of Hemlock + Vale\"\n}" +GUID: 54eab5 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Wilson Richards +SidewaysCard: true +Snap: true +Sticky: true +Tags: +- Investigator +- PlayerCard +Tooltip: true +Transform: + posX: 9.23 + posY: 3.55 + posZ: 2.42 + rotX: 0 + rotY: 180 + rotZ: 0 + scaleX: 1.15 + scaleY: 1 + scaleZ: 1.15 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Wilson Richards ceb426.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Wilson Richards ceb426.yaml new file mode 100644 index 000000000..2d6636ab4 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Wilson Richards ceb426.yaml @@ -0,0 +1,53 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 833400 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '8334': + BackIsHidden: true + BackURL: http://cloud-3.steamusercontent.com/ugc/2223150865961116947/D586147EC3D293A3A1879A4E61CE6FDF3094A746/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2223150865961117168/D42461AB21EC7E1F17DA41E1B6BD58F22E22252B/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10001-m\",\n \"type\": \"Minicard\"\n}" +GUID: ceb426 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Wilson Richards +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- Minicard +Tooltip: true +Transform: + posX: 5.76 + posY: 3.65 + posZ: 15.39 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 0.6 + scaleY: 1 + scaleZ: 0.6 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag All Player Cards 15bb07/CardCustom Zamacona 541ba9.yaml b/unpacked/Bag All Player Cards 15bb07/CardCustom Zamacona 541ba9.yaml new file mode 100644 index 000000000..b117fd4c5 --- /dev/null +++ b/unpacked/Bag All Player Cards 15bb07/CardCustom Zamacona 541ba9.yaml @@ -0,0 +1,55 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +CardID: 1000 +ColorDiffuse: + b: 0.71324 + g: 0.71324 + r: 0.71324 +CustomDeck: + '10': + BackIsHidden: true + BackURL: https://i.imgur.com/EcbhVuh.jpg/ + FaceURL: http://cloud-3.steamusercontent.com/ugc/2172484009071331144/5BF472F3A7B8E786FE4942B38201E09E8291A77A/ + NumHeight: 1 + NumWidth: 1 + Type: 0 + UniqueBack: false +Description: '' +DragSelectable: true +GMNotes: "{\n \"id\": \"10011\",\n \"type\": \"Enemy\",\n \"class\": \"Neutral\",\n + \ \"traits\": \"Humanoid. Criminal.\",\n \"weakness\": true,\n \"cycle\": \"The + Feast of Hemlock Vale\"\n}" +GUID: 541ba9 +Grid: true +GridProjection: false +Hands: true +HideWhenFaceDown: true +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: CardCustom +Nickname: Zamacona +SidewaysCard: false +Snap: true +Sticky: true +Tags: +- PlayerCard +Tooltip: true +Transform: + posX: 9.32 + posY: 3.55 + posZ: -3.11 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Bag OptionPanel Source 830bd0.yaml b/unpacked/Bag OptionPanel Source 830bd0.yaml index 4fffb4edc..668ca2569 100644 --- a/unpacked/Bag OptionPanel Source 830bd0.yaml +++ b/unpacked/Bag OptionPanel Source 830bd0.yaml @@ -16,7 +16,6 @@ ContainedObjects: - !include 'Bag OptionPanel Source 830bd0/Custom_Tile Hand Helper 450688.yaml' - !include 'Bag OptionPanel Source 830bd0/Custom_Token Displacement Tool 0f1374.yaml' - !include 'Bag OptionPanel Source 830bd0/Custom_Token Clean Up Helper 26cf4b.yaml' -- !include 'Bag OptionPanel Source 830bd0/Custom_Token Custom Playmat Images 004fe7.yaml' Description: Contains the objects that are spawnable via option panel DragSelectable: true GMNotes: '' diff --git a/unpacked/Bag OptionPanel Source 830bd0/Custom_Tile Hand Helper 450688.ttslua b/unpacked/Bag OptionPanel Source 830bd0/Custom_Tile Hand Helper 450688.ttslua index 550917a54..7959489dc 100644 --- a/unpacked/Bag OptionPanel Source 830bd0/Custom_Tile Hand Helper 450688.ttslua +++ b/unpacked/Bag OptionPanel Source 830bd0/Custom_Tile Hand Helper 450688.ttslua @@ -164,229 +164,263 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag OptionPanel Source 830bd0/Custom_Tile Search Assistant 17aed0.ttslua b/unpacked/Bag OptionPanel Source 830bd0/Custom_Tile Search Assistant 17aed0.ttslua index 321ead1ef..7de394745 100644 --- a/unpacked/Bag OptionPanel Source 830bd0/Custom_Tile Search Assistant 17aed0.ttslua +++ b/unpacked/Bag OptionPanel Source 830bd0/Custom_Tile Search Assistant 17aed0.ttslua @@ -41,231 +41,34 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local GUIDReferenceApi = {} - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end + local function getGuidHandler() + return getObjectFromGUID("123456") end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") + -- 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 the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" + -- 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 the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") + -- 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 - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi + return GUIDReferenceApi end end) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) @@ -275,7 +78,7 @@ __bundle_register("accessories/SearchAssistant", function(require, _LOADED, __bu local playmatApi = require("playermat/PlaymatApi") -- forward declaration of variables that are used across functions -local matColor, handColor, setAsidePosition, setAsideRotation, drawDeckPosition +local matColor, handColor, setAsidePosition, setAsideRotation, drawDeckPosition, topCardDetected local quickParameters = {} quickParameters.function_owner = self @@ -375,15 +178,18 @@ end function startSearch(messageColor, number) matColor = playmatApi.getMatColorByPosition(self.getPosition()) handColor = playmatApi.getPlayerColor(matColor) + topCardDetected = false -- get draw deck - local drawDeck = playmatApi.getDrawDeck(matColor) - if drawDeck == nil then + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + if deckAreaObjects.draw == nil then printToColor(matColor .. " draw deck could not be found!", messageColor, "Red") return end - drawDeckPosition = drawDeck.getPosition() + -- get bounds to know the height of the deck + local bounds = deckAreaObjects.draw.getBounds() + drawDeckPosition = bounds.center + Vector(0, bounds.size.y / 2 + 0.2, 0) printToColor("Place target(s) of search on set aside hand.", messageColor, "Green") -- get playmat orientation @@ -398,23 +204,26 @@ function startSearch(messageColor, number) setAsidePosition = handData.position + offset * handData.right setAsideRotation = { handData.rotation.x, handData.rotation.y + 180, 180 } + -- set y-value + setAsidePosition.y = 1.5 + for i = #handCards, 1, -1 do - handCards[i].setPosition(setAsidePosition - Vector(0, i * 0.3, 0)) + handCards[i].setPosition(setAsidePosition + Vector(0, (#handCards - i) * 0.1, 0)) handCards[i].setRotation(setAsideRotation) end -- handling for Norman Withers - for _, v in ipairs(searchArea(drawDeckPosition)) do - local object = v.hit_object - if object.tag == "Card" and not object.is_face_down then - object.flip() - Wait.time(function() drawDeck = playmatApi.getDrawDeck(matColor) end, 1) - break - end + if deckAreaObjects.topCard then + deckAreaObjects.topCard.flip() + topCardDetected = true end - Wait.time(function() drawDeck.deal(number, handColor) end, 1) searchView() + + Wait.time(function() + deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + deckAreaObjects.draw.deal(number, handColor) + end, 1) end -- place handCards back into deck and optionally shuffle @@ -422,28 +231,19 @@ function endSearch(_, _, isRightClick) local handCards = Player[handColor].getHandObjects() for i = #handCards, 1, -1 do - handCards[i].setPosition(drawDeckPosition + Vector(0, 6 - i * 0.3, 0)) + handCards[i].setPosition(drawDeckPosition + Vector(0, (#handCards - i) * 0.1, 0)) handCards[i].setRotation(setAsideRotation) end - if not isRightClick then - Wait.time(function() - local deck = playmatApi.getDrawDeck(matColor) - if deck ~= nil then - deck.shuffle() - end - end, 2) - end - -- draw set aside cards (from the ground!) - for _, v in ipairs(searchArea(setAsidePosition - Vector(0, 5, 0))) do + for _, v in ipairs(searchArea(setAsidePosition)) do local obj = v.hit_object - if obj.tag == "Deck" then + if obj.type == "Deck" then Wait.time(function() obj.deal(#obj.getObjects(), handColor) end, 1) break - elseif obj.tag == "Card" then + elseif obj.type == "Card" then obj.setPosition(Player[handColor].getHandTransform().position) obj.flip() break @@ -451,6 +251,21 @@ function endSearch(_, _, isRightClick) end normalView() + + -- delay is to wait for cards to enter deck + if not isRightClick then + Wait.time(function() + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + if deckAreaObjects.draw then + deckAreaObjects.draw.shuffle() + end + end, #handCards * 0.1) + end + + -- Norman Withers handling + if topCardDetected then + Wait.time(function() playmatApi.flipTopCardFromDeck(matColor) end, #handCards * 0.1) + end end -- utility function @@ -464,4 +279,235 @@ function searchArea(position) }) end end) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +end +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Clean Up Helper 26cf4b.ttslua b/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Clean Up Helper 26cf4b.ttslua index 1cf72c2b7..6a3c722f4 100644 --- a/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Clean Up Helper 26cf4b.ttslua +++ b/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Clean Up Helper 26cf4b.ttslua @@ -43,107 +43,111 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( end)(nil) __bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end -- Returns the current value of the investigator counter from the playmat ---@return Integer. Number of investigators currently set on the counter PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") + return getInvestigatorCounter().getVar("val") end -- Updates the current value of the investigator counter from the playmat ---@param count Number of investigators to set on the counter PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) + getInvestigatorCounter().call("updateVal", count) end -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) end PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) end PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) end PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) end -- Reset the play area's tracking of which cards have had tokens spawned. PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") + return getPlayArea().call("resetSpawnedCards") end -- Event to be called when the current scenario has changed. ---@param scenarioName Name of the new scenario PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) end -- Sets this playmat's snap points to limit snapping to locations or not. -- If matchTypes is false, snap points will be reset to snap all cards. ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) end -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged -- cards before they're destroyed by entering the container PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) end -- counts the VP on locations in the play area PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") + return getPlayArea().call("countVP") end -- highlights all locations in the play area without metadata ---@param state Boolean True if highlighting should be enabled PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) + return getPlayArea().call("highlightMissingData", state) end -- highlights all locations in the play area with VP ---@param state Boolean True if highlighting should be enabled PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) + return getPlayArea().call("countVP", state) end -- Checks if an object is in the play area (returns true or false) PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) + return getPlayArea().call("isInPlayArea", object) end PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image + return getPlayArea().getCustomObject().image end PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) + return getPlayArea().call("updateSurface", url) end -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the -- data to the local token manager instance. ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) + getPlayArea().call("updateLocations", args) end PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") + return getPlayArea().getVar("customDataHelper") end return PlayAreaApi @@ -152,6 +156,7 @@ end) __bundle_register("core/SoundCubeApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local SoundCubeApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") -- this table links the name of a trigger effect to its index local soundIndices = { @@ -161,7 +166,8 @@ do } local function playTriggerEffect(index) - getObjectsWithTag("SoundCube")[1].AssetBundle.playTriggerEffect(index) + local SoundCube = guidReferenceApi.getObjectByOwnerAndType("Mythos", "SoundCube") + SoundCube.AssetBundle.playTriggerEffect(index) end -- plays the by name requested sound @@ -175,263 +181,40 @@ end end) __bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local TokenSpawnTracker = { } - local SPAWN_TRACKER_GUID = "e3ffc9" + local TokenSpawnTracker = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getSpawnTracker() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSpawnTracker") + end TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("hasSpawnedTokens", cardGuid) + return getSpawnTracker().call("hasSpawnedTokens", cardGuid) end TokenSpawnTracker.markTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("markTokensSpawned", cardGuid) + return getSpawnTracker().call("markTokensSpawned", cardGuid) end TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetTokensSpawned", cardGuid) + return getSpawnTracker().call("resetTokensSpawned", cardGuid) end TokenSpawnTracker.resetAllAssetAndEvents = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllAssetAndEvents") + return getSpawnTracker().call("resetAllAssetAndEvents") end TokenSpawnTracker.resetAllLocations = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllLocations") + return getSpawnTracker().call("resetAllLocations") end TokenSpawnTracker.resetAll = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAll") + return getSpawnTracker().call("resetAll") end return TokenSpawnTracker end end) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlaymatApi = { } - local internal = { } - - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end - end - - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi -end -end) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("accessories/CleanUpHelper") end) @@ -441,79 +224,24 @@ __bundle_register("accessories/CleanUpHelper", function(require, _LOADED, __bund - puts everything on playmats and hands into respective trashcans - use the IGNORE_TAG to exclude objects from tidying (default: "CleanUpHelper_Ignore")]] -local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi") -local chaosBagApi = require("chaosbag/ChaosBagApi") -local playAreaApi = require("core/PlayAreaApi") -local playmatApi = require("playermat/PlaymatApi") -local soundCubeApi = require("core/SoundCubeApi") -local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") - --- these objects will be ignored -local IGNORE_GUIDS = { - -- big playmat, change image panel and investigator counter - "b7b45b", "f182ee", "721ba2", - -- bless/curse manager - "afa06b", "bd0253", "5933fb", - -- stuff on agenda/act playmat - "85c4c6", "4a3aa4", "fea079", "b015d8", "11e0cf", "9f334f", "70b9f6", "0a5a29", - -- doom/location token bag - "47ffc3", "170f10", - -- table - "4ee1f2" -} +local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi") +local chaosBagApi = require("chaosbag/ChaosBagApi") +local guidReferenceApi = require("core/GUIDReferenceApi") +local playAreaApi = require("core/PlayAreaApi") +local playmatApi = require("playermat/PlaymatApi") +local soundCubeApi = require("core/SoundCubeApi") +local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") -- objects with this tag will be ignored local IGNORE_TAG = "CleanUpHelper_ignore" -- colors and order for following tables -local COLORS = { "White", "Orange", "Green", "Red", "Agenda" } - --- counter GUIDS (4x damage and 4x horror) -local DAMAGE_HORROR_GUIDS = { - "eb08d6", "e64eec", "1f5a0a", "591a45", - "468e88", "0257d9", "7b5729", "beb964", -} - +local COLORS = { "White", "Orange", "Green", "Red", "Mythos" } local campaignLog local RESET_VALUES = {} - --- GUIDS of objects (in order of ownership relating to 'COLORS') -local PLAYERMAT_GUIDS = { "8b081b", "bd0ff4", "383d8b", "0840d5" } -local RESOURCE_GUIDS = { "4406f0", "816d84", "cd15ac", "a4b60d" } -local TRACKER_GUIDS = { "e598c2", "b4a5f7", "af7ed7", "e74881" } -local CLUE_GUIDS = { "d86b7c", "1769ed", "032300", "37be78" } -local CLUE_CLICKER_GUIDS = { "db85d6", "3f22e5", "891403", "4111de" } -local TRASHCAN_GUIDS = { "147e80", "f7b6c8", "5f896a", "4b8594", "70b9f6" } - --- values for physics.cast (4 entries for player zones, 5th entry for agenda/act deck, 6th for campaign log) -local PHYSICS_POSITION = { - { -54.5, 2, 21 }, - { -54.5, 2, -21 }, - { -27.0, 2, 26 }, - { -27.0, 2, -26 }, - { -02.0, 2, 10 }, - { -00.0, 2, -27 } -} - -local PHYSICS_ROTATION = { - 270, - 270, - 0, - 180, - 270, - 0 -} - -local PHYSICS_SCALE = { - { 36.6, 1, 14.5 }, - { 36.6, 1, 14.5 }, - { 34.0, 1, 14.5 }, - { 34.0, 1, 14.5 }, - { 55.0, 1, 13.5 }, - { 05.0, 1, 05.0 } -} - +local loadingFailedBefore = false local optionsVisible = false + local options = {} options["importTrauma"] = true options["tidyPlayermats"] = true @@ -522,7 +250,6 @@ options["removeDrawnLines"] = false local buttonParameters = {} buttonParameters.function_owner = self -local loadingFailedBefore = false --------------------------------------------------------- -- option loading and GUI setup @@ -569,14 +296,6 @@ function onLoad(savedData) buttonParameters.position.z = 1.1 buttonParameters.width = 1550 self.createButton(buttonParameters) - - -- create single table for ignoring - for _, v in ipairs(CLUE_GUIDS) do table.insert(IGNORE_GUIDS, v) end - for _, v in ipairs(CLUE_CLICKER_GUIDS) do table.insert(IGNORE_GUIDS, v) end - for _, v in ipairs(RESOURCE_GUIDS) do table.insert(IGNORE_GUIDS, v) end - for _, v in ipairs(TRASHCAN_GUIDS) do table.insert(IGNORE_GUIDS, v) end - for _, v in ipairs(PLAYERMAT_GUIDS) do table.insert(IGNORE_GUIDS, v) end - for _, v in ipairs(DAMAGE_HORROR_GUIDS) do table.insert(IGNORE_GUIDS, v) end end --------------------------------------------------------- @@ -616,13 +335,8 @@ function cleanUp(_, color) getTrauma() -- delay to account for potential state change - Wait.time(function() - updateCounters(RESOURCE_GUIDS, 5, "Resource") - updateCounters(CLUE_CLICKER_GUIDS, 0, "Clue clicker") - updateCounters(DAMAGE_HORROR_GUIDS, RESET_VALUES, "Damage / Horror") - end, 0.2) + Wait.time(updateCounters, 0.2) - resetSkillTrackers() resetDoomCounter() blessCurseManagerApi.removeAll(color) removeLines() @@ -639,39 +353,20 @@ end -- modular functions, called by other functions --------------------------------------------------------- -function updateCounters(tableOfGUIDs, newValues, info) - -- instead of a table, this will be used if just a single value is provided - local singleValue = tonumber(newValues) +function updateCounters() + playmatApi.updateCounter("All", "ResourceCounter" , 5) + playmatApi.updateCounter("All", "ClickableClueCounter" , 0) + playmatApi.resetSkillTracker("All") - for i, guid in ipairs(tableOfGUIDs) do - local TOKEN = getObjectFromGUID(guid) - local newValue = singleValue or newValues[i] - - if TOKEN ~= nil then - TOKEN.call("updateVal", newValue) - else - printToAll(info .. ": No. " .. i .. " could not be found.", "Yellow") - end - end -end - --- set investigator skill trackers to "1, 1, 1, 1" -function resetSkillTrackers() - for i, guid in ipairs(TRACKER_GUIDS) do - local obj = getObjectFromGUID(guid) - - if obj ~= nil then - obj.call("updateStats", { 1, 1, 1, 1 }) - else - printToAll("Skill tracker for " .. COLORS[i] .. " playmat could not be found.", "Yellow") - end + for i = 1, 4 do + playmatApi.updateCounter(COLORS[i], "DamageCounter", RESET_VALUES.Damage[i]) + playmatApi.updateCounter(COLORS[i], "HorrorCounter", RESET_VALUES.Horror[i]) end end -- reset doom on agenda function resetDoomCounter() - local doomCounter = getObjectFromGUID("85c4c6") - + local doomCounter = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DoomCounter") if doomCounter ~= nil then doomCounter.call("updateVal") else @@ -679,19 +374,19 @@ function resetDoomCounter() end end --- gets the GUID of a custom data helper (if present) and adds it to the ignore list +-- adds the ignore tag to the custom data helper function ignoreCustomDataHelper() local customDataHelper = playAreaApi.getCustomDataHelper() if customDataHelper then - table.insert(IGNORE_GUIDS, customDataHelper.getGUID()) + customDataHelper.addTag(IGNORE_TAG) end end -- read values for trauma from campaign log if enabled function getTrauma() RESET_VALUES = { - 0, 0, 0, 0, - 0, 0, 0, 0 + Damage = { 0, 0, 0, 0 }, + Horror = { 0, 0, 0, 0 } } -- stop here if trauma import is disabled @@ -701,13 +396,12 @@ function getTrauma() end -- get campaign log - campaignLog = findObjects(6)[1] + campaignLog = getObjectsWithTag("CampaignLog")[1] if campaignLog == nil then printToAll("Campaign log not found in standard position!", "Yellow") printToAll("Default values for health and sanity loaded.", "Yellow") return end - campaignLog = campaignLog.hit_object loadTrauma() end @@ -718,7 +412,14 @@ function loadTrauma() if trauma ~= nil then printToAll("Trauma values found in campaign log!", "Green") - RESET_VALUES = campaignLog.call("returnTrauma") + trauma = campaignLog.call("returnTrauma") + for i = 1, 8 do + if i < 5 then + RESET_VALUES.Damage[i] = trauma[i] + else + RESET_VALUES.Horror[i-4] = trauma[i] + end + end loadingFailedBefore = false elseif loadingFailedBefore then printToAll("Trauma values could not be found in campaign log!", "Yellow") @@ -741,7 +442,7 @@ end -- remove drawn lines function removeLines() if options["removeDrawnLines"] then - printToAll("Removing vector lines...", "White") + printToAll("Removing global vector lines...", "White") Global.setVectorLines({}) end end @@ -750,40 +451,42 @@ end function discardHands() if not options["tidyPlayermats"] then return end for i = 1, 4 do - local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[i]) - if trashcan == nil then return end + local trash = guidReferenceApi.getObjectByOwnerAndType(COLORS[i], "Trash") + if trash == nil then return end local hand = Player[playmatApi.getPlayerColor(COLORS[i])].getHandObjects() for j = #hand, 1, -1 do - trashcan.putObject(hand[j]) + trash.putObject(hand[j]) end end end -- clean up for play area function tidyPlayareaCoroutine() - local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[5]) - local PLAYMATZONE = getObjectFromGUID("a2f932") + local trash = guidReferenceApi.getObjectByOwnerAndType("Mythos", "Trash") + local playAreaZone = guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayAreaZone") - if PLAYMATZONE == nil then + if playAreaZone == nil then printToAll("Scripting zone for main play area could not be found!", "Red") - elseif trashcan == nil then + elseif trash == nil then printToAll("Trashcan for main play area could not be found!", "Red") else - for _, obj in ipairs(PLAYMATZONE.getObjects()) do + for _, obj in ipairs(playAreaZone.getObjects()) do -- ignore these elements - if not tableContains(IGNORE_GUIDS, obj.getGUID()) and obj.hasTag(IGNORE_TAG) == false then + if obj.hasTag(IGNORE_TAG) == false + and obj.locked == false + and obj.interactable == true then coroutine.yield(0) - trashcan.putObject(obj) + trash.putObject(obj) end end end - printToAll("Tidying playermats and agenda mat...", "White") + printToAll("Tidying playermats and mythos area...", "White") startLuaCoroutine(self, "tidyPlayerMatCoroutine") return 1 end --- clean up for the four playermats and the agenda/act playmat +-- clean up for the four playermats and the mythos area function tidyPlayerMatCoroutine() for i = 1, 5 do -- only continue for playermat (1-4) if option enabled @@ -791,32 +494,39 @@ function tidyPlayerMatCoroutine() -- delay for animation purpose for k = 1, 30 do coroutine.yield(0) end - -- get respective trashcan - local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[i]) - if trashcan == nil then + -- get respective trash + local trash = guidReferenceApi.getObjectByOwnerAndType(COLORS[i], "Trash") + if trash == nil then printToAll("Trashcan for " .. COLORS[i] .. " playmat could not be found!", "Red") return 1 end - for _, entry in ipairs(findObjects(i)) do - local obj = entry.hit_object - local desc_low = string.lower(obj.getDescription()) + local objList + if i < 5 then + objList = playmatApi.searchAroundPlaymat(COLORS[i]) + else + objList = searchMythosArea() + end + for _, obj in ipairs(objList) do -- ignore these elements - if not tableContains(IGNORE_GUIDS, obj.getGUID()) and obj.hasTag(IGNORE_TAG) == false and - desc_low ~= "chaos bag" and desc_low ~= "action token" then + if obj.hasTag(IGNORE_TAG) == false + and obj.getDescription() ~= "Action Token" + and obj.hasTag("chaosBag") == false + and obj.locked == false + and obj.interactable == true then coroutine.yield(0) - trashcan.putObject(obj) + trash.putObject(obj) - -- flip action tokens back to ready - elseif desc_low == "action token" and obj.is_face_down then + -- flip action tokens back to ready + elseif obj.getDescription() == "Action Token" and obj.is_face_down then obj.flip() end end -- reset "activeInvestigatorId" if i < 5 then - local playermat = getObjectFromGUID(PLAYERMAT_GUIDS[i]) + local playermat = guidReferenceApi.getObjectByOwnerAndType(COLORS[i], "Playermat") if playermat then playermat.setVar("activeInvestigatorId", "00000") end @@ -824,7 +534,7 @@ function tidyPlayerMatCoroutine() end end - local datahelper = getObjectFromGUID("708279") + local datahelper = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") if datahelper then datahelper.setTable("SPAWNED_PLAYER_CARD_GUIDS", {}) end @@ -837,37 +547,37 @@ end -- helper functions --------------------------------------------------------- --- find objects depending on index (1 to 4 for playermats, 5 for agenda/act playmat, 6 for campaign log) -function findObjects(num) - return Physics.cast({ +-- find objects in the mythos area +function searchMythosArea() + local searchResult = Physics.cast({ direction = { 0, 1, 0 }, max_distance = 1, type = 3, - size = PHYSICS_SCALE[num], - origin = PHYSICS_POSITION[num], - orientation = { 0, PHYSICS_ROTATION[num], 0 }, + size = { 55, 1, 13.5 }, + origin = { -2, 2, 10 }, + orientation = { 0, 270, 0 }, debug = false }) -end --- search a table for a value, return true if found (else returns false) -function tableContains(table, value) - for _, v in ipairs(table) do - if v == value then - return true - end + local objList = {} + for _, v in ipairs(searchResult) do + table.insert(objList, v.hit_object) end - return false + return objList end end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -875,30 +585,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -980,4 +690,265 @@ do 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) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +end +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Clean Up Helper 26cf4b.xml b/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Clean Up Helper 26cf4b.xml index 9184bb4f2..abb9d9ab7 100644 --- a/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Clean Up Helper 26cf4b.xml +++ b/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Clean Up Helper 26cf4b.xml @@ -1,3 +1,4 @@ + @@ -67,4 +68,5 @@ - \ No newline at end of file + + \ No newline at end of file diff --git a/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Custom Playmat Images 004fe7.ttslua b/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Custom Playmat Images 004fe7.ttslua deleted file mode 100644 index f118e2680..000000000 --- a/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Custom Playmat Images 004fe7.ttslua +++ /dev/null @@ -1,868 +0,0 @@ --- 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("accessories/CustomPlaymatImages", function(require, _LOADED, __bundle_register, __bundle_modules) -local DATA = { - ["Arkham Locations"] = { { - Name = "Downtown 1", - URL = "https://i.ibb.co/FzRk98n/Arkham-Downtown-Cristi-Balanescu.jpg" - }, { - Name = "Downtown 2", - URL = "https://i.ibb.co/W2yJ5QZ/Arkham-Downtown-Jokubas-Uogintas.jpg" - }, { - Name = "Eastside 1", - URL = "https://i.ibb.co/W3QvdZW/Arkham-Eastside-Cristi-Balanescu.jpg" - }, { - Name = "Eastside 2", - URL = "https://i.ibb.co/xfn1Fp8/Arkham-Eastside-Jokubas-Uogintas.jpg" - }, { - Name = "French Hill", - URL = "https://i.ibb.co/N7Lk7jc/Arkham-French-Hill-Cristi-Balanescu.jpg" - }, { - Name = "Merchant District", - URL = "https://i.ibb.co/HTNCCq4/Arkham-Merchant-District-Jokubas-Uogintas.jpg" - }, { - Name = "Generic 1", - URL = "https://i.ibb.co/hswfZD6/Arkham-Guillem-H-Pongiluppi.jpg" - }, { - Name = "Generic 2", - URL = "https://i.ibb.co/5h5cMyF/Arkham-Guillem-H-Pongiluppi-2.jpg" - }, { - Name = "Generic 3", - URL = "https://i.ibb.co/ZBdVsWt/Arkham-Guillem-H-Pongiluppi-3.jpg" - }, { - Name = "Generic 4", - URL = "https://i.ibb.co/6NwbM59/Arkham-Michele-Botticelli.jpg" - }, { - Name = "Generic 5", - URL = "https://i.ibb.co/N6sxyq5/Arkham-Mihail-Bila.jpg" - }, { - Name = "Generic 6", - URL = "https://i.ibb.co/B393zxv/Arkham-Tomasz-Jedruszek.jpg" - }, { - Name = "Generic 7", - URL = "https://i.ibb.co/2WQ2Vt6/Arkham-Tomasz-Jedruszek-2.jpg" - }, { - Name = "Generic 8", - URL = "https://i.ibb.co/R7pQ9Y7/Arkham-Tomasz-Jedruszek-3.jpg" - }, { - Name = "Miskatonic University", - URL = "https://i.ibb.co/ncz9xjP/Arkham-Miskatonic-University-Jokubas-Uogintas.jpg" - }, { - Name = "Northside", - URL = "https://i.ibb.co/sVWx1R3/Arkham-Northside-Jokubas-Uogintas.jpg" - }, { - Name = "Rivertown", - URL = "https://i.ibb.co/RyJnHmz/Arkham-Rivertown-Jokubas-Uogintas.jpg" - }, { - Name = "Southside", - URL = "https://i.ibb.co/5GW5jg5/Arkham-Southside-Jokubas-Uogintas.jpg" - }, { - Name = "Uptown", - URL = "https://i.ibb.co/YXjvkMn/Arkham-Uptown-Jokubas-Uogintas.jpg" - } }, - ["Side Scenarios"] = { { - Name = "Blob That Ate Everything 1", - URL = "https://i.ibb.co/JxFV4ZN/Blob-That-Ate-Everything-Emilio-Rodriguez.jpg" - }, { - Name = "Blob That Ate Everything 2", - URL = "https://i.ibb.co/qJzstWF/Blob-That-Ate-Everything-Emilio-Rodriguez.jpg" - }, { - Name = "Carnevale of Horrors 1", - URL = "https://i.ibb.co/ZchJBpz/Carnevale-of-Horrors.jpg" - }, { - Name = "Curse of the Rougarou 1", - URL = "https://i.ibb.co/Qf7Sr7P/Curse-of-the-Rougarou.jpg" - }, { - Name = "Curse of the Rougarou 2", - URL = "https://i.ibb.co/hs1Qjp0/Curse-of-the-Rougarou-Ann-Kovaleva.jpg" - }, { - Name = "Curse of the Rougarou 3", - URL = "https://i.ibb.co/BK7rmJ9/Curse-of-the-Rougarou-Karine-Villette.jpg" - }, { - Name = "Curse of the Rougarou 4", - URL = "https://i.ibb.co/ZxGTC1w/Curse-of-the-Rougarou-Lachlan-Page.jpg" - }, { - Name = "Curse of the Rougarou 5", - URL = "https://i.ibb.co/HgNXJhW/Curse-of-the-Rougarou-Vladimir-Manyukhin.jpg" - }, { - Name = "Guardians of the Abyss 1", - URL = "https://i.ibb.co/gD3R6cw/Guardians-of-the-Abyss-Jake-Murray.jpg" - }, { - Name = "Guardians of the Abyss 2", - URL = "https://i.ibb.co/jMHPcvz/Guardians-of-the-Abyss-Jose-Vega.jpg" - }, { - Name = "Guardians of the Abyss 3", - URL = "https://i.ibb.co/99pqXQP/Guardians-of-the-Abyss-Koke-Nunez.jpg" - }, { - Name = "Guardians of the Abyss 4", - URL = "https://i.ibb.co/QbMvjbx/Guardians-of-the-Abyss-Mike-Szabados.jpg" - }, { - Name = "Guardians of the Abyss 5", - URL = "https://i.ibb.co/zFDt9Q8/Guardians-of-the-Abyss-Nele-Diel.jpg" - }, { - Name = "Guardians of the Abyss 6", - URL = "https://i.ibb.co/Vpzptmt/Guardians-of-the-Abyss-Yujin-Choo.jpg" - }, { - Name = "Kingsport", - URL = "https://i.ibb.co/rbkk7ys/Kingsport-Tomasz-Jedruszek.jpg" - }, { - Name = "Labyrinths of Lunacy 1", - URL = "https://i.ibb.co/f17PMCC/Labyrinths-of-Lunacy-Cordelia-Wolf.jpg" - }, { - Name = "Labyrinths of Lunacy 2", - URL = "https://i.ibb.co/44DXfWw/Labyrinths-of-Lunacy-Richard-Wright.jpg" - }, { - Name = "Labyrinths of Lunacy 3", - URL = "https://i.ibb.co/jMQhs68/Labyrinths-of-Lunacy-Robert-Berg.jpg" - }, { - Name = "Murder at Excelsior Hotel 1", - URL = "https://i.ibb.co/5cQ6LvN/Murder-at-Excelsior-Hotel-Alistair-Mitchell.jpg" - }, { - Name = "Murder at Excelsior Hotel 2", - URL = "https://i.ibb.co/vBQRHNS/Murder-at-Excelsior-Hotel-Romain-Bayle.jpg" - }, { - Name = "War of the Outer Gods", - URL = "https://i.ibb.co/wLNGFTG/War-of-the-Outer-Gods-Joshua-Cairos.jpg" - } }, - ["The Path to Carcosa"] = { { - Name = "I - Curtain Call", - URL = "https://i.ibb.co/TcnKXJD/Carcosa-1-Curtain-Call-Mark-Molnar.jpg" - }, { - Name = "II - Last King 1", - URL = "https://i.ibb.co/JRQJKR8/Carcosa-2-Last-King-Cristi-Balanescu.jpg" - }, { - Name = "II - Last King 2", - URL = "https://i.ibb.co/NZzBwgv/Carcosa-2-Last-King-Cristi-Balanescu-2.jpg" - }, { - Name = "II - Last King 3", - URL = "https://i.ibb.co/x56ZHt7/Carcosa-2-Last-King-Wu-Mengjia.jpg" - }, { - Name = "III - Echoes of the Past", - URL = "https://i.ibb.co/R6gSm0D/Carcosa-3-Echoes-of-the-Past-Heather-Savage.jpg" - }, { - Name = "IV - Unspeakable Oath 1", - URL = "https://i.ibb.co/DzzDQQQ/Carcosa-4-Unspeakable-Oath.jpg" - }, { - Name = "IV - Unspeakable Oath 2", - URL = "https://i.ibb.co/9gqBzXr/Carcosa-4-Unspeakable-Oath-2-Mark-Molnar.jpg" - }, { - Name = "IV - Unspeakable Oath 3", - URL = "https://i.ibb.co/wWL73c9/Carcosa-4-Unspeakable-Oath-Paul-Fairbairn.jpg" - }, { - Name = "V - Phantom of Truth 1", - URL = "https://i.ibb.co/mzpz1Dd/Carcosa-5-Phantom-of-Truth-Lucas-Staniec.jpg" - }, { - Name = "V - Phantom of Truth 2", - URL = "https://i.ibb.co/Vp1wNbT/Carcosa-5-Phantom-of-Truth-Tomasz-Jedruszek.jpg" - }, { - Name = "VI - Pallid Mask 1", - URL = "https://i.ibb.co/Bf5LByY/Carcosa-6-Pallid-Mask-Greg-Bobrowski.jpg" - }, { - Name = "VI - Pallid Mask 2", - URL = "https://i.ibb.co/1v1J9Xx/Carcosa-6-Pallid-Mask-Rafal-Pyra.jpg" - }, { - Name = "VII - Black Star Rises 1", - URL = "https://i.ibb.co/TB451t7/Carcosa-7-Black-Star-Rises-Audric-Gatoux.jpg" - }, { - Name = "VII - Black Star Rises 2", - URL = "https://i.ibb.co/nC8Ncxx/Carcosa-7-Black-Star-Rises-Chris-Kintner.jpg" - }, { - Name = "VIII - Dim Carcosa 1", - URL = "https://i.ibb.co/QvS4y3D/Carcosa-8-Dim-Carcosa-Alexandr-Elichev.jpg" - }, { - Name = "VIII - Dim Carcosa 2", - URL = "https://i.ibb.co/hR95x7k/Carcosa-8-Dim-Carcosa-Yuri-Shepherd.jpg" - } }, - ["The Circle Undone"] = { { - Name = "0 - Prologue", - URL = "https://i.ibb.co/gm4C6yy/Circle-Undone-0-Prologue-Ted-Galaday.jpg" - }, { - Name = "I - Witching Hour", - URL = "https://i.ibb.co/kgJ34WS/Circle-Undone-1-Witching-Hour-Nele-Diel.jpg" - }, { - Name = "II - At Death's Doorstep 1", - URL = "https://i.ibb.co/qNWzH0Y/Circle-Undone-2-At-Death-039-s-Doorstep-Emilio-Rodriguez.jpg" - }, { - Name = "II - At Death's Doorstep 2", - URL = "https://i.ibb.co/T1zp1QN/Circle-Undone-2-At-Death-039-s-Doorstep-Emilio-Rodriguez-2.jpg" - }, { - Name = "II - At Death's Doorstep 3", - URL = "https://i.ibb.co/ZJfYZ1w/Circle-Undone-2-At-Death-039-s-Doorstep-Majid-Azim.jpg" - }, { - Name = "III - The Secret Name 1", - URL = "https://i.ibb.co/hsBw4JQ/Circle-Undone-3-Secret-Name-Jeff-Jumper.jpg" - }, { - Name = "III - The Secret Name 2", - URL = "https://i.ibb.co/MpcPXR5/Circle-Undone-3-Secret-Name-Pierre-Santamaria.jpg" - }, { - Name = "III - The Secret Name 3", - URL = "https://i.ibb.co/LQ8rdKs/Circle-Undone-3-The-Secret-Name-Greg-Bobrowski.jpg" - }, { - Name = "III - The Secret Name 4", - URL = "https://i.ibb.co/0D7LzxV/Circle-Undone-3-The-Secret-Name-Robert-Laskey.jpg" - }, { - Name = "IV - Wages of Sin 1", - URL = "https://i.ibb.co/fDMqH1C/Circle-Undone-4-Wages-of-Sin-Emilio-Rodriguez.jpg" - }, { - Name = "IV - Wages of Sin 2", - URL = "https://i.ibb.co/HDrKkZF/Circle-Undone-4-Wages-of-Sin-Emilio-Rodriguez-2.jpg" - }, { - Name = "IV - Wages of Sin 3", - URL = "https://i.ibb.co/vkpG8cM/Circle-Undone-4-Wages-of-Sin-Greg-Bobrowski.jpg" - }, { - Name = "IV - Wages of Sin 4", - URL = "https://i.ibb.co/CMj007q/Circle-Undone-4-Wages-of-Sin-Mateusz-Michalski.jpg" - }, { - Name = "IV - Wages of Sin 5", - URL = "https://i.ibb.co/sj1bS5x/Circle-Undone-4-Wages-of-Sin-Serge-Da-Silva-Dias.jpg" - }, { - Name = "V - For the Greater Good 1", - URL = "https://i.ibb.co/LDyqjbj/Circle-Undone-5-For-the-Greater-Good.jpg" - }, { - Name = "V - For the Greater Good 2", - URL = "https://i.ibb.co/pPzXNd1/Circle-Undone-5-For-the-Greater-Good-2.jpg" - }, { - Name = "V - For the Greater Good 3", - URL = "https://i.ibb.co/8rMLvJH/Circle-Undone-5-For-the-Greater-Good-Greg-Bobrowski.jpg" - }, { - Name = "V - For the Greater Good 4", - URL = "https://i.ibb.co/vj1q4Cm/Circle-Undone-5-For-the-Greater-Good-Robert-Laskey.jpg" - }, { - Name = "VI - Union and Disillusioned", - URL = "https://i.ibb.co/n7SD1tB/Circle-Undone-6-Union-amp-Disillusioned-Andreas-Rocha.jpg" - }, { - Name = "VII - In the Clutches of Chaos 1", - URL = "https://i.ibb.co/bFXBNh7/Circle-Undone-7-In-the-Clutches-of-Chaos.jpg" - }, { - Name = "VII - In the Clutches of Chaos 2", - URL = "https://i.ibb.co/m6DshNg/Circle-Undone-7-In-the-Clutches-of-Chaos-Alexandr-Elichev.jpg" - }, { - Name = "VII - In the Clutches of Chaos 3", - URL = "https://i.ibb.co/k2p4yfG/Circle-Undone-7-In-the-Clutches-of-Chaos-Jokubas-Uogintas.jpg" - }, { - Name = "VIII - Before the Black Throne 1", - URL = "https://i.ibb.co/9TPwvP6/Circle-Undone-8-Before-the-Black-Throne-Aaron-Luke-Wilson.jpg" - }, { - Name = "VIII - Before the Black Throne 2", - URL = "https://i.ibb.co/VNtgH4v/Circle-Undone-8-Before-the-Black-Throne-Greg-Bobrowski.jpg" - } }, - ["Side Scenarios (FM)"] = { { - Name = "Consternation on the Constellation", - URL = "https://i.ibb.co/Tw2xBP1/Consternation-Constellation.jpg" - }, { - Name = "Symphony of Erich Zann", - URL = "https://i.ibb.co/SNr8tqN/Symphony-of-Erich-Zann-Hazel-Yingling.jpg" - } }, - ["Cyclopean Foundations (FM)"] = { { - Name = "I - Lost Moorings 1", - URL = "https://i.ibb.co/DQ76z3c/Cyclopean-1-Lost-Moorings-Care-Line-Art.png" - }, { - Name = "I - Lost Moorings 2", - URL = "https://i.ibb.co/c6LJNfr/Cyclopean-1-Lost-Moorings-Jake-Murray.png" - }, { - Name = "II - Going Twice", - URL = "https://i.ibb.co/P6h3vbm/Cyclopean-2-Going-Twice-Quentin-Bouilloud.png" - }, { - Name = "III - Private Lives", - URL = "https://i.ibb.co/9qK9Fzd/Cyclopean-3-Private-Lives-Christian-Bravery.png" - }, { - Name = "IV - Crumbling Masonry 1", - URL = "https://i.ibb.co/pdrGK6p/Cyclopean-4-Crumbling-Masonry-Pete-Amachree.png" - }, { - Name = "IV - Crumbling Masonry 2", - URL = "https://i.ibb.co/5RFcGyP/Cyclopean-4-Crumbling-Masonry-Simon-Craghead.png" - }, { - Name = "V - Across Dreadful Waters", - URL = "https://i.ibb.co/3mYfFNB/Cyclopean-5-Across-Dreadful-Waters-Ev-Shipard.png" - }, { - Name = "VI - Blood From Stones", - URL = "https://i.ibb.co/ynmQNSB/Cyclopean-6-Blood-From-Stones-Marc-Simonetti.png" - }, { - Name = "VII - Pyroclastic Flow 1", - URL = "https://i.ibb.co/s1JDkFv/Cyclopean-7-Pyroclastic-Flow-Bastien-Grivet.png" - }, { - Name = "VII - Pyroclastic Flow 2", - URL = "https://i.ibb.co/qs8Sk2N/Cyclopean-7-Pyroclastic-Flow-Rachid-Lotf.png" - }, { - Name = "VIII - Tomb of Dead Dreams 1", - URL = "https://i.ibb.co/0MwX460/Cyclopean-8-Tomb-of-Dead-Dreams-Guillem-H-Pongiluppi.png" - }, { - Name = "VIII - Tomb of Dead Dreams 2", - URL = "https://i.ibb.co/mGnKNcy/Cyclopean-8-Tomb-of-Dead-Dreams-Richard-Benning.png" - }, { - Name = "VIII - Tomb of Dead Dreams 3", - URL = "https://i.ibb.co/vmBM8x2/Cyclopean-8-Tomb-of-Dead-Dreams-Walter-Brocca.png" - } }, - ["Dark Matter (FM)"] = { { - Name = "I - Tatterdemalion 1", - URL = "https://i.ibb.co/DRMPGVt/Dark-Matter-1-Tatterdemalion-Andrey-Vozny.jpg" - }, { - Name = "I - Tatterdemalion 2", - URL = "https://i.ibb.co/1JzrrX2/Dark-Matter-1-Tatterdemalion-Brian-Taylor.jpg" - }, { - Name = "I - Tatterdemalion 3", - URL = "https://i.ibb.co/DzvvgGf/Dark-Matter-1-Tatterdemalion-John-Wallin-Liberto.jpg" - }, { - Name = "I - Tatterdemalion 4", - URL = "https://i.ibb.co/sQf85b8/Dark-Matter-1-Tatterdemalion-Paul-Pepera.jpg" - }, { - Name = "II - Electric Nightmares 1", - URL = "https://i.ibb.co/hLGVBt7/Dark-Matter-2-Electric-Nightmares-Dean-Lawrence.jpg" - }, { - Name = "II - Electric Nightmares 2", - URL = "https://i.ibb.co/cTKZQ61/Dark-Matter-2-Electric-Nightmares-Robert-Thoma.jpg" - }, { - Name = "IIIa - Lost Quantum", - URL = "https://i.ibb.co/6vyXv90/Dark-Matter-3-Lost-Quantum-Michael-Rajecki.jpg" - }, { - Name = "IIIb - In the Shadow of Earth 1", - URL = "https://i.ibb.co/DfbTKHP/Dark-Matter-4-In-the-Shadow-of-Earth-Jihoo-Kim.jpg" - }, { - Name = "IIIb - In the Shadow of Earth 2", - URL = "https://i.ibb.co/MCvPmCb/Dark-Matter-4-In-the-Shadow-of-Earth-N5-Luckybuuncle.jpg" - }, { - Name = "IIIc - Strange Moons", - URL = "https://i.ibb.co/b2d8qvg/Dark-Matter-5-Strange-Moons-Hongyu-Yin.jpg" - }, { - Name = "V - Fragment of Carcosa 1", - URL = "https://i.ibb.co/7WnTyYT/Dark-Matter-7-Fragment-of-Carcosa-Colin-Moore.jpg" - }, { - Name = "V - Fragment of Carcosa 2", - URL = "https://i.ibb.co/mG2Brrd/Dark-Matter-7-Fragments-of-Carcosa-Matthieu-Rebuffat.jpg" - }, { - Name = "VI - Starfall 1", - URL = "https://i.ibb.co/CJ3LKL7/Dark-Matter-8-Starfall-Vadim-Sadovski.jpg" - }, { - Name = "VI - Starfall 2", - URL = "https://i.ibb.co/Njd1FcB/Dark-Matter-8-Starfall-Vadim-Sadovski-2.jpg" - }, { - Name = "VI - Starfall 3", - URL = "https://i.ibb.co/W0Cx7bb/Dark-Matter-8-Starfall-Vadim-Sadovski-3.jpg" - } }, - ["The Dream-Eaters"] = { { - Name = "I-A - Beyond the Gates of Sleep 1", - URL = "https://i.ibb.co/S6sCy7G/Dream-Eaters-1-A-Beyond-the-Gates-of-Sleep-Phoebe-Herring.jpg" - }, { - Name = "I-A - Beyond the Gates of Sleep 2", - URL = "https://i.ibb.co/kBfW9SC/Dream-Eaters-1-A-Beyond-the-Gates-of-Sleep-Regina-Kurnya.jpg" - }, { - Name = "I-A - Beyond the Gates of Sleep 3", - URL = "https://i.ibb.co/HGvnxdX/Dream-Eaters-1-A-Beyond-the-Gates-of-Sleep-Jason-Scheier.jpg" - }, { - Name = "I-B - Waking Nightmare", - URL = "https://i.ibb.co/sWsZCv8/Dream-Eaters-1-B-Waking-Nightmare-Josh-Gould-jpg.jpg" - }, { - Name = "II-A - Search for Kadath 1", - URL = "https://i.ibb.co/4SwzCD8/Dream-Eaters-2-A-Search-for-Kadath-Andrei-Khrutskii.jpg" - }, { - Name = "II-A - Search for Kadath 2", - URL = "https://i.ibb.co/WpZ4fMc/Dream-Eaters-2-A-Search-for-Kadath-Dan-Iorgulescu.jpg" - }, { - Name = "II-A - Search for Kadath 3", - URL = "https://i.ibb.co/jwsn0jf/Dream-Eaters-2-A-Search-for-Kadath-Diana-Tsareva.jpg" - }, { - Name = "II-A - Search for Kadath 4", - URL = "https://i.ibb.co/pd9vxmL/Dream-Eaters-2-A-Search-for-Kadath-Helen-Ilnytska.jpg" - }, { - Name = "II-A - Search for Kadath 5", - URL = "https://i.ibb.co/MZ7Qtcc/Dream-Eaters-2-A-Search-for-Kadath-Nele-Diel.jpg" - }, { - Name = "II-B - Thousand Shapes of Horror 1", - URL = "https://i.ibb.co/9s7M0PP/Dream-Eaters-2-B-Thousand-Shapes-of-Horror-Nele-Diel-2.jpg" - }, { - Name = "II-B - Thousand Shapes of Horror 2", - URL = "https://i.ibb.co/T4Pqx0H/Dream-Eaters-2-B-Thousand-Shapes-of-Horror-Nele-Diel.jpg" - }, { - Name = "II-B - Thousand Shapes of Horror 3", - URL = "https://i.ibb.co/VJFQVYd/Dream-Eaters-2-B-Thousand-Shapes-of-Horror-Greg-Bobrowski.jpg" - }, { - Name = "III-A - Dark Side of the Moon 1", - URL = "https://i.ibb.co/B2DfXLZ/Dream-Eaters-3-A-Dark-Side-of-the-Moon-Dabanli.jpg" - }, { - Name = "III-A - Dark Side of the Moon 2", - URL = "https://i.ibb.co/c27JRvv/Dream-Eaters-3-A-Dark-Side-of-the-Moon-Frej-Agelii.jpg" - }, { - Name = "III-B - Point of No Return 1", - URL = "https://i.ibb.co/dMGNB9Y/Dream-Eaters-3-B-Point-of-No-Return-Daria-Khlebnikova.jpg" - }, { - Name = "III-B - Point of No Return 2", - URL = "https://i.ibb.co/dpXxPmz/Dream-Eaters-3-B-Point-of-No-Return-Karine-Villette.jpg" - }, { - Name = "IV-A - Where the Gods Dwell", - URL = "https://i.ibb.co/v4nqw6G/Dream-Eaters-4-A-Where-the-Gods-Dwell-Samantha-Franco.jpg" - }, { - Name = "IV-B - Weaver of the Cosmos 1", - URL = "https://i.ibb.co/7btNBS1/Dream-Eaters-4-B-Weaver-of-the-Cosmos-Diana-Franco.jpg" - }, { - Name = "IV-B - Weaver of the Cosmos 2", - URL = "https://i.ibb.co/RY7y22b/Dream-Eaters-4-B-Weaver-of-the-Cosmos-Leanna-Crossan.jpg" - }, { - Name = "IV-B - Weaver of the Cosmos 3", - URL = "https://i.ibb.co/f8LBbFW/Dream-Eaters-4-B-Weaver-of-the-Cosmos-Nele-Diel.jpg" - } }, - ["The Dunwich Legacy"] = { { - Name = "I-A - Extracurricular Activity 1", - URL = "https://i.ibb.co/tDxX8KS/Dunwich-1-Extracurricular-Activity-Igor-Kirdeika.jpg" - }, { - Name = "I-A - Extracurricular Activity 2", - URL = "https://i.ibb.co/RQ6z0pj/Dunwich-1-Extracurricular-Activity-Joseph-Diaz.jpg" - }, { - Name = "I-A - Extracurricular Activity 3", - URL = "https://i.ibb.co/nnJdwL2/Dunwich-1-Extracurricular-Activity-Tomasz-Jedruszek.jpg" - }, { - Name = "I-B - House Always Wins 1", - URL = "https://i.ibb.co/8XPLdr9/Dunwich-2-House-Always-Wins-Jonny-Klein.jpg" - }, { - Name = "I-B - House Always Wins 2", - URL = "https://i.ibb.co/HtX95GK/Dunwich-2-House-Always-Wins-Robert-Laskey.jpg" - }, { - Name = "I-B - House Always Wins 3", - URL = "https://i.ibb.co/MCLP3Sz/Dunwich-2-House-Always-Wins-XX-l.jpg" - }, { - Name = "I-B - House Always Wins 4", - URL = "https://i.ibb.co/w7Pf5sd/Dunwich-2-House-Always-Wins-XX-l-2.jpg" - }, { - Name = "II - Miskatonic Museum 1", - URL = "https://i.ibb.co/x1Kf7qG/Dunwich-3-Miskatonic-Museum-Emre-Aktuna.jpg" - }, { - Name = "II - Miskatonic Museum 2", - URL = "https://i.ibb.co/yWXVPcN/Dunwich-3-Miskatonic-Museum-Richard-Wright.jpg" - }, { - Name = "III - Essex County Express", - URL = "https://i.ibb.co/602CMZb/Dunwich-4-Essex-County-Express-David-Alvarez.jpg" - }, { - Name = "IV - Blood on the Altar 1", - URL = "https://i.ibb.co/3CYHDhf/Dunwich-5-Blood-on-the-Altar.jpg" - }, { - Name = "IV - Blood on the Altar 2", - URL = "https://i.ibb.co/FbxcCY2/Dunwich-5-Blood-on-the-Altar-Chris-Ostrowski.jpg" - }, { - Name = "IV - Blood on the Altar 3", - URL = "https://i.ibb.co/sJf6YsZ/Dunwich-5-Blood-on-the-Altar-Lucas-Staniec.jpg" - }, { - Name = "IV - Blood on the Altar 4", - URL = "https://i.ibb.co/kBPNGBd/Dunwich-5-Blood-on-the-Altar-Mark-Molnar.jpg" - }, { - Name = "V - Undimensioned and Unseen 1", - URL = "https://i.ibb.co/QvfhjDv/Dunwich-6-Undimensioned-and-Unseen-Frej-Agelii.jpg" - }, { - Name = "V - Undimensioned and Unseen 2", - URL = "https://i.ibb.co/4VL9gSK/Dunwich-6-Undimensioned-and-Unseen-Lucas-Staniec.jpg" - }, { - Name = "V - Undimensioned and Unseen 3", - URL = "https://i.ibb.co/wBFsS8P/Dunwich-6-Undimensioned-and-Unseen-Michal-Teliga-jpg.jpg" - }, { - Name = "V - Undimensioned and Unseen 4", - URL = "https://i.ibb.co/wwGDcq6/Dunwich-6-Undimensioned-and-Unseen-Tomasz-Jedruszek.jpg" - }, { - Name = "VI - Where Doom Awaits 1", - URL = "https://i.ibb.co/TvMwqj4/Dunwich-7-Where-Doom-Awaits.jpg" - }, { - Name = "VI - Where Doom Awaits 2", - URL = "https://i.ibb.co/S6cSLH9/Dunwich-7-Where-Doom-Awaits-3.jpg" - }, { - Name = "VI - Where Doom Awaits 3", - URL = "https://i.ibb.co/khBX32g/Dunwich-7-Where-Doom-Awaits-4.jpg" - }, { - Name = "VI - Where Doom Awaits 4", - URL = "https://i.ibb.co/S0hcwN8/Dunwich-7-Where-Doom-Awaits-5.jpg" - }, { - Name = "VI - Where Doom Awaits 5", - URL = "https://i.ibb.co/Lxv1Bjp/Dunwich-7-Where-Doom-Awaits-Luca-Trentin.jpg" - }, { - Name = "VII - Lost in Time and Space 1", - URL = "https://i.ibb.co/rtTpbDx/Dunwich-8-Lost-in-Time-amp-Space.jpg" - }, { - Name = "VII - Lost in Time and Space 2", - URL = "https://i.ibb.co/dBXP0GL/Dunwich-8-Lost-in-Time-amp-Space-Chris-Ostrowski.jpg" - }, { - Name = "VII - Lost in Time and Space 3", - URL = "https://i.ibb.co/0XcnxFD/Dunwich-8-Lost-in-Time-amp-Space-Lino-Drieghe.jpg" - } }, - ["Edge of the Earth"] = { { - Name = "I - Ice and Death 1", - URL = "https://i.ibb.co/FWZMWtW/Edge-1-Ice-and-Death-David-Frasheski.png" - }, { - Name = "I - Ice and Death 2", - URL = "https://i.ibb.co/QDGV0jQ/Edge-1-Ice-and-Death-Felix-Riano.png" - }, { - Name = "I - Ice and Death 3", - URL = "https://i.ibb.co/hFJQM8v/Edge-1-Ice-and-Death-Mike-Gizienski.png" - }, { - Name = "??? - Fatal Mirage", - URL = "https://i.ibb.co/KzwvjJN/Edge-2-Fatal-Mirage-David-Frasheski.png" - }, { - Name = "II - Forbidden Peaks 1", - URL = "https://i.ibb.co/C2SLByt/Edge-2-Forbidden-Peaks-David-Frasheski-2.png" - }, { - Name = "II - Forbidden Peaks 2", - URL = "https://i.ibb.co/0cGkkBL/Edge-3-Forbidden-Peaks-David-Frasheski.png" - }, { - Name = "III - City of Elder Things 1", - URL = "https://i.ibb.co/FbpgBD3/Edge-4-City-Francois-Baranger.png" - }, { - Name = "III - City of Elder Things 2", - URL = "https://i.ibb.co/ncRvHr3/Edge-4-City-Francois-Baranger-2.png" - }, { - Name = "IV - Heart of Madness 1", - URL = "https://i.ibb.co/rk0qR4z/Edge-5-Heart-of-Madness-Karol-Sollich.png" - }, { - Name = "IV - Heart of Madness 2", - URL = "https://i.ibb.co/NVFjx6N/Edge-5-Heart-of-Madness-Miguel-Coimbra.png" - } }, - ["The Forgotten Age"] = { { - Name = "I - Untamed Wilds 1", - URL = "https://i.ibb.co/BLhwCG1/Forgotten-Age-1-Untamed-Wilds-David-Frasheski.jpg" - }, { - Name = "I - Untamed Wilds 2", - URL = "https://i.ibb.co/SnJfsNy/Forgotten-Age-1-Untamed-Wilds-David-Frasheski-2.jpg" - }, { - Name = "I - Untamed Wilds 3", - URL = "https://i.ibb.co/kcx1tvp/Forgotten-Age-1-Untamed-Wilds-Ethan-Patrick-Harris.jpg" - }, { - Name = "I - Untamed Wilds 4", - URL = "https://i.ibb.co/HPbJwXk/Forgotten-Age-1-Untamed-Wilds-Lucas-Staniec.jpg" - }, { - Name = "I - Untamed Wilds 5", - URL = "https://i.ibb.co/bbq1ZrK/Forgotten-Age-1-Untamed-Wilds-Nele-Diel.jpg" - }, { - Name = "II - Doom of Etzli 1", - URL = "https://i.ibb.co/Pw4by4q/Forgotten-Age-2-Doom-of-Eztli-Cristi-Balanescu.jpg" - }, { - Name = "II - Doom of Etzli 2", - URL = "https://i.ibb.co/xqW6cXR/Forgotten-Age-2-Doom-of-Eztli-Greg-Bobrowski.jpg" - }, { - Name = "II - Doom of Etzli 3", - URL = "https://i.ibb.co/kgsC3pb/Forgotten-Age-2-Doom-of-Eztli-Nele-Diel.jpg" - }, { - Name = "III - Threads of Fate", - URL = "https://i.ibb.co/Bn0Pjng/Forgotten-Age-3-Threads-of-Fate-Jokubas-Uogintas.jpg" - }, { - Name = "IV - Boundary Beyond 1", - URL = "https://i.ibb.co/yPZ9v2X/Forgotten-Age-4-Boundary-Beyond-Greg-Bobrowski-2-jpg.jpg" - }, { - Name = "IV - Boundary Beyond 2", - URL = "https://i.ibb.co/vm0JgFs/Forgotten-Age-4-Boundary-Beyond-Greg-Bobrowski-jpg.jpg" - }, { - Name = "IV - Boundary Beyond 3", - URL = "https://i.ibb.co/D1rh9Ry/Forgotten-Age-4-Boundary-Beyond-Nele-Diel.jpg" - }, { - Name = "V - Heart of the Elders I-1", - URL = "https://i.ibb.co/jzKvv6P/Forgotten-Age-5-Heart-of-the-Elders-I-Lucas-Staniec.jpg" - }, { - Name = "V - Heart of the Elders I-2", - URL = "https://i.ibb.co/mR79MX4/Forgotten-Age-5-Heart-of-the-Elders-I-Lucas-Staniec-2.jpg" - }, { - Name = "V - Heart of the Elders II", - URL = "https://i.ibb.co/pQSbL0t/Forgotten-Age-5-Heart-of-the-Elders-II-Nele-Diel.jpg" - }, { - Name = "VI - City of Archives 1", - URL = "https://i.ibb.co/f04DSPb/Forgotten-Age-6-City-of-Archives.jpg" - }, { - Name = "VI - City of Archives 2", - URL = "https://i.ibb.co/WsSBrYj/Forgotten-Age-6-City-of-Archives-2.jpg" - }, { - Name = "VI - City of Archives 3", - URL = "https://i.ibb.co/qdPbSZ8/Forgotten-Age-6-City-of-Archives-Chris-Ostrowski.jpg" - }, { - Name = "VII - Depths of Yoth 1", - URL = "https://i.ibb.co/dbLKgGv/Forgotten-Age-7-Depths-of-Yoth-Diego-Arbetta.jpg" - }, { - Name = "VII - Depths of Yoth 2", - URL = "https://i.ibb.co/NW7Wp98/Forgotten-Age-7-Depths-of-Yoth-Greg-Bobrowski.jpg" - }, { - Name = "VII - Depths of Yoth 3", - URL = "https://i.ibb.co/257zr7c/Forgotten-Age-7-Depths-of-Yoth-Greg-Bobrowski-2-jpg.jpg" - }, { - Name = "VIII - Shattered Aeons 1", - URL = "https://i.ibb.co/KwnWTGR/Forgotten-Age-8-Shattered-Aeons.jpg" - }, { - Name = "VIII - Shattered Aeons 2", - URL = "https://i.ibb.co/b7kVd4F/Forgotten-Age-8-Shattered-Aeons-Alexandr-Elichev.jpg" - } }, - ["The Innsmouth Conspiracy"] = { { - Name = "I - Pit of Despair 1", - URL = "https://i.ibb.co/2sc0F61/Innsmouth-1-Pit-of-Despair-Amanda-Castrillo.jpg" - }, { - Name = "I - Pit of Despair 2", - URL = "https://i.ibb.co/Nj9JLBQ/Innsmouth-1-Pit-of-Despair-J-Mill.jpg" - }, { - Name = "II - Vanishing of Elina Harper 1", - URL = "https://i.ibb.co/2j74cVn/Innsmouth-2-Vanishing-of-Elina-Harper-Konstantin-Vohwinkel.jpg" - }, { - Name = "II - Vanishing of Elina Harper 2", - URL = "https://i.ibb.co/r2VqHSn/Innsmouth-2-Vanishing-of-Elina-Harper-Mihail-Bila.jpg" - }, { - Name = "II - Vanishing of Elina Harper 3", - URL = "https://i.ibb.co/hFQMm7N/Innsmouth-2-Vanishing-of-Elina-Harper-Richard-Wright.jpg" - }, { - Name = "II - Vanishing of Elina Harper 4", - URL = "https://i.ibb.co/2nZKGN6/Innsmouth-2-Vanishing-of-Elina-Harper-Tomasz-Jedruszek-1.jpg" - }, { - Name = "II - Vanishing of Elina Harper 5", - URL = "https://i.ibb.co/WxLpKrM/Innsmouth-2-Vanishing-of-Elina-Harper-Tomasz-Jedruszek-2.jpg" - }, { - Name = "III - In Too Deep 1", - URL = "https://i.ibb.co/SsQ3my4/Innsmouth-3-In-Too-Deep-David-Frasheski.jpg" - }, { - Name = "III - In Too Deep 2", - URL = "https://i.ibb.co/jgQ8zQN/Innsmouth-3-In-Too-Deep-Klaudia-Bezak.jpg" - }, { - Name = "III - In Too Deep 3", - URL = "https://i.ibb.co/VVgtNM1/Innsmouth-3-In-Too-Deep-Patrik-Antonescu.jpg" - }, { - Name = "IV - Devil Reef 1", - URL = "https://i.ibb.co/Jrf6CJ0/Innsmouth-4-Devil-Reef-Ludovic-Sanson.jpg" - }, { - Name = "IV - Devil Reef 2", - URL = "https://i.ibb.co/4jfwDZR/Innsmouth-4-Devil-Reef-Marc-Stewart.jpg" - }, { - Name = "V - Horror in High Gear 1", - URL = "https://i.ibb.co/vqYJjYJ/Innsmouth-5-Horror-in-High-Gear-Greg-Bobrowski.jpg" - }, { - Name = "V - Horror in High Gear 2", - URL = "https://i.ibb.co/yYrzbYS/Innsmouth-5-Horror-in-High-Gear-Greg-Bobrowski-2.jpg" - }, { - Name = "V - Horror in High Gear 3", - URL = "https://i.ibb.co/fpKWhGY/Innsmouth-5-Horror-in-High-Gear-Guillem-H-Pongiluppi.jpg" - }, { - Name = "V - Horror in High Gear 4", - URL = "https://i.ibb.co/YkLFy7y/Innsmouth-5-Horror-in-High-Gear-Rostyslav-Zagornov.jpg" - }, { - Name = "VI - Light in the Fog 1", - URL = "https://i.ibb.co/v1rhgqJ/Innsmouth-6-Light-in-the-Fog-Florian-Aupetit.jpg" - }, { - Name = "VI - Light in the Fog 2", - URL = "https://i.ibb.co/Db2pRd6/Innsmouth-6-Light-in-the-Fog-JB-Caillet.jpg" - }, { - Name = "VII - Lair of Dagon 1", - URL = "https://i.ibb.co/QPwzQL5/Innsmouth-7-Lair-of-Dagon-Daria-Khlebnikova.jpg" - }, { - Name = "VII - Lair of Dagon 2", - URL = "https://i.ibb.co/MZBpCbs/Innsmouth-7-Lair-of-Dagon-Guillem-H-Pongiluppi.jpg" - }, { - Name = "VIII - Into the Maelstrom 1", - URL = "https://i.ibb.co/fkSXDgs/Innsmouth-8-Into-the-Maelstrom-Dimitri-Bielak.jpg" - }, { - Name = "VIII - Into the Maelstrom 2", - URL = "https://i.ibb.co/k56Dn9q/Innsmouth-8-Into-the-Maelstrom-Mateusz-Michalski.jpg" - } }, - ["Night of the Zealot"] = { { - Name = "I - The Gathering 1", - URL = "https://i.ibb.co/6NWqg1K/Zealot-Gathering.jpg" - }, { - Name = "III - Devourer Below 1", - URL = "https://i.ibb.co/x5QFzrx/Zealot-3-Devourer-Below-Helen-Castelow.png" - }, { - Name = "III - Devourer Below 2", - URL = "https://i.ibb.co/6r6LFGz/Zealot-3-Devourer-Below-Sarah-Miller.png" - } }, - ["The Ghosts of Onigawa (FM)"] = { { - Name = "I - The Ghosts of Onigawa", - URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-01.png?raw=true" - }, { - Name = "II - In The Shadow Of Mount Kokoro", - URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-02.png?raw=true" - }, { - Name = "III - The Onigawa River", - URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-03.png?raw=true" - }, { - Name = "IV - The Crimson Butterfly", - URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-04.png?raw=true" - }, { - Name = "V - The Koi Conspiracy", - URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-05.png?raw=true" - } }, - ["The Scarlet Keys"] = { { - Name = "5-A Riddles and Rain", - URL = "http://cloud-3.steamusercontent.com/ugc/2037357792057358580/E9E5FE4028C08B3D4883406821221B73C8B5B2C7/" - }, { - Name = "11-B Dead Heat", - URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566443853/CAD7771D90141EA6D5FFAFE1EC5E7AD9647C82DB/" - }, { - Name = "16-D Sanguine Shadows", - URL = "http://cloud-3.steamusercontent.com/ugc/2037357792057358704/4A7261EB31511467CBC46E876476DD205F528A4B/" - }, { - Name = "21-F Dealings in the Dark", - URL = "http://cloud-3.steamusercontent.com/ugc/2037357792057358816/7C9FE4C34CD0A7AE87EF054742D878F310C71AA7/" - }, { - Name = "28-I Dancing Mad", - URL = "http://cloud-3.steamusercontent.com/ugc/2037357792056955518/EAB857DD5629EC6A3078FB0A3A703B85B5F514B9/" - }, { - Name = "23-K On Thin Ice", - URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444026/EB5628E254AE25DA89A9C999EAAD995ECF67068E/" - }, { - Name = "38-N Dogs of War", - URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444199/194FD9A713907197471A55411AE300B62C5F5278/" - }, { - Name = "46-Q Shades of Suffering", - URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444330/3ED2CCE95DE933546E1B5CBBF445D773E6D65465/" - }, { - Name = "56-Y ???", - URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444450/FE4C335B0F72E83900A4EED0FD1A1D304D70D6B7/" - }, { - Name = "59-Z Congress of Keys I", - URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444576/5BB32469ED412D59BB0A46E57D226500B1D0568B/" - }, { - Name = "59-Z Congress of Keys II", - URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444690/B01A1FEAB57473D9B6DF11B92D62C214AA1C2C02/" - } } -} - -local verticalOffset = 0.5 - -local buttonParameters = {} -buttonParameters.function_owner = self -buttonParameters.width = 1200 -buttonParameters.height = 300 -buttonParameters.position = { x = -0.2, y = 0.06, z = -verticalOffset } - -local CycleIndex = 1 -local CycleList = { - "Arkham Locations", - "Night of the Zealot", - "The Dunwich Legacy", - "The Path to Carcosa", - "The Forgotten Age", - "The Circle Undone", - "The Dream-Eaters", - "The Innsmouth Conspiracy", - "Edge of the Earth", - "The Scarlet Keys", - "Side Scenarios", - "Cyclopean Foundations (FM)", - "Dark Matter (FM)", - "The Ghosts of Onigawa (FM)", - "Side Scenarios (FM)" -} - --- save the index of selected cycle and table with spawnData -function onSave() return JSON.encode({ CycleIndex, spawnData }) end - -function onLoad(savedData) - if savedData == nil then - print("Error: Saved Data was not found.") - else - local loadedData = JSON.decode(savedData) - CycleIndex = loadedData[1] - spawnData = loadedData[2] - end - - --spawnData = getObjectFromGUID("f4a462").getData() - - -- index 0: cycle selection button - buttonParameters.click_function = "selectCycle" - buttonParameters.tooltip = "Select a cycle" - buttonParameters.label = CycleList[CycleIndex] - buttonParameters.font_size = 90 - self.createButton(buttonParameters) - - -- index 1: display button - buttonParameters.click_function = "showImages" - buttonParameters.tooltip = "Right-Click to remove displayed tiles" - buttonParameters.label = "Display available images" - buttonParameters.position.z = buttonParameters.position.z + 2 * verticalOffset - self.createButton(buttonParameters) -end - --- open option dialog to select cycle -function selectCycle(_, color) - Player[color].showOptionsDialog("Select cycle:", CycleList, CycleIndex, optionCallback) -end - --- update CycleIndex based on selection in the option dialog -function optionCallback(_, optionIndex) - CycleIndex = optionIndex - self.editButton({ - index = 0, - label = CycleList[CycleIndex] - }) - showImages() -end - --- triggered by clicking the "display" button -function showImages(_, _, isRightClick) - removeImages() - - -- don't display new tiles when right-clicked - if isRightClick then return end - - local pos = self.getPosition() - local rot = self.getRotation() - local offset = 3.7 - pos.z = pos.z - 1 - offset - - -- loop over respective entries in DATA - for i, entry in ipairs(DATA[CycleList[CycleIndex]]) do - spawnData.CustomImage.ImageURL = entry.URL - spawnData.Nickname = entry.Name - - spawnObjectData({ - data = spawnData, - position = pos, - rotation = rot, - scale = { 0.9, 1, 0.9 } - }) - - -- display 20 tiles in a row, move then to next row - if i % 20 == 0 then - pos.x = pos.x - offset - pos.z = self.getPosition().z - 1 - offset - else - pos.z = pos.z - offset - end - end -end - --- remove already laid out image tiles by tag -function removeImages() - for _, tile in ipairs(getObjectsWithTag("ImageSwapperTile")) do - tile.destruct() - end -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("accessories/CustomPlaymatImages") -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Custom Playmat Images 004fe7.yaml b/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Custom Playmat Images 004fe7.yaml deleted file mode 100644 index 8e165417a..000000000 --- a/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Custom Playmat Images 004fe7.yaml +++ /dev/null @@ -1,63 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - b: 1 - g: 1 - r: 1 -CustomImage: - CustomToken: - MergeDistancePixels: 15 - Stackable: false - StandUp: false - Thickness: 0.1 - ImageScalar: 1 - ImageSecondaryURL: '' - ImageURL: http://cloud-3.steamusercontent.com/ugc/2026086584367391757/2E37A1020563AA528471DA7425B8E58343E2BAF7/ - WidthScale: 0 -Description: Change playmat image to a custom one made by Mint Tea Fan. -DragSelectable: true -GMNotes: '' -GUID: 004fe7 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Token Custom Playmat Images 004fe7.ttslua' -LuaScriptState: "[1,{\"AltLookAngle\":{\"x\":0,\"y\":0,\"z\":0},\"Autoraise\":true,\"ColorDiffuse\":{\"a\":1,\"b\":1,\"g\":1,\"r\":1},\"CustomImage\":{\"CustomToken\":{\"MergeDistancePixels\":15,\"Stackable\":false,\"StandUp\":false,\"Thickness\":0.1},\"ImageScalar\":1,\"ImageSecondaryURL\":\"\",\"ImageURL\":\"https://i.ibb.co/YXjvkMn/Arkham-Uptown-Jokubas-Uogintas.jpg\",\"WidthScale\":0},\"Description\":\"Click - the 'Apply' button to load this image.\",\"DragSelectable\":true,\"GMNotes\":\"\",\"Grid\":true,\"GridProjection\":false,\"GUID\":\"f4a462\",\"Hands\":true,\"HideWhenFaceDown\":false,\"IgnoreFoW\":false,\"LayoutGroupSortIndex\":0,\"Locked\":false,\"LuaScript\":\"function - onLoad()\\n local params = {}\\n params.click_function = 'updatePlayarea'\\n - \ params.function_owner = self\\n params.label = 'Apply'\\n params.tooltip - \ = 'Left-Click: Apply image\\\\nRight-Click: Revert to default'\\n params.position - \ = { 0, 0.06, -1.45 }\\n params.height = 300\\n params.width = - 675\\n params.color = { 0, 0, 0 }\\n params.font_size = 200\\n - \ params.font_color = { 1, 1, 1 }\\n self.createButton(params)\\nend\\n\\nfunction - updatePlayarea(_, _, isRightClick)\\n local imageswapper = getObjectFromGUID(\\\"b7b45b\\\")\\n\\n - \ -- error handling\\n if imageswapper == nil then\\n printToAll(\\\"Image - swapper could not be found!\\\", \\\"Orange\\\")\\n return\\n end\\n\\n -- - get default image when right-clicked, else load its own image\\n if isRightClick - then\\n imageswapper.call(\\\"updateSurface\\\")\\n else\\n imageswapper.call(\\\"updateSurface\\\", - self.getCustomObject().image)\\n end\\nend\\n\",\"LuaScriptState\":\"\",\"MeasureMovement\":false,\"Name\":\"Custom_Token\",\"Nickname\":\"Uptown\",\"Snap\":true,\"Sticky\":true,\"Tags\":[\"ImageSwapperTile\"],\"Tooltip\":true,\"Transform\":{\"posX\":0,\"posY\":2,\"posZ\":0,\"rotX\":0,\"rotY\":270,\"rotZ\":0,\"scaleX\":1,\"scaleY\":1,\"scaleZ\":1},\"Value\":0,\"XmlUI\":\"\"}]\r" -MeasureMovement: false -Name: Custom_Token -Nickname: Custom Playmat Images -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 44.32 - posY: 2.29 - posZ: -60.49 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1.33 - scaleY: 1 - scaleZ: 1.33 -Value: 0 -XmlUI: '' diff --git a/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Displacement Tool 0f1374.ttslua b/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Displacement Tool 0f1374.ttslua index 1c74ecd3f..ea6275c64 100644 --- a/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Displacement Tool 0f1374.ttslua +++ b/unpacked/Bag OptionPanel Source 830bd0/Custom_Token Displacement Tool 0f1374.ttslua @@ -92,110 +92,144 @@ function shift_down(color) playAreaApi.shiftContentsDown(color) end end) __bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end -- Returns the current value of the investigator counter from the playmat ---@return Integer. Number of investigators currently set on the counter PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") + return getInvestigatorCounter().getVar("val") end -- Updates the current value of the investigator counter from the playmat ---@param count Number of investigators to set on the counter PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) + getInvestigatorCounter().call("updateVal", count) end -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) end PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) end PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) end PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) end -- Reset the play area's tracking of which cards have had tokens spawned. PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") + return getPlayArea().call("resetSpawnedCards") end -- Event to be called when the current scenario has changed. ---@param scenarioName Name of the new scenario PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) end -- Sets this playmat's snap points to limit snapping to locations or not. -- If matchTypes is false, snap points will be reset to snap all cards. ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) end -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged -- cards before they're destroyed by entering the container PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) end -- counts the VP on locations in the play area PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") + return getPlayArea().call("countVP") end -- highlights all locations in the play area without metadata ---@param state Boolean True if highlighting should be enabled PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) + return getPlayArea().call("highlightMissingData", state) end -- highlights all locations in the play area with VP ---@param state Boolean True if highlighting should be enabled PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) + return getPlayArea().call("countVP", state) end -- Checks if an object is in the play area (returns true or false) PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) + return getPlayArea().call("isInPlayArea", object) end PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image + return getPlayArea().getCustomObject().image end PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) + return getPlayArea().call("updateSurface", url) end -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the -- data to the local token manager instance. ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) + getPlayArea().call("updateLocations", args) end PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") + return getPlayArea().getVar("customDataHelper") end return PlayAreaApi 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag Tarot Deck (Scripted) a230f9/Card Justice · XI c4282a.ttslua b/unpacked/Bag Tarot Deck (Scripted) a230f9/Card Justice · XI c4282a.ttslua index 85990f2b9..8fddee22b 100644 --- a/unpacked/Bag Tarot Deck (Scripted) a230f9/Card Justice · XI c4282a.ttslua +++ b/unpacked/Bag Tarot Deck (Scripted) a230f9/Card Justice · XI c4282a.ttslua @@ -41,9 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/Tarotcard") -end) __bundle_register("playercards/Tarotcard", function(require, _LOADED, __bundle_register, __bundle_modules) -- context menu to manually fix rotation function onLoad() @@ -68,4 +65,7 @@ function rotateSelfAndPreview() rotatePreview() end end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/Tarotcard") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The Chariot · VII f633db.ttslua b/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The Chariot · VII f633db.ttslua index 85990f2b9..8fddee22b 100644 --- a/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The Chariot · VII f633db.ttslua +++ b/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The Chariot · VII f633db.ttslua @@ -41,9 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/Tarotcard") -end) __bundle_register("playercards/Tarotcard", function(require, _LOADED, __bundle_register, __bundle_modules) -- context menu to manually fix rotation function onLoad() @@ -68,4 +65,7 @@ function rotateSelfAndPreview() rotatePreview() end end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/Tarotcard") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The High Priestess · II a6d017.ttslua b/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The High Priestess · II a6d017.ttslua index 8fddee22b..85990f2b9 100644 --- a/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The High Priestess · II a6d017.ttslua +++ b/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The High Priestess · II a6d017.ttslua @@ -41,6 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/Tarotcard") +end) __bundle_register("playercards/Tarotcard", function(require, _LOADED, __bundle_register, __bundle_modules) -- context menu to manually fix rotation function onLoad() @@ -65,7 +68,4 @@ function rotateSelfAndPreview() rotatePreview() end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/Tarotcard") -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The Star · XVII 37153b.ttslua b/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The Star · XVII 37153b.ttslua index 85990f2b9..8fddee22b 100644 --- a/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The Star · XVII 37153b.ttslua +++ b/unpacked/Bag Tarot Deck (Scripted) a230f9/Card The Star · XVII 37153b.ttslua @@ -41,9 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playercards/Tarotcard") -end) __bundle_register("playercards/Tarotcard", function(require, _LOADED, __bundle_register, __bundle_modules) -- context menu to manually fix rotation function onLoad() @@ -68,4 +65,7 @@ function rotateSelfAndPreview() rotatePreview() end end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playercards/Tarotcard") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model Souls of Darkness a94e6b.ttslua b/unpacked/BlockRectangle Placeholder Box Dummy a93466.ttslua similarity index 100% rename from unpacked/Custom_Model Souls of Darkness a94e6b.ttslua rename to unpacked/BlockRectangle Placeholder Box Dummy a93466.ttslua diff --git a/unpacked/BlockRectangle Placeholder Box Dummy a93466.yaml b/unpacked/BlockRectangle Placeholder Box Dummy a93466.yaml new file mode 100644 index 000000000..86e2acbf9 --- /dev/null +++ b/unpacked/BlockRectangle Placeholder Box Dummy a93466.yaml @@ -0,0 +1,41 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +ColorDiffuse: + b: 0.82353 + g: 0.20157 + r: 0 +Description: This dummy is there to hold the up-to-date script file for placeholder + boxes to be available for placeholder box spawning. +DragSelectable: true +GMNotes: '' +GUID: a93466 +Grid: true +GridProjection: false +Hands: false +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: true +LuaScript: !include 'BlockRectangle Placeholder Box Dummy a93466.ttslua' +LuaScriptState: '' +MeasureMovement: false +Name: BlockRectangle +Nickname: Placeholder Box Dummy +Snap: true +Sticky: true +Tooltip: true +Transform: + posX: 78 + posY: 1.65 + posZ: -33 + rotX: 0 + rotY: 0 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/Checker_black Arkham Deck Cutter 445115.ttslua b/unpacked/Checker_black Arkham Deck Cutter 445115.ttslua deleted file mode 100644 index ef9c31b55..000000000 --- a/unpacked/Checker_black Arkham Deck Cutter 445115.ttslua +++ /dev/null @@ -1,79 +0,0 @@ --- 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("util/DeckCutter") -end) -__bundle_register("util/DeckCutter", function(require, _LOADED, __bundle_register, __bundle_modules) --- cut 3 (6) cards from a deck if numpad 1 (2) is pressed -function onScriptingButtonDown(index, player_color) - if not (index >= 1 and index <= 2) then return end - - local count = index * 3 - local player = Player[player_color] - local object = player.getHoverObject() - - if not object then - broadcastToColor("Hover over a deck and try again.", player_color, "Orange") - return - end - if object.tag ~= "Deck" then - broadcastToColor("Hover over a deck and try again.", player_color, "Orange") - return - end - if count >= object.getQuantity() then - broadcastToColor("Deck is too small to cut " .. count .. " cards.", player_color, "Orange") - return - end - - local pos = object.positionToWorld(Vector(0, 0, -3.5)) - for _ = 1, count do - object.takeObject { - index = 0, - position = pos, - smooth = false - } - end -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Checker_white Token Spawn Tool 36b4ee.ttslua b/unpacked/Checker_white Token Spawn Tool 36b4ee.ttslua index 51661cc87..5b5254590 100644 --- a/unpacked/Checker_white Token Spawn Tool 36b4ee.ttslua +++ b/unpacked/Checker_white Token Spawn Tool 36b4ee.ttslua @@ -41,33 +41,197 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__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) +__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local OptionPanelApi = {} + + -- loads saved options + ---@param options Table New options table + OptionPanelApi.loadSettings = function(options) + return Global.call("loadSettings", options) + end + + -- returns option panel table + OptionPanelApi.getOptions = function() + return Global.getTable("optionPanel") + end + + return OptionPanelApi +end +end) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end + + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") + end + + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) + end + + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) + end + + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) + end + + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi +end +end) __bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local TokenSpawnTracker = { } - local SPAWN_TRACKER_GUID = "e3ffc9" + local TokenSpawnTracker = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getSpawnTracker() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSpawnTracker") + end TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("hasSpawnedTokens", cardGuid) + return getSpawnTracker().call("hasSpawnedTokens", cardGuid) end TokenSpawnTracker.markTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("markTokensSpawned", cardGuid) + return getSpawnTracker().call("markTokensSpawned", cardGuid) end TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetTokensSpawned", cardGuid) + return getSpawnTracker().call("resetTokensSpawned", cardGuid) end TokenSpawnTracker.resetAllAssetAndEvents = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllAssetAndEvents") + return getSpawnTracker().call("resetAllAssetAndEvents") end TokenSpawnTracker.resetAllLocations = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllLocations") + return getSpawnTracker().call("resetAllLocations") end TokenSpawnTracker.resetAll = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAll") + return getSpawnTracker().call("resetAll") end return TokenSpawnTracker @@ -138,6 +302,28 @@ function onScriptingButtonDown(index, playerColor) if stateID ~= nil and stateID ~= 1 then callback = function(spawned) spawned.setState(stateID) end end + -- check hovered object for "resourceCounter" tokens and increase them instead + elseif tokenType == "resourceCounter" then + local hoverObj = Player[playerColor].getHoverObject() + if hoverObj then + if tokenType == hoverObj.getMemo() then + hoverObj.call("addOrSubtract") + return + end + end + -- check hovered object for "damage" and "horror" tokens and increase them instead + elseif tokenType == "damage" or tokenType == "horror" then + local hoverObj = Player[playerColor].getHoverObject() + if hoverObj then + if tokenType == hoverObj.getMemo() then + local stateInfo = hoverObj.getStates() + local stateId = hoverObj.getStateId() + if stateId <= #stateInfo then + hoverObj.setState(stateId + 1) + return + end + end + end end tokenManager.spawnToken(position, tokenType, rotation, callback) @@ -145,6 +331,7 @@ end end) __bundle_register("core/token/TokenManager", function(require, _LOADED, __bundle_register, __bundle_modules) do + local guidReferenceApi = require("core/GUIDReferenceApi") local optionPanelApi = require("core/OptionPanelApi") local playAreaApi = require("core/PlayAreaApi") local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") @@ -265,15 +452,10 @@ do ["supply"] = 7 } - -- Source for tokens - local TOKEN_SOURCE_GUID = "124381" - -- Table of data extracted from the token source bag, keyed by the Memo on each token which -- should match the token type keys ("resource", "clue", etc) local tokenTemplates - local DATA_HELPER_GUID = "708279" - local playerCardData local locationData @@ -371,9 +553,11 @@ do -- Copy the offsets to make sure we don't change the static values local baseOffsets = offsets offsets = { } + + -- get a vector for the shifting (downwards local to the card) + local shiftDownVector = Vector(0, 0, shiftDown):rotateOver("y", card.getRotation().y) for i, baseOffset in ipairs(baseOffsets) do - offsets[i] = baseOffset - offsets[i][3] = offsets[i][3] + shiftDown + offsets[i] = baseOffset + shiftDownVector end end @@ -486,8 +670,8 @@ do if tokenTemplates ~= nil then return end - tokenTemplates = { } - local tokenSource = getObjectFromGUID(TOKEN_SOURCE_GUID) + tokenTemplates = {} + local tokenSource = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSource") for _, tokenTemplate in ipairs(tokenSource.getData().ContainedObjects) do local tokenName = tokenTemplate.Memo tokenTemplates[tokenName] = tokenTemplate @@ -499,7 +683,7 @@ do if playerCardData ~= nil then return end - local dataHelper = getObjectFromGUID(DATA_HELPER_GUID) + local dataHelper = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") playerCardData = dataHelper.getTable('PLAYER_CARD_DATA') locationData = dataHelper.getTable('LOCATIONS_DATA') end @@ -514,18 +698,16 @@ do if uses == nil then return end -- go through tokens to spawn - local type, token, tokenCount + local tokenCount for i, useInfo in ipairs(uses) do - type = useInfo.type - token = useInfo.token - tokenCount = (useInfo.count or 0) - + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() - if extraUses ~= nil and extraUses[type] ~= nil then - tokenCount = tokenCount + extraUses[type] + tokenCount = (useInfo.count or 0) + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() + if extraUses ~= nil and extraUses[useInfo.type] ~= nil then + tokenCount = tokenCount + extraUses[useInfo.type] end -- Shift each spawned group after the first down so they don't pile on each other - TokenManager.spawnTokenGroup(card, token, tokenCount, (i - 1) * 0.8, type) + TokenManager.spawnTokenGroup(card, useInfo.token, tokenCount, (i - 1) * 0.8, useInfo.type) end + tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -549,9 +731,8 @@ do ---@param playerData Table Player card data structure retrieved from the DataHelper. Should be -- the right data for this card. internal.spawnPlayerCardTokensFromDataHelper = function(card, playerData) - token = playerData.tokenType - tokenCount = playerData.tokenCount - --log("Spawning data helper tokens for "..card.getName()..'['..card.getDescription()..']: '..tokenCount.."x "..token) + local token = playerData.tokenType + local tokenCount = playerData.tokenCount TokenManager.spawnTokenGroup(card, token, tokenCount) tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -584,7 +765,6 @@ do return 0 end - --log(card.getName() .. ' : ' .. locationData.type .. ' : ' .. locationData.value .. ' : ' .. locationData.clueSide) if ((card.is_face_down and locationData.clueSide == 'back') or (not card.is_face_down and locationData.clueSide == 'front')) then if locationData.type == 'fixed' then @@ -694,130 +874,4 @@ do return TokenManager end end) -__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local OptionPanelApi = {} - - -- loads saved options - ---@param options Table New options table - OptionPanelApi.loadSettings = function(options) - return Global.call("loadSettings", options) - end - - -- returns option panel table - OptionPanelApi.getOptions = function() - return Global.getTable("optionPanel") - end - - return OptionPanelApi -end -end) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" - - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") - end - - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) - end - - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) - end - - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) - end - - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) - end - - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) - end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") - end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi -end -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Checker_white Token Spawn Tracker e3ffc9.ttslua b/unpacked/Checker_white Token Spawn Tracker e3ffc9.ttslua index 705893be3..8e2f0e046 100644 --- a/unpacked/Checker_white Token Spawn Tracker e3ffc9.ttslua +++ b/unpacked/Checker_white Token Spawn Tracker e3ffc9.ttslua @@ -41,30 +41,22 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/token/TokenSpawnTracker") +end) __bundle_register("core/token/TokenSpawnTracker", function(require, _LOADED, __bundle_register, __bundle_modules) -local spawnedCardGuids = { } +local spawnedCardGuids = {} -local HAND_ZONES = { } -HAND_ZONES["a70eee"] = true -- White -HAND_ZONES["0285cc"] = true -- Green -HAND_ZONES["5fe087"] = true -- Orange -HAND_ZONES["be2f17"] = true -- Red +function onSave() return JSON.encode({ cards = spawnedCardGuids }) end function onLoad(saveState) if saveState ~= nil then - local saveTable = JSON.decode(saveState) or { } - spawnedCardGuids = saveTable.cards or { } + local saveTable = JSON.decode(saveState) or {} + spawnedCardGuids = saveTable.cards or {} end - createResetMenuItems() end -function onSave() - return JSON.encode({ - cards = spawnedCardGuids - }) -end - function createResetMenuItems() self.addContextMenuItem("Reset All", resetAll) self.addContextMenuItem("Reset Locations", resetAllLocations) @@ -83,14 +75,20 @@ function resetTokensSpawned(cardGuid) spawnedCardGuids[cardGuid] = nil end -function resetAllAssetAndEvents() - local resetList = { } +function resetAll() spawnedCardGuids = {} end + +function resetAllLocations() resetSpecificTypes("Location") end + +function resetAllAssetAndEvents() resetSpecificTypes("Asset", "Event") end + +function resetSpecificTypes(type1, type2) + local resetList = {} for cardGuid, _ in pairs(spawnedCardGuids) do local card = getObjectFromGUID(cardGuid) if card ~= nil then - local cardMetadata = JSON.decode(card.getGMNotes()) or { } + local cardMetadata = JSON.decode(card.getGMNotes()) or {} -- Check this by type rather than the PlayerCard tag so we don't reset weaknesses - if cardMetadata.type == "Asset" or cardMetadata.type == "Event" then + if cardMetadata.type == type1 or cardMetadata.type == type2 then resetList[cardGuid] = true end end @@ -100,35 +98,11 @@ function resetAllAssetAndEvents() end end -function resetAllLocations() - local resetList = { } - for cardGuid, _ in pairs(spawnedCardGuids) do - local card = getObjectFromGUID(cardGuid) - if card ~= nil then - local cardMetadata = JSON.decode(card.getGMNotes()) or { } - -- Check this by type rather than the PlayerCard tag so we don't reset weaknesses - if cardMetadata.type == "Location" then - resetList[cardGuid] = true - end - end - end - for cardGuid, _ in pairs(resetList) do - spawnedCardGuids[cardGuid] = nil - end -end - -function resetAll() - spawnedCardGuids = { } -end - -- Listener to reset card token spawns when they enter a hand. function onObjectEnterZone(zone, enterObject) - if HAND_ZONES[zone.getGUID()] then + if zone.type == "Hand" and enterObject.type == "Card" then resetTokensSpawned(enterObject.getGUID()) end end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/token/TokenSpawnTracker") -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Assetbundle SoundCube 3c988f.yaml b/unpacked/Custom_Assetbundle SoundCube 3c988f.yaml index 0c0572d1b..f0635c17e 100644 --- a/unpacked/Custom_Assetbundle SoundCube 3c988f.yaml +++ b/unpacked/Custom_Assetbundle SoundCube 3c988f.yaml @@ -31,8 +31,6 @@ Name: Custom_Assetbundle Nickname: SoundCube Snap: true Sticky: true -Tags: -- SoundCube Tooltip: true Transform: posX: 78 diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Bad Batch 0a1d16.ttslua b/unpacked/Custom_Model Baldur's Gate III 695abd.ttslua similarity index 100% rename from unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Bad Batch 0a1d16.ttslua rename to unpacked/Custom_Model Baldur's Gate III 695abd.ttslua diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Fortune or Folly - Parallel Rex Murphy Set 7fa06f.yaml b/unpacked/Custom_Model Baldur's Gate III 695abd.yaml similarity index 53% rename from unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Fortune or Folly - Parallel Rex Murphy Set 7fa06f.yaml rename to unpacked/Custom_Model Baldur's Gate III 695abd.yaml index 974affc5f..d40de7e30 100644 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Fortune or Folly - Parallel Rex Murphy Set 7fa06f.yaml +++ b/unpacked/Custom_Model Baldur's Gate III 695abd.yaml @@ -4,7 +4,7 @@ AltLookAngle: z: 0 Autoraise: true ColorDiffuse: - a: 0.27451 + a: 0.27843 b: 1 g: 1 r: 1 @@ -12,42 +12,34 @@ CustomMesh: CastShadows: true ColliderURL: '' Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1746802526940892011/A775E42F9014CD75B091D7D060012681E58B906E/ + DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2117314083163063648/B404BC484394C1B241A97479C3A1FDC8D33ADE2F/ MaterialIndex: 3 MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj NormalURL: '' TypeIndex: 0 -Description: By Davi +Description: by Mint Tea Fan DragSelectable: true -GMNotes: fancreations/scenario_fortune_or_folly.json -GUID: 7fa06f +GMNotes: fancreations/investigators_baldurs_gate_3.json +GUID: 695abd Grid: true GridProjection: false -Hands: true +Hands: false HideWhenFaceDown: false IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: false -LuaScript: !include 'Custom_Model Fortune or Folly - Parallel Rex Murphy Set 7fa06f.ttslua' +LuaScript: !include 'Custom_Model Baldur''s Gate III 695abd.ttslua' LuaScriptState: '' MeasureMovement: false Name: Custom_Model -Nickname: Fortune or Folly - Parallel Rex Murphy Set +Nickname: ' Baldur''s Gate III' Snap: true Sticky: true Tooltip: true Transform: - posX: -9.34 - posY: 1.62 - posZ: 65.41 + posX: -26 + posY: 1.48 + posZ: -87 rotX: 0 rotY: 270 rotZ: 0 diff --git a/unpacked/Custom_Model Clue Counter 032300.ttslua b/unpacked/Custom_Model Clue Counter 032300.ttslua index d1a8426f7..1380b391c 100644 --- a/unpacked/Custom_Model Clue Counter 032300.ttslua +++ b/unpacked/Custom_Model Clue Counter 032300.ttslua @@ -41,9 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playermat/ClueCounter") -end) __bundle_register("playermat/ClueCounter", function(require, _LOADED, __bundle_register, __bundle_modules) -- Table of items which can be counted in this Bowl -- Each entry has 2 things to enter @@ -54,13 +51,12 @@ local validCountItemList = { ["Clue"] = 1, [""] = 1 } -local trashGUID = "70b9f6" exposedValue = 0 function onLoad() self.createButton({ label = "", - click_function = "removeAllClues", + click_function = "countItems", function_owner = self, position = { 0, 0.1, 0 }, height = 0, @@ -74,16 +70,15 @@ end -- Activated once per second, counts items in bowls function countItems() local totalValue = 0 - local countableItems = findValidItemsInSphere() - for _, entry in ipairs(countableItems) do - local descValue = tonumber(entry.hit_object.getDescription()) - local stackMult = math.abs(entry.hit_object.getQuantity()) + for _, item in ipairs(findValidItemsInSphere()) do + local descValue = tonumber(item.getDescription()) + local stackMult = math.abs(item.getQuantity()) -- Use value in description if available if descValue ~= nil then totalValue = totalValue + descValue * stackMult else -- Otherwise use the value in validCountItemList - totalValue = totalValue + validCountItemList[entry.hit_object.getName()] * stackMult + totalValue = totalValue + validCountItemList[item.getName()] * stackMult end end exposedValue = totalValue @@ -96,40 +91,27 @@ function findValidItemsInSphere() direction = { 0, 1, 0 }, type = 2, max_distance = 0, - size = { 2, 2, 2 }, - --debug=true + size = { 2, 2, 2 } }) - retval = {} + local validItemList = {} for _, entry in ipairs(items) do - --Ignore the bowl if entry.hit_object ~= self then - --Ignore if not in validCountItemList - local tableEntry = validCountItemList[entry.hit_object.getName()] - if tableEntry ~= nil then - table.insert(retval, entry) + if validCountItemList[entry.hit_object.getName()] ~= nil then + table.insert(validItemList, entry.hit_object) end end end - return retval + return validItemList end -function removeAllClues() - startLuaCoroutine(self, "clueRemovalCoroutine") -end - -function clueRemovalCoroutine() - for _, entry in ipairs(findValidItemsInSphere()) do - -- Do not put the table in the garbage - if entry.hit_object.getGUID() ~= "4ee1f2" then - -- delay for animation purposes - for k = 1, 10 do - coroutine.yield(0) - end - getObjectFromGUID(trashGUID).putObject(entry.hit_object) - end +function removeAllClues(trash) + for _, obj in ipairs(findValidItemsInSphere()) do + trash.putObject(obj) end - return 1 end end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playermat/ClueCounter") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model Clue Counter 1769ed.ttslua b/unpacked/Custom_Model Clue Counter 1769ed.ttslua index d1a8426f7..5a28bcc23 100644 --- a/unpacked/Custom_Model Clue Counter 1769ed.ttslua +++ b/unpacked/Custom_Model Clue Counter 1769ed.ttslua @@ -54,13 +54,12 @@ local validCountItemList = { ["Clue"] = 1, [""] = 1 } -local trashGUID = "70b9f6" exposedValue = 0 function onLoad() self.createButton({ label = "", - click_function = "removeAllClues", + click_function = "countItems", function_owner = self, position = { 0, 0.1, 0 }, height = 0, @@ -74,16 +73,15 @@ end -- Activated once per second, counts items in bowls function countItems() local totalValue = 0 - local countableItems = findValidItemsInSphere() - for _, entry in ipairs(countableItems) do - local descValue = tonumber(entry.hit_object.getDescription()) - local stackMult = math.abs(entry.hit_object.getQuantity()) + for _, item in ipairs(findValidItemsInSphere()) do + local descValue = tonumber(item.getDescription()) + local stackMult = math.abs(item.getQuantity()) -- Use value in description if available if descValue ~= nil then totalValue = totalValue + descValue * stackMult else -- Otherwise use the value in validCountItemList - totalValue = totalValue + validCountItemList[entry.hit_object.getName()] * stackMult + totalValue = totalValue + validCountItemList[item.getName()] * stackMult end end exposedValue = totalValue @@ -96,40 +94,24 @@ function findValidItemsInSphere() direction = { 0, 1, 0 }, type = 2, max_distance = 0, - size = { 2, 2, 2 }, - --debug=true + size = { 2, 2, 2 } }) - retval = {} + local validItemList = {} for _, entry in ipairs(items) do - --Ignore the bowl if entry.hit_object ~= self then - --Ignore if not in validCountItemList - local tableEntry = validCountItemList[entry.hit_object.getName()] - if tableEntry ~= nil then - table.insert(retval, entry) + if validCountItemList[entry.hit_object.getName()] ~= nil then + table.insert(validItemList, entry.hit_object) end end end - return retval + return validItemList end -function removeAllClues() - startLuaCoroutine(self, "clueRemovalCoroutine") -end - -function clueRemovalCoroutine() - for _, entry in ipairs(findValidItemsInSphere()) do - -- Do not put the table in the garbage - if entry.hit_object.getGUID() ~= "4ee1f2" then - -- delay for animation purposes - for k = 1, 10 do - coroutine.yield(0) - end - getObjectFromGUID(trashGUID).putObject(entry.hit_object) - end +function removeAllClues(trash) + for _, obj in ipairs(findValidItemsInSphere()) do + trash.putObject(obj) end - return 1 end end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model Clue Counter 37be78.ttslua b/unpacked/Custom_Model Clue Counter 37be78.ttslua index d1a8426f7..5a28bcc23 100644 --- a/unpacked/Custom_Model Clue Counter 37be78.ttslua +++ b/unpacked/Custom_Model Clue Counter 37be78.ttslua @@ -54,13 +54,12 @@ local validCountItemList = { ["Clue"] = 1, [""] = 1 } -local trashGUID = "70b9f6" exposedValue = 0 function onLoad() self.createButton({ label = "", - click_function = "removeAllClues", + click_function = "countItems", function_owner = self, position = { 0, 0.1, 0 }, height = 0, @@ -74,16 +73,15 @@ end -- Activated once per second, counts items in bowls function countItems() local totalValue = 0 - local countableItems = findValidItemsInSphere() - for _, entry in ipairs(countableItems) do - local descValue = tonumber(entry.hit_object.getDescription()) - local stackMult = math.abs(entry.hit_object.getQuantity()) + for _, item in ipairs(findValidItemsInSphere()) do + local descValue = tonumber(item.getDescription()) + local stackMult = math.abs(item.getQuantity()) -- Use value in description if available if descValue ~= nil then totalValue = totalValue + descValue * stackMult else -- Otherwise use the value in validCountItemList - totalValue = totalValue + validCountItemList[entry.hit_object.getName()] * stackMult + totalValue = totalValue + validCountItemList[item.getName()] * stackMult end end exposedValue = totalValue @@ -96,40 +94,24 @@ function findValidItemsInSphere() direction = { 0, 1, 0 }, type = 2, max_distance = 0, - size = { 2, 2, 2 }, - --debug=true + size = { 2, 2, 2 } }) - retval = {} + local validItemList = {} for _, entry in ipairs(items) do - --Ignore the bowl if entry.hit_object ~= self then - --Ignore if not in validCountItemList - local tableEntry = validCountItemList[entry.hit_object.getName()] - if tableEntry ~= nil then - table.insert(retval, entry) + if validCountItemList[entry.hit_object.getName()] ~= nil then + table.insert(validItemList, entry.hit_object) end end end - return retval + return validItemList end -function removeAllClues() - startLuaCoroutine(self, "clueRemovalCoroutine") -end - -function clueRemovalCoroutine() - for _, entry in ipairs(findValidItemsInSphere()) do - -- Do not put the table in the garbage - if entry.hit_object.getGUID() ~= "4ee1f2" then - -- delay for animation purposes - for k = 1, 10 do - coroutine.yield(0) - end - getObjectFromGUID(trashGUID).putObject(entry.hit_object) - end +function removeAllClues(trash) + for _, obj in ipairs(findValidItemsInSphere()) do + trash.putObject(obj) end - return 1 end end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model Clue Counter d86b7c.ttslua b/unpacked/Custom_Model Clue Counter d86b7c.ttslua index d1a8426f7..1380b391c 100644 --- a/unpacked/Custom_Model Clue Counter d86b7c.ttslua +++ b/unpacked/Custom_Model Clue Counter d86b7c.ttslua @@ -41,9 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playermat/ClueCounter") -end) __bundle_register("playermat/ClueCounter", function(require, _LOADED, __bundle_register, __bundle_modules) -- Table of items which can be counted in this Bowl -- Each entry has 2 things to enter @@ -54,13 +51,12 @@ local validCountItemList = { ["Clue"] = 1, [""] = 1 } -local trashGUID = "70b9f6" exposedValue = 0 function onLoad() self.createButton({ label = "", - click_function = "removeAllClues", + click_function = "countItems", function_owner = self, position = { 0, 0.1, 0 }, height = 0, @@ -74,16 +70,15 @@ end -- Activated once per second, counts items in bowls function countItems() local totalValue = 0 - local countableItems = findValidItemsInSphere() - for _, entry in ipairs(countableItems) do - local descValue = tonumber(entry.hit_object.getDescription()) - local stackMult = math.abs(entry.hit_object.getQuantity()) + for _, item in ipairs(findValidItemsInSphere()) do + local descValue = tonumber(item.getDescription()) + local stackMult = math.abs(item.getQuantity()) -- Use value in description if available if descValue ~= nil then totalValue = totalValue + descValue * stackMult else -- Otherwise use the value in validCountItemList - totalValue = totalValue + validCountItemList[entry.hit_object.getName()] * stackMult + totalValue = totalValue + validCountItemList[item.getName()] * stackMult end end exposedValue = totalValue @@ -96,40 +91,27 @@ function findValidItemsInSphere() direction = { 0, 1, 0 }, type = 2, max_distance = 0, - size = { 2, 2, 2 }, - --debug=true + size = { 2, 2, 2 } }) - retval = {} + local validItemList = {} for _, entry in ipairs(items) do - --Ignore the bowl if entry.hit_object ~= self then - --Ignore if not in validCountItemList - local tableEntry = validCountItemList[entry.hit_object.getName()] - if tableEntry ~= nil then - table.insert(retval, entry) + if validCountItemList[entry.hit_object.getName()] ~= nil then + table.insert(validItemList, entry.hit_object) end end end - return retval + return validItemList end -function removeAllClues() - startLuaCoroutine(self, "clueRemovalCoroutine") -end - -function clueRemovalCoroutine() - for _, entry in ipairs(findValidItemsInSphere()) do - -- Do not put the table in the garbage - if entry.hit_object.getGUID() ~= "4ee1f2" then - -- delay for animation purposes - for k = 1, 10 do - coroutine.yield(0) - end - getObjectFromGUID(trashGUID).putObject(entry.hit_object) - end +function removeAllClues(trash) + for _, obj in ipairs(findValidItemsInSphere()) do + trash.putObject(obj) end - return 1 end end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playermat/ClueCounter") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model Return to The Circle Undone 757324.ttslua b/unpacked/Custom_Model Return to The Circle Undone 757324.ttslua index e6f67c6af..3c2a044ca 100644 --- a/unpacked/Custom_Model Return to The Circle Undone 757324.ttslua +++ b/unpacked/Custom_Model Return to The Circle Undone 757324.ttslua @@ -41,6 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/DownloadBox") +end) __bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) function onLoad() local notes = self.getGMNotes() @@ -84,7 +87,4 @@ function buttonClick_download() Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model Souls of Darkness a94e6b.yaml b/unpacked/Custom_Model Souls of Darkness a94e6b.yaml deleted file mode 100644 index 5ac55ee4b..000000000 --- a/unpacked/Custom_Model Souls of Darkness a94e6b.yaml +++ /dev/null @@ -1,72 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - b: 0.40592 - g: 0.40592 - r: 0.40592 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://i.ibb.co/SrtzMNN/souls-of-darkness.png - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_souls_of_darkness.json -GUID: a94e6b -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Souls of Darkness a94e6b.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Souls of Darkness -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -26.96 - posY: 1.48 - posZ: -84.51 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Bless tokens afa06b.yaml b/unpacked/Custom_Model_Bag Bless tokens afa06b.yaml index dd282229b..ee6340511 100644 --- a/unpacked/Custom_Model_Bag Bless tokens afa06b.yaml +++ b/unpacked/Custom_Model_Bag Bless tokens afa06b.yaml @@ -58,6 +58,7 @@ Nickname: Bless tokens Snap: true Sticky: true Tags: +- CleanUpHelper_ignore - displacement_excluded Tooltip: true Transform: diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7.yaml deleted file mode 100644 index 23e74e7f0..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7.yaml +++ /dev/null @@ -1,122 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -Bag: - Order: 0 -ColorDiffuse: - b: 1 - g: 1 - r: 1 -ContainedObjects: -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Weird West Custom Investigators 58ddca.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Touhou Project Investigators c5c294.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Streets of New Capenna 48b4ca.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Strange Aeons Custom Investigators d78bd2.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Signature Replacements b06fd9.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - The Sands Of Memphis (Investigator Expansion) 073201.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - The Shadows of Arkham Player Cards 2e5eef.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - The Red Coterie de13e3.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Rabbit Hole Expansion b7ff06.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Pokemon Eldritch Edition Custom Investigators 1fb7ce.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Nightmare Pack - EN e32a71.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Maximillion Pegasus Custom Investigator 4608c8.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Mass Effect Investigators b82c6f.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Magical Girl Arkham Project 814e2a.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Lola Hayes Rework 197f36.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Idol Thoughts Custom Investigators 991ff9.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - The Ghosts Of Onigawa (Investigator Expansion) c19cfa.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Gender Swapped Investigators 33272e.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Elspeth Baudin Custom Investigator 84c153.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Don''t Starve Investigators 2e69d0.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Delta Green Convergence Custom Investigators 84be1d.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Dead Space Investigators 880860.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - City of Secrets 1ee775.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Circus Ex Mortis Investigator Expansion 195936.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Cartoon Investigators 524fbc.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Buffy the Vampire Slayer 6bf40f.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Battle Goes On dd90c5.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - The Bad Batch 0a1d16.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Artifact Expansion 1.3 2f8332.yaml' -- !include 'Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model - Aespa Investigators ec74df.yaml' -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1597044073919513962/49846EAC1BFF6C62218A7933D1754ED37F4C72C8/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 6 -Description: '' -DragSelectable: true -GMNotes: '' -GUID: ed4ca7 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: true -LuaScript: '' -LuaScriptState: '' -MaterialIndex: -1 -MeasureMovement: false -MeshIndex: -1 -Name: Custom_Model_Bag -Nickname: Community-Created Player Cards/Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 60 - posY: 1.48 - posZ: 89 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 0.75 - scaleY: 0.1 - scaleZ: 0.75 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Aespa Investigators ec74df.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Aespa Investigators ec74df.yaml deleted file mode 100644 index 60d8baff6..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Aespa Investigators ec74df.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1862816781492027399/65707471C1DAF2E107F9ACDD28B5D65FDABBCE79/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: Mint Tea Fan -DragSelectable: true -GMNotes: fancreations/investigators_aespa.json -GUID: ec74df -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Aespa Investigators ec74df.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Aespa Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -19.77 - posY: 1.92 - posZ: -106.22 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Artifact Expansion 1.3 2f8332.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Artifact Expansion 1.3 2f8332.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Artifact Expansion 1.3 2f8332.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Artifact Expansion 1.3 2f8332.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Artifact Expansion 1.3 2f8332.yaml deleted file mode 100644 index d011f385f..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Artifact Expansion 1.3 2f8332.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1799728983834465397/5B8C8FFC332DCC1F09FEA1617F0F3446F06821DB/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: By Mint Tea Fan -DragSelectable: true -GMNotes: fancreations/investigators_artifact.json -GUID: 2f8332 -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Artifact Expansion 1.3 2f8332.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Artifact Expansion 1.3 -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -34.31 - posY: 2.0 - posZ: -85.69 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Battle Goes On dd90c5.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Battle Goes On dd90c5.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Battle Goes On dd90c5.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Battle Goes On dd90c5.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Battle Goes On dd90c5.yaml deleted file mode 100644 index b4b7aa58d..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Battle Goes On dd90c5.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0.7999996 - SpecularColor: - b: 0.735294163 - g: 0.735294163 - r: 0.735294163 - SpecularIntensity: 5 - SpecularSharpness: 8 - DiffuseURL: https://i.imgur.com/F4W3qLq.jpg - MaterialIndex: 2 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: by The Popest -DragSelectable: true -GMNotes: fancreations/investigators_battle_goes_on.json -GUID: dd90c5 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Battle Goes On dd90c5.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Battle Goes On -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 18.95 - posY: 1.92 - posZ: -135.81 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Buffy the Vampire Slayer 6bf40f.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Buffy the Vampire Slayer 6bf40f.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Buffy the Vampire Slayer 6bf40f.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Buffy the Vampire Slayer 6bf40f.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Buffy the Vampire Slayer 6bf40f.yaml deleted file mode 100644 index e66dab33e..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Buffy the Vampire Slayer 6bf40f.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2048620433331970643/2C2D6388AD3BAEC8B9C474B8810CF3E042E5D725/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: by AtomicZ -DragSelectable: true -GMNotes: fancreations/investigators_buffy.json -GUID: 6bf40f -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Buffy the Vampire Slayer 6bf40f.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Buffy the Vampire Slayer -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 0 - posY: 1.5 - posZ: -10 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Cartoon Investigators 524fbc.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Cartoon Investigators 524fbc.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Cartoon Investigators 524fbc.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Cartoon Investigators 524fbc.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Cartoon Investigators 524fbc.yaml deleted file mode 100644 index 5e2e1781e..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Cartoon Investigators 524fbc.yaml +++ /dev/null @@ -1,60 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1785092789057549667/7230A58735443DF70B24F5BAFD93B4FBBC1B28D7/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_cartoon_funtime.json -GUID: 524fbc -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Cartoon Investigators 524fbc.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Cartoon Investigators -Snap: true -Sticky: true -Tags: -- LargeBox -Tooltip: true -Transform: - posX: -23.61 - posY: 1.92 - posZ: -135.63 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1 - scaleY: 0.14 - scaleZ: 1 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Circus Ex Mortis Investigator Expansion 195936.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Circus Ex Mortis Investigator Expansion 195936.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Circus Ex Mortis Investigator Expansion 195936.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Circus Ex Mortis Investigator Expansion 195936.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Circus Ex Mortis Investigator Expansion 195936.yaml deleted file mode 100644 index 55e3171e6..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Circus Ex Mortis Investigator Expansion 195936.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2001337710389944672/AFEE73925C29D5330493528D81D26D499E2ABFCE/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: by TheBeard -DragSelectable: true -GMNotes: fancreations/investigators_circus_ex_mortis.json -GUID: '195936' -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Circus Ex Mortis Investigator Expansion 195936.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Circus Ex Mortis Investigator Expansion -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 0 - posY: 1.5 - posZ: -10 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model City of Secrets 1ee775.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model City of Secrets 1ee775.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model City of Secrets 1ee775.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model City of Secrets 1ee775.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model City of Secrets 1ee775.yaml deleted file mode 100644 index 361892bf7..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model City of Secrets 1ee775.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2055380534214131870/37E74A27D78CFDC8F320B15F02C5379834EA6202/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_city_of_secrets.json -GUID: 1ee775 -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model City of Secrets 1ee775.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: City of Secrets -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 0 - posY: 1.5 - posZ: -10 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Dead Space Investigators 880860.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Dead Space Investigators 880860.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Dead Space Investigators 880860.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Dead Space Investigators 880860.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Dead Space Investigators 880860.yaml deleted file mode 100644 index 5fda36019..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Dead Space Investigators 880860.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1898848485543773146/5255CF70ED228D9C98E4C9F4F010577A77B5C46E/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_dead_space.json -GUID: '880860' -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Dead Space Investigators 880860.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Dead Space Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 19.67 - posY: 2.25 - posZ: -97.9 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Delta Green Convergence Custom Investigators 84be1d.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Delta Green Convergence Custom Investigators 84be1d.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Delta Green Convergence Custom Investigators 84be1d.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Delta Green Convergence Custom Investigators 84be1d.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Delta Green Convergence Custom Investigators 84be1d.yaml deleted file mode 100644 index 234ec0c34..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Delta Green Convergence Custom Investigators 84be1d.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142900469/BDA1068C5A88459AE805540FE05B8092C4F8F392/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_delta_green_convergence.json -GUID: 84be1d -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Delta Green Convergence Custom Investigators 84be1d.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Delta Green Convergence Custom Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -33.85 - posY: 2.0 - posZ: -87.57 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Don't Starve Investigators 2e69d0.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Don't Starve Investigators 2e69d0.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Don't Starve Investigators 2e69d0.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Don't Starve Investigators 2e69d0.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Don't Starve Investigators 2e69d0.yaml deleted file mode 100644 index 951ea1444..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Don't Starve Investigators 2e69d0.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1646593716898209387/B827263B809A6C8E1042BDF1C8D33E58458C2EF4/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_dont_starve.json -GUID: 2e69d0 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Don''t Starve Investigators 2e69d0.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Don't Starve Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -20.94 - posY: 1.98 - posZ: 81.01 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Elspeth Baudin Custom Investigator 84c153.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Elspeth Baudin Custom Investigator 84c153.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Elspeth Baudin Custom Investigator 84c153.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Elspeth Baudin Custom Investigator 84c153.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Elspeth Baudin Custom Investigator 84c153.yaml deleted file mode 100644 index 4432fcede..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Elspeth Baudin Custom Investigator 84c153.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1655599785039299268/52DB5C3A0E600D6AECB0B851ECF90C5B3D016421/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: By Donelloth. As Seen in Bad Blood! -DragSelectable: true -GMNotes: fancreations/investigators_elspeth_baudin.json -GUID: 84c153 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Elspeth Baudin Custom Investigator 84c153.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Elspeth Baudin Custom Investigator -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -20.94 - posY: 1.96 - posZ: 81.01 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Gender Swapped Investigators 33272e.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Gender Swapped Investigators 33272e.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Gender Swapped Investigators 33272e.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Gender Swapped Investigators 33272e.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Gender Swapped Investigators 33272e.yaml deleted file mode 100644 index d32628317..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Gender Swapped Investigators 33272e.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1597044073919531303/A7A92208CADC509C2546E65242ADDC8EF88FEAB8/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: By /u/corpboy -DragSelectable: true -GMNotes: fancreations/investigators_gender_swapped.json -GUID: 33272e -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Gender Swapped Investigators 33272e.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Gender Swapped Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -20.94 - posY: 1.98 - posZ: 81.01 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Idol Thoughts Custom Investigators 991ff9.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Idol Thoughts Custom Investigators 991ff9.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Idol Thoughts Custom Investigators 991ff9.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Idol Thoughts Custom Investigators 991ff9.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Idol Thoughts Custom Investigators 991ff9.yaml deleted file mode 100644 index cc4060e0f..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Idol Thoughts Custom Investigators 991ff9.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1011563111884720834/103D38A8FBBFA64EB66439667F8775B15FC679C9/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_idol_thoughts.json -GUID: 991ff9 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Idol Thoughts Custom Investigators 991ff9.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Idol Thoughts Custom Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -21.84 - posY: 1.97 - posZ: 81.64 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Lola Hayes Rework 197f36.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Lola Hayes Rework 197f36.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Lola Hayes Rework 197f36.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Lola Hayes Rework 197f36.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Lola Hayes Rework 197f36.yaml deleted file mode 100644 index aa95463c4..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Lola Hayes Rework 197f36.yaml +++ /dev/null @@ -1,72 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - b: 0.34902 - g: 0.34902 - r: 0.35294 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1754686449895663371/D5D8A1205E220C2ED2D0CA50705FBADE82C053BF/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: By Mint Tea Fan -DragSelectable: true -GMNotes: fancreations/investigators_lola_hayes_rework.json -GUID: 197f36 -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Lola Hayes Rework 197f36.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Lola Hayes Rework -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -33.93 - posY: 1.97 - posZ: -99.81 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Magical Girl Arkham Project 814e2a.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Magical Girl Arkham Project 814e2a.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Magical Girl Arkham Project 814e2a.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Magical Girl Arkham Project 814e2a.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Magical Girl Arkham Project 814e2a.yaml deleted file mode 100644 index e0c12fcdd..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Magical Girl Arkham Project 814e2a.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1903353113607751170/B835836D4DB21CA06206BF84EEAAD6B3E6C157CB/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_magical_girl.json -GUID: 814e2a -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Magical Girl Arkham Project 814e2a.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Magical Girl Arkham Project -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -57.86 - posY: 2.38 - posZ: -72.02 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Mass Effect Investigators b82c6f.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Mass Effect Investigators b82c6f.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Mass Effect Investigators b82c6f.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Mass Effect Investigators b82c6f.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Mass Effect Investigators b82c6f.yaml deleted file mode 100644 index b2ad4f7b7..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Mass Effect Investigators b82c6f.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1667985852037525429/FFCBAFD8EF7EFD1127F4482DF01FFD8AE9638B4D/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_mass_effect.json -GUID: b82c6f -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Mass Effect Investigators b82c6f.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Mass Effect Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -20.94 - posY: 1.96 - posZ: 81.01 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Maximillion Pegasus Custom Investigator 4608c8.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Maximillion Pegasus Custom Investigator 4608c8.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Maximillion Pegasus Custom Investigator 4608c8.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Maximillion Pegasus Custom Investigator 4608c8.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Maximillion Pegasus Custom Investigator 4608c8.yaml deleted file mode 100644 index aa08957d7..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Maximillion Pegasus Custom Investigator 4608c8.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1684870715280907223/1E9DE758F089D7F880ADC8CA594F9AA938743F8B/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: By Game#0398 -DragSelectable: true -GMNotes: fancreations/investigators_maximillion_pegasus.json -GUID: 4608c8 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Maximillion Pegasus Custom Investigator 4608c8.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Maximillion Pegasus Custom Investigator -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -20.94 - posY: 1.96 - posZ: 81.01 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Nightmare Pack - EN e32a71.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Nightmare Pack - EN e32a71.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Nightmare Pack - EN e32a71.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Nightmare Pack - EN e32a71.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Nightmare Pack - EN e32a71.yaml deleted file mode 100644 index a02f8fb77..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Nightmare Pack - EN e32a71.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0.4999999 - SpecularColor: - b: 0.735294163 - g: 0.735294163 - r: 0.735294163 - SpecularIntensity: 0.3 - SpecularSharpness: 8 - DiffuseURL: https://i.imgur.com/ftafgpa.pnghttps://i.imgur.com/ftafgpa.png - MaterialIndex: 2 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: by The Popest -DragSelectable: true -GMNotes: fancreations/investigators_nightmare_town.json -GUID: e32a71 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Nightmare Pack - EN e32a71.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Nightmare Pack - EN -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -45.87 - posY: 1.97 - posZ: -114.77 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Pokemon Eldritch Edition Custom Investigators 1fb7ce.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Pokemon Eldritch Edition Custom Investigators 1fb7ce.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Pokemon Eldritch Edition Custom Investigators 1fb7ce.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Pokemon Eldritch Edition Custom Investigators 1fb7ce.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Pokemon Eldritch Edition Custom Investigators 1fb7ce.yaml deleted file mode 100644 index f8a7b5c90..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Pokemon Eldritch Edition Custom Investigators 1fb7ce.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1597043896926982160/40A0068DAB05395205E184765110430CAADDA2CF/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_pokemon_eldritch_edition.json -GUID: 1fb7ce -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Pokemon Eldritch Edition Custom Investigators 1fb7ce.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: 'Pokemon: Eldritch Edition Custom Investigators' -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -20.94 - posY: 1.96 - posZ: 81.01 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Rabbit Hole Expansion b7ff06.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Rabbit Hole Expansion b7ff06.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Rabbit Hole Expansion b7ff06.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Rabbit Hole Expansion b7ff06.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Rabbit Hole Expansion b7ff06.yaml deleted file mode 100644 index b4d0e81a3..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Rabbit Hole Expansion b7ff06.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1862800022614300553/046FEA88FB8D4DB6BE0AC9898149058EF32BFD0A/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: Mint Tea Fan -DragSelectable: true -GMNotes: fancreations/investigators_rabbit_hole.json -GUID: b7ff06 -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Rabbit Hole Expansion b7ff06.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Rabbit Hole Expansion -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -44.31 - posY: 1.97 - posZ: -114.79 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Signature Replacements b06fd9.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Signature Replacements b06fd9.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Signature Replacements b06fd9.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Signature Replacements b06fd9.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Signature Replacements b06fd9.yaml deleted file mode 100644 index 7266e1d44..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Signature Replacements b06fd9.yaml +++ /dev/null @@ -1,72 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - b: 0.34902 - g: 0.34902 - r: 0.35294 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1754686449895581106/83D855A76FC7568415189A03882317685F6B55EE/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: By Mint Tea Fan -DragSelectable: true -GMNotes: fancreations/investigators_replacements.json -GUID: b06fd9 -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Signature Replacements b06fd9.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Signature Replacements -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -44.34 - posY: 1.97 - posZ: -111.05 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Strange Aeons Custom Investigators d78bd2.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Strange Aeons Custom Investigators d78bd2.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Strange Aeons Custom Investigators d78bd2.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Strange Aeons Custom Investigators d78bd2.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Strange Aeons Custom Investigators d78bd2.yaml deleted file mode 100644 index 9317e9a78..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Strange Aeons Custom Investigators d78bd2.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142947772/120E2BA8DF8C4E2AAC9E059FA046CC3A6229ECDF/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_strange_aeons.json -GUID: d78bd2 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Strange Aeons Custom Investigators d78bd2.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Strange Aeons Custom Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -17.43 - posY: 2.83 - posZ: -101.73 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Streets of New Capenna 48b4ca.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Streets of New Capenna 48b4ca.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Streets of New Capenna 48b4ca.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Streets of New Capenna 48b4ca.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Streets of New Capenna 48b4ca.yaml deleted file mode 100644 index a600fb280..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Streets of New Capenna 48b4ca.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1853807409892957080/8BAF356ADEADE6CF377438200268899C64FA420E/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_SNC.json -GUID: 48b4ca -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Streets of New Capenna 48b4ca.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Streets of New Capenna -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -24.82 - posY: 2.36 - posZ: -62.97 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Bad Batch 0a1d16.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Bad Batch 0a1d16.yaml deleted file mode 100644 index 120d4525d..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Bad Batch 0a1d16.yaml +++ /dev/null @@ -1,61 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 0.02353 - g: 0.00392 - r: 0.02353 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/764975951334960553/C518D80E31E27DB23EEAC8CF9253E59798865790/ - MaterialIndex: 1 - MeshURL: http://cloud-3.steamusercontent.com/ugc/764975951334964971/3078F312706FC974833ECD2A359B87FD4F283509/ - NormalURL: http://cloud-3.steamusercontent.com/ugc/764975951334960069/E70E4A58A1B7827F1E5E2AF9FF44DF0BD5DA33F7/ - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_bad_batch.json -GUID: 0a1d16 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Bad Batch 0a1d16.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Bad Batch -PhysicsMaterial: - BounceCombine: 0 - Bounciness: 0 - DynamicFriction: 0.6 - FrictionCombine: 0 - StaticFriction: 0.6 -Rigidbody: - AngularDrag: 5 - Drag: 5 - Mass: 1.375 - UseGravity: true -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -22.82 - posY: 2.23 - posZ: -97.68 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2 - scaleY: 2 - scaleZ: 2 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Ghosts Of Onigawa (Investigator Expansion) c19cfa.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Ghosts Of Onigawa (Investigator Expansion) c19cfa.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Ghosts Of Onigawa (Investigator Expansion) c19cfa.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Ghosts Of Onigawa (Investigator Expansion) c19cfa.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Ghosts Of Onigawa (Investigator Expansion) c19cfa.yaml deleted file mode 100644 index 5064a24f9..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Ghosts Of Onigawa (Investigator Expansion) c19cfa.yaml +++ /dev/null @@ -1,60 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://dl.airtable.com/.attachmentThumbnails/e9dd0f33f26dcf0a628d962e0806de04/b41b19e1 - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: https://arkham.cards -DragSelectable: true -GMNotes: fancreations/investigators_onigawa.json -GUID: c19cfa -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Ghosts Of Onigawa (Investigator Expansion) c19cfa.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Ghosts Of Onigawa (Investigator Expansion) -Snap: true -Sticky: true -Tags: -- LargeBox -Tooltip: true -Transform: - posX: -47.19 - posY: 2.83 - posZ: -121.34 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1 - scaleY: 0.14 - scaleZ: 1 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Red Coterie de13e3.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Red Coterie de13e3.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Red Coterie de13e3.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Red Coterie de13e3.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Red Coterie de13e3.yaml deleted file mode 100644 index 3a81ac948..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Red Coterie de13e3.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2062129724651762962/3EE544183397D062C39D90FAE8E6C0DA6BF6320F/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: by Mattastrophic -DragSelectable: true -GMNotes: fancreations/investigators_red_coterie.json -GUID: de13e3 -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Red Coterie de13e3.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Red Coterie -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 25 - posY: 1.5 - posZ: 49 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Sands Of Memphis (Investigator Expansion) 073201.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Sands Of Memphis (Investigator Expansion) 073201.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Sands Of Memphis (Investigator Expansion) 073201.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Sands Of Memphis (Investigator Expansion) 073201.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Sands Of Memphis (Investigator Expansion) 073201.yaml deleted file mode 100644 index e1675a98b..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Sands Of Memphis (Investigator Expansion) 073201.yaml +++ /dev/null @@ -1,60 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://i.imgur.com/etJMio6.png - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: https://arkham.cards -DragSelectable: true -GMNotes: fancreations/investigators_memphis.json -GUID: '073201' -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Sands Of Memphis (Investigator Expansion) 073201.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Sands Of Memphis (Investigator Expansion) -Snap: true -Sticky: true -Tags: -- LargeBox -Tooltip: true -Transform: - posX: -47.19 - posY: 2.83 - posZ: -121.34 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1 - scaleY: 0.14 - scaleZ: 1 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Shadows of Arkham Player Cards 2e5eef.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Shadows of Arkham Player Cards 2e5eef.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Shadows of Arkham Player Cards 2e5eef.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Shadows of Arkham Player Cards 2e5eef.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Shadows of Arkham Player Cards 2e5eef.yaml deleted file mode 100644 index c5d70376b..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model The Shadows of Arkham Player Cards 2e5eef.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1697282751257289223/D03666A291CC5705A3656865488583FF4AB762B4/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_shadows_of_arkham.json -GUID: 2e5eef -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Shadows of Arkham Player Cards 2e5eef.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Shadows of Arkham Player Cards -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -17.12 - posY: 3.27 - posZ: -93.32 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Touhou Project Investigators c5c294.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Touhou Project Investigators c5c294.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Touhou Project Investigators c5c294.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Touhou Project Investigators c5c294.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Touhou Project Investigators c5c294.yaml deleted file mode 100644 index cee35614f..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Touhou Project Investigators c5c294.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1697277697641042816/D60194A8F22DA3032E6C2AC2EE040E6321A2B259/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/investigators_touhou_project.json -GUID: c5c294 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Touhou Project Investigators c5c294.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Touhou Project Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -35.72 - posY: 1.97 - posZ: -126.28 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Weird West Custom Investigators 58ddca.ttslua b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Weird West Custom Investigators 58ddca.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Weird West Custom Investigators 58ddca.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Weird West Custom Investigators 58ddca.yaml b/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Weird West Custom Investigators 58ddca.yaml deleted file mode 100644 index a78294cd0..000000000 --- a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Weird West Custom Investigators 58ddca.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1697276706767572704/331469F5EAD01108E83C7662B9949F4AC3D00313/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: Created by Samirashul -DragSelectable: true -GMNotes: fancreations/investigators_weird_west.json -GUID: 58ddca -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Weird West Custom Investigators 58ddca.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Weird West Custom Investigators -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -20.94 - posY: 2.01 - posZ: 81.01 - rotX: 359 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Curse tokens bd0253.yaml b/unpacked/Custom_Model_Bag Curse tokens bd0253.yaml index f0a10dc96..6c3d99570 100644 --- a/unpacked/Custom_Model_Bag Curse tokens bd0253.yaml +++ b/unpacked/Custom_Model_Bag Curse tokens bd0253.yaml @@ -58,6 +58,7 @@ Nickname: Curse tokens Snap: true Sticky: true Tags: +- CleanUpHelper_ignore - displacement_excluded Tooltip: true Transform: diff --git a/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38.yaml b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38.yaml index 2e132aa71..47724072a 100644 --- a/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38.yaml +++ b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38.yaml @@ -16,6 +16,8 @@ ContainedObjects: Selector 8112ff.yaml' - !include 'Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Model Lucky Penny 2ab443.yaml' +- !include 'Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums + b2077d.yaml' - !include 'Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile Double-Sided Resource bc81cb.yaml' - !include 'Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile Descriptive Phase @@ -26,6 +28,8 @@ ContainedObjects: Market Helper 3650ea.yaml' - !include 'Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile Subject 5U-21 Helper 1335e8.yaml' +- !include 'Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile PlayermatHider + a758b2.yaml' - !include 'Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile Auto-fail Counter a9a321.yaml' - !include 'Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile Elder Sign Counter diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d.yaml b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d.yaml similarity index 93% rename from unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d.yaml rename to unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d.yaml index 2844ff53d..a093ff97d 100644 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d.yaml +++ b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d.yaml @@ -6,9 +6,9 @@ Autoraise: true Bag: Order: 0 ColorDiffuse: - b: 0 - g: 0 - r: 0 + b: 1 + g: 1 + r: 1 ContainedObjects: - !include 'Bag Secret Objectives & Ultimatums b2077d/Deck 5f3cba.yaml' - !include 'Bag Secret Objectives & Ultimatums b2077d/Notecard HOW TO USE SECRET OBJ. @@ -38,9 +38,9 @@ Snap: true Sticky: true Tooltip: true Transform: - posX: -9 - posY: 1.3 - posZ: -55 + posX: -37.16 + posY: 2.83 + posZ: -112.79 rotX: 0 rotY: 270 rotZ: 0 diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d/Deck 1e8a13.yaml b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d/Deck 1e8a13.yaml similarity index 100% rename from unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d/Deck 1e8a13.yaml rename to unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d/Deck 1e8a13.yaml diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d/Deck 5f3cba.yaml b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d/Deck 5f3cba.yaml similarity index 100% rename from unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d/Deck 5f3cba.yaml rename to unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d/Deck 5f3cba.yaml diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d/Notecard HOW TO USE SECRET OBJ. f3dfc9.yaml b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d/Notecard HOW TO USE SECRET OBJ. f3dfc9.yaml similarity index 100% rename from unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d/Notecard HOW TO USE SECRET OBJ. f3dfc9.yaml rename to unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d/Notecard HOW TO USE SECRET OBJ. f3dfc9.yaml diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d/Notecard HOW TO USE ULTIMATUMS ed4645.yaml b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d/Notecard HOW TO USE ULTIMATUMS ed4645.yaml similarity index 100% rename from unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret Objectives & Ultimatums b2077d/Notecard HOW TO USE ULTIMATUMS ed4645.yaml rename to unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Bag Secret Objectives & Ultimatums b2077d/Notecard HOW TO USE ULTIMATUMS ed4645.yaml diff --git a/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Model_Bag Underworld Market Helper 3650ea.ttslua b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Model_Bag Underworld Market Helper 3650ea.ttslua index 4f581efa3..594fad6e7 100644 --- a/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Model_Bag Underworld Market Helper 3650ea.ttslua +++ b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Model_Bag Underworld Market Helper 3650ea.ttslua @@ -1,3 +1,50 @@ +-- 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) function onload(saved_data) revealCardPositions = { Vector(3.5, 0.25, 0), @@ -281,4 +328,6 @@ function resetHelper() self.reset() print('Underworld Market Helper: Helper has been reset.') -end \ No newline at end of file +end +end) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile PlayermatHider a758b2.ttslua b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile PlayermatHider a758b2.ttslua new file mode 100644 index 000000000..1c5bf9663 --- /dev/null +++ b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile PlayermatHider a758b2.ttslua @@ -0,0 +1,120 @@ +-- 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/PlayermatHider") +end) +__bundle_register("accessories/PlayermatHider", function(require, _LOADED, __bundle_register, __bundle_modules) +local guidReferenceApi = require("core/GUIDReferenceApi") +local objects + +function onClick_hideShow(player, matColor) + objects = guidReferenceApi.getObjectsByOwner(matColor) + local actionTokens = searchMat(objects.Playermat.positionToWorld({-1.1, 0.05, -0.27}), {4, 1, 1}, isActionToken) + local pos = objects.Playermat.getPosition() + local mod = (pos.y > 0) and -2 or 2 + + -- move all objects + for _, obj in pairs(objects) do + obj.setPosition(obj.getPosition() + Vector(0, mod, 0)) + end + + -- move action tokens + for _, obj in ipairs(actionTokens) do + obj.setLock(pos.y > 0) + obj.setPosition(obj.getPosition() + Vector(0, mod, 0)) + end +end + +function isActionToken(x) return x.getDescription() == 'Action Token' end + +function searchMat(origin, size, filter) + local searchResult = Physics.cast({ + origin = origin, + direction = { 0, 1, 0 }, + orientation = objects.Playermat.getRotation(), + type = 3, + size = size, + max_distance = 0 + }) + + local objList = {} + for _, v in ipairs(searchResult) do + if not filter or (filter and filter(v.hit_object)) then + table.insert(objList, v.hit_object) + end + end + return objList +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) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile PlayermatHider a758b2.xml b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile PlayermatHider a758b2.xml new file mode 100644 index 000000000..c4343b67a --- /dev/null +++ b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile PlayermatHider a758b2.xml @@ -0,0 +1,78 @@ + + + + + + + + + + Playermat 2 (Orange) + + + + + + + + + + Playermat 3 (Green) + + + + + + + + + + Playermat 4 (Red) + + + + + + + + + \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile PlayermatHider a758b2.yaml b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile PlayermatHider a758b2.yaml new file mode 100644 index 000000000..3fcd2bc3d --- /dev/null +++ b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile PlayermatHider a758b2.yaml @@ -0,0 +1,52 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +ColorDiffuse: + b: 1 + g: 1 + r: 1 +CustomImage: + CustomTile: + Stackable: false + Stretch: true + Thickness: 0.1 + Type: 3 + ImageScalar: 1 + ImageSecondaryURL: '' + ImageURL: http://cloud-3.steamusercontent.com/ugc/2115061845796985108/F0ADB7094641DA966FFA3AF0CC6987D33D2D9591/ + WidthScale: 0 +Description: Use the buttons to show / hide a playmat. +DragSelectable: true +GMNotes: '' +GUID: a758b2 +Grid: true +GridProjection: false +Hands: false +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: !include 'Custom_Tile PlayermatHider a758b2.ttslua' +LuaScriptState: '' +MeasureMovement: false +Name: Custom_Tile +Nickname: PlayermatHider +Snap: true +Sticky: true +Tags: +- CleanUpHelper_ignore +Tooltip: true +Transform: + posX: 0 + posY: 2 + posZ: 0 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 5 + scaleY: 1 + scaleZ: 5 +Value: 0 +XmlUI: !include 'Custom_Tile PlayermatHider a758b2.xml' diff --git a/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile Subject 5U-21 Helper 1335e8.ttslua b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile Subject 5U-21 Helper 1335e8.ttslua index f8a3f6891..899f199f3 100644 --- a/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile Subject 5U-21 Helper 1335e8.ttslua +++ b/unpacked/Custom_Model_Bag Fan-Made Accessories aa8b38/Custom_Tile Subject 5U-21 Helper 1335e8.ttslua @@ -1,3 +1,50 @@ +-- 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/Subject5U-21Helper") +end) +__bundle_register("accessories/Subject5U-21Helper", function(require, _LOADED, __bundle_register, __bundle_modules) local classOrder = { "Guardian", "Seeker", @@ -91,13 +138,19 @@ function getNotesFromCardsAndContainers() notes = JSON.decode(obj.getGMNotes()) or {} table.insert(notesList, notes) elseif obj.type == "Bag" or obj.type == "Deck" then - for _, deepObj in ipairs(obj.getData().ContainedObjects) do - if deepObj.Name == "Card" or deepObj.Name == "CardCustom" then - notes = JSON.decode(deepObj.GMNotes) or {} - table.insert(notesList, notes) + -- check if there are actually objects contained and loop through them + local containedObjects = obj.getData().ContainedObjects + if containedObjects then + for _, deepObj in ipairs(containedObjects) do + if deepObj.Name == "Card" or deepObj.Name == "CardCustom" then + notes = JSON.decode(deepObj.GMNotes) or {} + table.insert(notesList, notes) + end end end end end return notesList -end \ No newline at end of file +end +end) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c.ttslua deleted file mode 100644 index 5e3a3f62d..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c.ttslua +++ /dev/null @@ -1,504 +0,0 @@ --- Utility memory bag by Directsun --- Version 2.5.2 --- Fork of Memory Bag 2.0 by MrStump - -function updateSave() - local data_to_save = {["ml"]=memoryList} - saved_data = JSON.encode(data_to_save) - self.script_state = saved_data -end - -function combineMemoryFromBagsWithin() - local bagObjList = self.getObjects() - for _, bagObj in ipairs(bagObjList) do - local data = bagObj.lua_script_state - if data ~= nil then - local j = JSON.decode(data) - if j ~= nil and j.ml ~= nil then - for guid, entry in pairs(j.ml) do - memoryList[guid] = entry - end - end - end - end -end - -function updateMemoryWithMoves() - memoryList = memoryListBackup - --get the first transposed object's coordinates - local obj = getObjectFromGUID(moveGuid) - - -- p1 is where needs to go, p2 is where it was - local refObjPos = memoryList[moveGuid].pos - local deltaPos = findOffsetDistance(obj.getPosition(), refObjPos, nil) - local movedRotation = obj.getRotation() - for guid, entry in pairs(memoryList) do - memoryList[guid].pos.x = entry.pos.x - deltaPos.x - memoryList[guid].pos.y = entry.pos.y - deltaPos.y - memoryList[guid].pos.z = entry.pos.z - deltaPos.z - -- memoryList[guid].rot.x = movedRotation.x - -- memoryList[guid].rot.y = movedRotation.y - -- memoryList[guid].rot.z = movedRotation.z - end - - --theList[obj.getGUID()] = { - -- pos={x=round(pos.x,4), y=round(pos.y,4), z=round(pos.z,4)}, - -- rot={x=round(rot.x,4), y=round(rot.y,4), z=round(rot.z,4)}, - -- lock=obj.getLock() - --} - moveList = {} -end - -function onload(saved_data) - fresh = true - if saved_data ~= "" then - local loaded_data = JSON.decode(saved_data) - --Set up information off of loaded_data - memoryList = loaded_data.ml - else - --Set up information for if there is no saved saved data - memoryList = {} - end - - moveList = {} - moveGuid = nil - - if next(memoryList) == nil then - createSetupButton() - else - fresh = false - createMemoryActionButtons() - end -end - - ---Beginning Setup - - ---Make setup button -function createSetupButton() - self.createButton({ - label="Setup", click_function="buttonClick_setup", function_owner=self, - position={0,0.1,-6}, rotation={0,0,0}, height=500, width=1200, - font_size=350, color={0,0,0}, font_color={1,1,1} - }) -end - ---Triggered by Transpose button -function buttonClick_transpose() - moveGuid = nil - broadcastToAll("Select one object and move it- all objects will move relative to the new location", {0.75, 0.75, 1}) - memoryListBackup = duplicateTable(memoryList) - memoryList = {} - moveList = {} - self.clearButtons() - createButtonsOnAllObjects(true) - createSetupActionButtons(true) -end - ---Triggered by setup button, -function buttonClick_setup() - memoryListBackup = duplicateTable(memoryList) - memoryList = {} - self.clearButtons() - createButtonsOnAllObjects(false) - createSetupActionButtons(false) -end - -function getAllObjectsInMemory() - local objTable = {} - local curObj = {} - - for guid in pairs(memoryListBackup) do - curObj = getObjectFromGUID(guid) - table.insert(objTable, curObj) - end - - return objTable - -- return getAllObjects() -end - ---Creates selection buttons on objects -function createButtonsOnAllObjects(move) - local howManyButtons = 0 - - local objsToHaveButtons = {} - if move == true then - objsToHaveButtons = getAllObjectsInMemory() - else - objsToHaveButtons = getAllObjects() - end - - for _, obj in ipairs(objsToHaveButtons) do - if obj ~= self then - local dummyIndex = howManyButtons - --On a normal bag, the button positions aren't the same size as the bag. - globalScaleFactor = 1 * 1/self.getScale().x - --Super sweet math to set button positions - local selfPos = self.getPosition() - local objPos = obj.getPosition() - local deltaPos = findOffsetDistance(selfPos, objPos, obj) - local objPos = rotateLocalCoordinates(deltaPos, self) - objPos.x = -objPos.x * globalScaleFactor - objPos.y = objPos.y * globalScaleFactor + 4 - objPos.z = objPos.z * globalScaleFactor - --Offset rotation of bag - local rot = self.getRotation() - rot.y = -rot.y + 180 - --Create function - local funcName = "selectButton_" .. howManyButtons - local func = function() buttonClick_selection(dummyIndex, obj, move) end - local color = {0.75,0.25,0.25,0.6} - local colorMove = {0,0,1,0.6} - if move == true then - color = colorMove - end - self.setVar(funcName, func) - self.createButton({ - click_function=funcName, function_owner=self, - position=objPos, rotation=rot, height=1000, width=1000, - color=color, - }) - howManyButtons = howManyButtons + 1 - end - end -end - ---Creates submit and cancel buttons -function createSetupActionButtons(move) - self.createButton({ - label="Cancel", click_function="buttonClick_cancel", function_owner=self, - position={0,1,-2}, rotation={0,0,0}, height=240, width=550, - font_size=150, color={0,0,0}, font_color={1,1,1} - }) - - self.createButton({ - label="Submit", click_function="buttonClick_submit", function_owner=self, - position={-1.2,1,-2}, rotation={0,0,0}, height=240, width=570, - font_size=150, color={0,0,0}, font_color={1,1,1} - }) - - if move == false then - self.createButton({ - label="Add", click_function="buttonClick_add", function_owner=self, - position={-1.2,1,2}, rotation={0,0,0}, height=240, width=550, - font_size=150, color={0,0,0}, font_color={0.25,1,0.25} - }) - - if fresh == false then - self.createButton({ - label="Set New", click_function="buttonClick_setNew", function_owner=self, - position={0,1,2}, rotation={0,0,0}, height=240, width=600, - font_size=150, color={0,0,0}, font_color={0.75,0.75,1} - }) - self.createButton({ - label="Remove", click_function="buttonClick_remove", function_owner=self, - position={1.3,1,2}, rotation={0,0,0}, height=240, width=600, - font_size=150, color={0,0,0}, font_color={1,0.25,0.25} - }) - end - end - - self.createButton({ - label="Reset", click_function="buttonClick_reset", function_owner=self, - position={1.2,1,-2}, rotation={0,0,0}, height=240, width=500, - font_size=150, color={0,0,0}, font_color={1,1,1} - }) -end - - ---During Setup - - ---Checks or unchecks buttons -function buttonClick_selection(index, obj, move) - local colorMove = {0,0,1,0.6} - local color = {0,1,0,0.6} - - previousGuid = selectedGuid - selectedGuid = obj.getGUID() - - theList = memoryList - if move == true then - theList = moveList - if previousGuid ~= nil and previousGuid ~= selectedGuid then - local prevObj = getObjectFromGUID(previousGuid) - prevObj.highlightOff() - self.editButton({index=previousIndex, color=colorMove}) - theList[previousGuid] = nil - end - previousIndex = index - end - - if theList[selectedGuid] == nil then - self.editButton({index=index, color=color}) - --Adding pos/rot to memory table - local pos, rot = obj.getPosition(), obj.getRotation() - --I need to add it like this or it won't save due to indexing issue - theList[obj.getGUID()] = { - pos={x=round(pos.x,4), y=round(pos.y,4), z=round(pos.z,4)}, - rot={x=round(rot.x,4), y=round(rot.y,4), z=round(rot.z,4)}, - lock=obj.getLock() - } - obj.highlightOn({0,1,0}) - else - color = {0.75,0.25,0.25,0.6} - if move == true then - color = colorMove - end - self.editButton({index=index, color=color}) - theList[obj.getGUID()] = nil - obj.highlightOff() - end -end - ---Cancels selection process -function buttonClick_cancel() - memoryList = memoryListBackup - moveList = {} - self.clearButtons() - if next(memoryList) == nil then - createSetupButton() - else - createMemoryActionButtons() - end - removeAllHighlights() - broadcastToAll("Selection Canceled", {1,1,1}) - moveGuid = nil -end - ---Saves selections -function buttonClick_submit() - fresh = false - if next(moveList) ~= nil then - for guid in pairs(moveList) do - moveGuid = guid - end - if memoryListBackup[moveGuid] == nil then - broadcastToAll("Item selected for moving is not already in memory", {1, 0.25, 0.25}) - else - broadcastToAll("Moving all items in memory relative to new objects position!", {0.75, 0.75, 1}) - self.clearButtons() - createMemoryActionButtons() - local count = 0 - for guid in pairs(moveList) do - moveGuid = guid - count = count + 1 - local obj = getObjectFromGUID(guid) - if obj ~= nil then obj.highlightOff() end - end - updateMemoryWithMoves() - updateSave() - buttonClick_place() - end - elseif next(memoryList) == nil and moveGuid == nil then - memoryList = memoryListBackup - broadcastToAll("No selections made.", {0.75, 0.25, 0.25}) - end - combineMemoryFromBagsWithin() - self.clearButtons() - createMemoryActionButtons() - local count = 0 - for guid in pairs(memoryList) do - count = count + 1 - local obj = getObjectFromGUID(guid) - if obj ~= nil then obj.highlightOff() end - end - broadcastToAll(count.." Objects Saved", {1,1,1}) - updateSave() - moveGuid = nil -end - -function combineTables(first_table, second_table) - for k,v in pairs(second_table) do first_table[k] = v end -end - -function buttonClick_add() - fresh = false - combineTables(memoryList, memoryListBackup) - broadcastToAll("Adding internal bags and selections to existing memory", {0.25, 0.75, 0.25}) - combineMemoryFromBagsWithin() - self.clearButtons() - createMemoryActionButtons() - local count = 0 - for guid in pairs(memoryList) do - count = count + 1 - local obj = getObjectFromGUID(guid) - if obj ~= nil then obj.highlightOff() end - end - broadcastToAll(count.." Objects Saved", {1,1,1}) - updateSave() -end - -function buttonClick_remove() - broadcastToAll("Removing Selected Entries From Memory", {1.0, 0.25, 0.25}) - self.clearButtons() - createMemoryActionButtons() - local count = 0 - for guid in pairs(memoryList) do - count = count + 1 - memoryListBackup[guid] = nil - local obj = getObjectFromGUID(guid) - if obj ~= nil then obj.highlightOff() end - end - broadcastToAll(count.." Objects Removed", {1,1,1}) - memoryList = memoryListBackup - updateSave() -end - -function buttonClick_setNew() - broadcastToAll("Setting new position relative to items in memory", {0.75, 0.75, 1}) - self.clearButtons() - createMemoryActionButtons() - local count = 0 - for _, obj in ipairs(getAllObjects()) do - guid = obj.guid - if memoryListBackup[guid] ~= nil then - count = count + 1 - memoryListBackup[guid].pos = obj.getPosition() - memoryListBackup[guid].rot = obj.getRotation() - memoryListBackup[guid].lock = obj.getLock() - end - end - broadcastToAll(count.." Objects Saved", {1,1,1}) - memoryList = memoryListBackup - updateSave() -end - ---Resets bag to starting status -function buttonClick_reset() - fresh = true - memoryList = {} - self.clearButtons() - createSetupButton() - removeAllHighlights() - broadcastToAll("Tool Reset", {1,1,1}) - updateSave() -end - - ---After Setup - - ---Creates recall and place buttons -function createMemoryActionButtons() - self.createButton({ - label="Place", click_function="buttonClick_place", function_owner=self, - position={0.7,1,2}, rotation={0,0,0}, height=280, width=600, - font_size=200, color={0,0,0}, font_color={1,1,1} - }) - self.createButton({ - label="Recall", click_function="buttonClick_recall", function_owner=self, - position={-0.7,1,2}, rotation={0,0,0}, height=280, width=650, - font_size=200, color={0,0,0}, font_color={1,1,1} - }) - self.createButton({ - label="Setup", click_function="buttonClick_setup", function_owner=self, - position={0,1,-2}, rotation={0,0,0}, height=240, width=500, - font_size=150, color={0,0,0}, font_color={1,1,1} - }) - ---- self.createButton({ ---- label="Move", click_function="buttonClick_transpose", function_owner=self, ---- position={-2.8,0.3,0}, rotation={0,0,0}, height=350, width=800, ---- font_size=250, color={0,0,0}, font_color={0.75,0.75,1} ---- }) -end - ---Sends objects from bag/table to their saved position/rotation -function buttonClick_place() - local bagObjList = self.getObjects() - for guid, entry in pairs(memoryList) do - local obj = getObjectFromGUID(guid) - --If obj is out on the table, move it to the saved pos/rot - if obj ~= nil then - obj.setPositionSmooth(entry.pos) - obj.setRotationSmooth(entry.rot) - obj.setLock(entry.lock) - else - --If obj is inside of the bag - for _, bagObj in ipairs(bagObjList) do - if bagObj.guid == guid then - local item = self.takeObject({ - guid=guid, position=entry.pos, rotation=entry.rot, smooth=false - }) - item.setLock(entry.lock) - break - end - end - end - end - broadcastToAll("Objects Placed", {1,1,1}) -end - ---Recalls objects to bag from table -function buttonClick_recall() - for guid, entry in pairs(memoryList) do - local obj = getObjectFromGUID(guid) - if obj ~= nil then self.putObject(obj) end - end - broadcastToAll("Objects Recalled", {1,1,1}) -end - - ---Utility functions - - ---Find delta (difference) between 2 x/y/z coordinates -function findOffsetDistance(p1, p2, obj) - local yOffset = 0 - if obj ~= nil then - local bounds = obj.getBounds() - yOffset = (bounds.size.y - bounds.offset.y) - end - local deltaPos = {} - deltaPos.x = (p2.x-p1.x) - deltaPos.y = (p2.y-p1.y) + yOffset - deltaPos.z = (p2.z-p1.z) - return deltaPos -end - ---Used to rotate a set of coordinates by an angle -function rotateLocalCoordinates(desiredPos, obj) - local objPos, objRot = obj.getPosition(), obj.getRotation() - local angle = math.rad(objRot.y) - local x = desiredPos.x * math.cos(angle) - desiredPos.z * math.sin(angle) - local z = desiredPos.x * math.sin(angle) + desiredPos.z * math.cos(angle) - --return {x=objPos.x+x, y=objPos.y+desiredPos.y, z=objPos.z+z} - return {x=x, y=desiredPos.y, z=z} -end - -function rotateMyCoordinates(desiredPos, obj) - local angle = math.rad(obj.getRotation().y) - local x = desiredPos.x * math.sin(angle) - local z = desiredPos.z * math.cos(angle) - return {x=x, y=desiredPos.y, z=z} -end - ---Coroutine delay, in seconds -function wait(time) - local start = os.time() - repeat coroutine.yield(0) until os.time() > start + time -end - ---Duplicates a table (needed to prevent it making reference to the same objects) -function duplicateTable(oldTable) - local newTable = {} - for k, v in pairs(oldTable) do - newTable[k] = v - end - return newTable -end - ---Moves scripted highlight from all objects -function removeAllHighlights() - for _, obj in ipairs(getAllObjects()) do - obj.highlightOff() - end -end - ---Round number (num) to the Nth decimal (dec) -function round(num, dec) - local mult = 10^(dec or 0) - return math.floor(num * mult + 0.5) / mult -end \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c.yaml deleted file mode 100644 index e80c7ef74..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c.yaml +++ /dev/null @@ -1,68 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -Bag: - Order: 0 -ColorDiffuse: - b: 1 - g: 0.99217 - r: 1 -ContainedObjects: -- !include 'Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag - Fan-Made Standalone Scenarios 5db60c.yaml' -- !include 'Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag - Fan-Made Campaigns 89c32e.yaml' -- !include 'Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Bag Secret - Objectives & Ultimatums b2077d.yaml' -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1758068588410888435/EDEEC5792F4161A1F125EF7F65AB1C1DC8FDBC27/ - MaterialIndex: 3 - MeshURL: http://pastebin.com/raw.php?i=uWAmuNZ2 - NormalURL: '' - TypeIndex: 6 -Description: '' -DragSelectable: true -GMNotes: '' -GUID: 66e97c -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c.ttslua' -LuaScriptState: "{\"ml\":{\"5db60c\":{\"lock\":false,\"pos\":{\"x\":-9,\"y\":1.4815,\"z\":-50},\"rot\":{\"x\":0,\"y\":270.0001,\"z\":0}},\"89c32e\":{\"lock\":false,\"pos\":{\"x\":-9,\"y\":1.4815,\"z\":-60},\"rot\":{\"x\":0,\"y\":270.0001,\"z\":0}},\"b2077d\":{\"lock\":false,\"pos\":{\"x\":-9,\"y\":1.2965,\"z\":-55},\"rot\":{\"x\":0,\"y\":269.9973,\"z\":0}}}}\r" -MaterialIndex: -1 -MeasureMovement: false -MeshIndex: -1 -Name: Custom_Model_Bag -Nickname: Fan-Made Scenarios/Campaigns/Miscellany -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 0 - posY: 1.87 - posZ: -55 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1.76 - scaleY: 0.11 - scaleZ: 1.49 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e.yaml deleted file mode 100644 index 98d237ca5..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e.yaml +++ /dev/null @@ -1,134 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -Bag: - Order: 0 -ColorDiffuse: - b: 1 - g: 1 - r: 1 -ContainedObjects: -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Winter Winds 754057.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The War of the - Worlds 19d469.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Strange Aeons - 2abdd6.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Souls of Darkness - a94e6b.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Sands Of Memphis - Campaign Expansion 2634e3.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The (Unofficial) - Return to The Innsmouth Conspiracy bba2b6.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Pokemon Eldritch - Edition 75fe78.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Parallel Universe - 28e0a1.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Outsider 3c175c.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ordo Templi Orientis - 608bea.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Of Sphinx and - Sands edb650.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model North Country - Cycle aaceca.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Machining A Mystery - 79b36d.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The London Set - 0f96ac.yaml' -- !include "Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kiedy sny Staj\u0105 - si\u0119 Rzeczywi\u015Bci\u0105 acdf16.yaml" -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kaimonogatari - 2df25a.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Jumanji b46db2.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Into the Shadowlands - 019847.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Idol Thoughts - 2d417b.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Heart of Darkness - cc95ff.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Half-Life b46db2.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Ghosts Of - Onigawa Campaign Expansion 8daa73.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Future Reflections - 0f0680.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Essence of Humanity - Campaign Box 691339.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Dying Star - bcfff6.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Dark Matter d713f4.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Darkham Horror - bc7fa7.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Cyclopean Foundations - 169eb9.yaml' -- !include "Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model \uF729The Crown - of Egil 7458b7.yaml" -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Color Out - of Oz be7d21.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Close Encounters - of the LV-426 Kind 4f5421.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Circus Ex Mortis - Campaign 93b8cb.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Celtic Rising - 4d305a.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Call of the Plaguebearer - 613b64.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Bloodborne - City - of the Unseen 24fb2b.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Betrayal at the - Mountains of Madness ef939a.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Approaching - Storm ab6b9a.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Alice in Wonderland - 39916d.yaml' -- !include 'Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ages Unwound f7e5eb.yaml' -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1758068588410858852/B3312EB929FDEF7CB2B88F98CD757950B919B147/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 6 -Description: '' -DragSelectable: true -GMNotes: '' -GUID: 89c32e -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: '' -LuaScriptState: '{"ml":[]}' -MaterialIndex: -1 -MeasureMovement: false -MeshIndex: -1 -Name: Custom_Model_Bag -Nickname: Fan-Made Campaigns -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9 - posY: 1.48 - posZ: -60 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 0.5 - scaleY: 0.1 - scaleZ: 0.5 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ages Unwound f7e5eb.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ages Unwound f7e5eb.ttslua deleted file mode 100644 index e6f67c6af..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ages Unwound f7e5eb.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ages Unwound f7e5eb.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ages Unwound f7e5eb.yaml deleted file mode 100644 index 8f4888061..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ages Unwound f7e5eb.yaml +++ /dev/null @@ -1,72 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - b: 0.40592 - g: 0.40592 - r: 0.40592 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1811004822724765158/DE184EBA95BF16D06DC2528B30E9058A87C7567E/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_ages_unwound.json -GUID: f7e5eb -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Ages Unwound f7e5eb.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Ages Unwound -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 18.63 - posY: 1.85 - posZ: 24.43 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Alice in Wonderland 39916d.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Alice in Wonderland 39916d.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Alice in Wonderland 39916d.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Alice in Wonderland 39916d.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Alice in Wonderland 39916d.yaml deleted file mode 100644 index f22c6e40a..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Alice in Wonderland 39916d.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1478823218929917964/80063921C2355FE26816A0E40F88D31F9EF5C4A6/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_alice_in_wonderland.json -GUID: 39916d -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Alice in Wonderland 39916d.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Alice in Wonderland -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 15.31 - posY: 1.82 - posZ: -2.2 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Betrayal at the Mountains of Madness ef939a.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Betrayal at the Mountains of Madness ef939a.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Betrayal at the Mountains of Madness ef939a.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Betrayal at the Mountains of Madness ef939a.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Betrayal at the Mountains of Madness ef939a.yaml deleted file mode 100644 index fa061ab7f..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Betrayal at the Mountains of Madness ef939a.yaml +++ /dev/null @@ -1,60 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_COL.obj - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1479949766318759506/9BAB9C45ECB33AC5A0F83806B5EF79A6D89C1D31/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_betrayal_at_mountains.json -GUID: ef939a -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Betrayal at the Mountains of Madness ef939a.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Betrayal at the Mountains of Madness -Snap: true -Sticky: true -Tags: -- LargeBox -Tooltip: true -Transform: - posX: 61.16 - posY: 3.41 - posZ: -57.22 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1 - scaleY: 0.14 - scaleZ: 1 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Bloodborne - City of the Unseen 24fb2b.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Bloodborne - City of the Unseen 24fb2b.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Bloodborne - City of the Unseen 24fb2b.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Bloodborne - City of the Unseen 24fb2b.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Bloodborne - City of the Unseen 24fb2b.yaml deleted file mode 100644 index 184f5714c..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Bloodborne - City of the Unseen 24fb2b.yaml +++ /dev/null @@ -1,60 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_COL.obj - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://i.imgur.com/WtioCq1.jpg - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_bloodborne.json -GUID: 24fb2b -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Bloodborne - City of the Unseen 24fb2b.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Bloodborne - City of the Unseen -Snap: true -Sticky: true -Tags: -- LargeBox -Tooltip: true -Transform: - posX: -9.28 - posY: 2.68 - posZ: -109.46 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1 - scaleY: 0.14 - scaleZ: 1 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Call of the Plaguebearer 613b64.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Call of the Plaguebearer 613b64.ttslua deleted file mode 100644 index e6f67c6af..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Call of the Plaguebearer 613b64.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Call of the Plaguebearer 613b64.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Call of the Plaguebearer 613b64.yaml deleted file mode 100644 index 358b76259..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Call of the Plaguebearer 613b64.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1767067672754132384/EBC8D780049D2612C6BC0603BD87E94769C34D19/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_call_of_the_plaguebearer.json -GUID: 613b64 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Call of the Plaguebearer 613b64.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Call of the Plaguebearer -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -6.24 - posY: 1.62 - posZ: 68.9 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Celtic Rising 4d305a.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Celtic Rising 4d305a.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Celtic Rising 4d305a.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Celtic Rising 4d305a.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Celtic Rising 4d305a.yaml deleted file mode 100644 index 24ae5f54e..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Celtic Rising 4d305a.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1754685726010541421/DC8223A713D02261326877B51FC717A9BAA217B8/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: 5 Scenario Custom Cycle -DragSelectable: true -GMNotes: fancreations/campaign_celtic_rising.json -GUID: 4d305a -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Celtic Rising 4d305a.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Celtic Rising -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 26.69 - posY: 5.16 - posZ: -36.15 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Circus Ex Mortis Campaign 93b8cb.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Circus Ex Mortis Campaign 93b8cb.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Circus Ex Mortis Campaign 93b8cb.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Circus Ex Mortis Campaign 93b8cb.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Circus Ex Mortis Campaign 93b8cb.yaml deleted file mode 100644 index c7f9a247f..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Circus Ex Mortis Campaign 93b8cb.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27843 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2001337710389944099/BC4BADD35E9E87F6BC0BAC93F0FCEB168848AAAC/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_circus_ex_mortis.json -GUID: 93b8cb -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Circus Ex Mortis Campaign 93b8cb.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Circus Ex Mortis Campaign -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -4.07 - posY: 1.97 - posZ: -123.42 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Close Encounters of the LV-426 Kind 4f5421.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Close Encounters of the LV-426 Kind 4f5421.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Close Encounters of the LV-426 Kind 4f5421.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Close Encounters of the LV-426 Kind 4f5421.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Close Encounters of the LV-426 Kind 4f5421.yaml deleted file mode 100644 index 39886d715..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Close Encounters of the LV-426 Kind 4f5421.yaml +++ /dev/null @@ -1,60 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2018214163836048989/445ECEB6725E5387C41EEB8FBC69A3F247A5AD13/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: lv426 -DragSelectable: true -GMNotes: fancreations/campaign_close_encounters.json -GUID: 4f5421 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Close Encounters of the LV-426 Kind 4f5421.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Close Encounters of the LV-426 Kind -Snap: true -Sticky: true -Tags: -- LargeBox -Tooltip: true -Transform: - posX: -14.86 - posY: 2.58 - posZ: -72.36 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1 - scaleY: 0.14 - scaleZ: 1 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Cyclopean Foundations 169eb9.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Cyclopean Foundations 169eb9.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Cyclopean Foundations 169eb9.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Cyclopean Foundations 169eb9.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Cyclopean Foundations 169eb9.yaml deleted file mode 100644 index 122f87e09..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Cyclopean Foundations 169eb9.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1746813422552975974/8FB3A4AF2D5A102720F630961A2270572ABA2317/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_cyclopean_foundations.json -GUID: 169eb9 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Cyclopean Foundations 169eb9.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Cyclopean Foundations -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -7.51 - posY: 1.62 - posZ: 67.9 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Dark Matter d713f4.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Dark Matter d713f4.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Dark Matter d713f4.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Dark Matter d713f4.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Dark Matter d713f4.yaml deleted file mode 100644 index 6e46a9eb4..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Dark Matter d713f4.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1699532377258479383/73EBF45477C1D927159E5993D99AD144641037EA/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: Final Release -DragSelectable: true -GMNotes: fancreations/campaign_dark_matter.json -GUID: d713f4 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Dark Matter d713f4.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Dark Matter -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -8.25 - posY: 1.63 - posZ: 69.27 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Darkham Horror bc7fa7.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Darkham Horror bc7fa7.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Darkham Horror bc7fa7.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Darkham Horror bc7fa7.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Darkham Horror bc7fa7.yaml deleted file mode 100644 index dc5d848ed..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Darkham Horror bc7fa7.yaml +++ /dev/null @@ -1,72 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - b: 0.39199 - g: 0.39199 - r: 0.39199 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1692775970051821718/827267BBD7EFBAD3EA384A5A04629B2E5BD88EE5/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_darkham_horror.json -GUID: bc7fa7 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Darkham Horror bc7fa7.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Darkham Horror -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 36.93 - posY: 2.29 - posZ: -84.23 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Essence of Humanity Campaign Box 691339.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Essence of Humanity Campaign Box 691339.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Essence of Humanity Campaign Box 691339.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Essence of Humanity Campaign Box 691339.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Essence of Humanity Campaign Box 691339.yaml deleted file mode 100644 index a983a4d84..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Essence of Humanity Campaign Box 691339.yaml +++ /dev/null @@ -1,60 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1823394900012495167/63C400A27475E745FF94F8837D7A8AECC7F837F4/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_essence_of_humanity.json -GUID: '691339' -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Essence of Humanity Campaign Box 691339.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Essence of Humanity Campaign Box -Snap: true -Sticky: true -Tags: -- LargeBox -Tooltip: true -Transform: - posX: 35.3 - posY: 4.15 - posZ: -6.4 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1 - scaleY: 0.14 - scaleZ: 1 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Future Reflections 0f0680.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Future Reflections 0f0680.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Future Reflections 0f0680.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Future Reflections 0f0680.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Future Reflections 0f0680.yaml deleted file mode 100644 index 68c205106..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Future Reflections 0f0680.yaml +++ /dev/null @@ -1,60 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_COL.obj - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://i.imgur.com/T97bYDU.pnghttps://i.imgur.com/T97bYDU.png - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_future_reflections.json -GUID: 0f0680 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Future Reflections 0f0680.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Future Reflections -Snap: true -Sticky: true -Tags: -- LargeBox -Tooltip: true -Transform: - posX: -9.2 - posY: 1.63 - posZ: 68.86 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1 - scaleY: 0.14 - scaleZ: 1 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Half-Life b46db2.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Half-Life b46db2.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Half-Life b46db2.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Half-Life b46db2.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Half-Life b46db2.yaml deleted file mode 100644 index 4325246e9..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Half-Life b46db2.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27843 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2005838229417815473/BC879D878262BA9FBD9040AE4F952468C3C4C2CC/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_half-life.json -GUID: b46db2 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Half-Life b46db2.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Half-Life -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -23.67 - posY: 1.97 - posZ: -108.2 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Heart of Darkness cc95ff.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Heart of Darkness cc95ff.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Heart of Darkness cc95ff.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Heart of Darkness cc95ff.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Heart of Darkness cc95ff.yaml deleted file mode 100644 index 4c8446248..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Heart of Darkness cc95ff.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27843 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2088037933344388834/4ECD1EA2BEA99E4C49F25B6C3077258791E4A9C4/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_heart_of_darkness.json -GUID: cc95ff -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Heart of Darkness cc95ff.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Heart of Darkness -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 12.25 - posY: 1.5 - posZ: 12 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Idol Thoughts 2d417b.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Idol Thoughts 2d417b.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Idol Thoughts 2d417b.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Idol Thoughts 2d417b.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Idol Thoughts 2d417b.yaml deleted file mode 100644 index 4820ab70e..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Idol Thoughts 2d417b.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1011563111884720834/103D38A8FBBFA64EB66439667F8775B15FC679C9/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_idol_thoughts.json -GUID: 2d417b -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Idol Thoughts 2d417b.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Idol Thoughts -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -7.85 - posY: 1.63 - posZ: 68.83 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Into the Shadowlands 019847.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Into the Shadowlands 019847.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Into the Shadowlands 019847.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Into the Shadowlands 019847.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Into the Shadowlands 019847.yaml deleted file mode 100644 index a37870d73..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Into the Shadowlands 019847.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142946871/EAA18FFE753B1ED020A9F3117E9654B093369D26/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_into_the_shadowland.json -GUID: 019847 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Into the Shadowlands 019847.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Into the Shadowlands -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -5.02 - posY: 1.62 - posZ: 70.21 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Jumanji b46db2.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Jumanji b46db2.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Jumanji b46db2.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Jumanji b46db2.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Jumanji b46db2.yaml deleted file mode 100644 index b5398c49b..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Jumanji b46db2.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1847049778276522891/B0F1D72796E5A43963B6EFA6B7FD870A89B139AF/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_jumanji.json -GUID: b46db2 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Jumanji b46db2.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Jumanji -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 17.14 - posY: 3.39 - posZ: -31.21 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kaimonogatari 2df25a.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kaimonogatari 2df25a.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kaimonogatari 2df25a.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kaimonogatari 2df25a.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kaimonogatari 2df25a.yaml deleted file mode 100644 index 1752ffe2f..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kaimonogatari 2df25a.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1673610640345018565/0AFEB7913AD4F24AA04D2CB7DCD97106F58D33D9/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: version 1.41 -DragSelectable: true -GMNotes: fancreations/campaign_kaimonogatari.json -GUID: 2df25a -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Kaimonogatari 2df25a.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Kaimonogatari -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -7.32 - posY: 1.63 - posZ: 68.34 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kiedy sny Stają się Rzeczywiścią acdf16.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kiedy sny Stają się Rzeczywiścią acdf16.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kiedy sny Stają się Rzeczywiścią acdf16.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kiedy sny Stają się Rzeczywiścią acdf16.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kiedy sny Stają się Rzeczywiścią acdf16.yaml deleted file mode 100644 index 6d0698c21..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Kiedy sny Stają się Rzeczywiścią acdf16.yaml +++ /dev/null @@ -1,74 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142937909/81868D8E838249B9D5C467282B6EF12DC5879CA5/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_kiedy_sny_staj%C4%85_si%C4%99_rzeczywi%C5%9Bci%C4%85.json -GUID: acdf16 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include "Custom_Model Kiedy sny Staj\u0105 si\u0119 Rzeczywi\u015Bci\u0105 - acdf16.ttslua" -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: "Kiedy sny Staj\u0105 si\u0119 Rzeczywi\u015Bci\u0105" -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -7.37 - posY: 1.63 - posZ: 68.08 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Machining A Mystery 79b36d.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Machining A Mystery 79b36d.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Machining A Mystery 79b36d.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Machining A Mystery 79b36d.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Machining A Mystery 79b36d.yaml deleted file mode 100644 index 89e42a9d6..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Machining A Mystery 79b36d.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1860561550045252585/5B883A570DB12EF90E66C9AC83D48B64A397F27D/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_machining_a_mystery.json -GUID: 79b36d -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Machining A Mystery 79b36d.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Machining A Mystery -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -23.95 - posY: 2.36 - posZ: -59.24 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model North Country Cycle aaceca.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model North Country Cycle aaceca.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model North Country Cycle aaceca.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model North Country Cycle aaceca.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model North Country Cycle aaceca.yaml deleted file mode 100644 index 7e0c25449..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model North Country Cycle aaceca.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142942211/3504BAF688D57DC30E7E1E2009A0FD4951D3BA58/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_north_country_cycle.json -GUID: aaceca -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model North Country Cycle aaceca.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: North Country Cycle -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -8.64 - posY: 1.62 - posZ: 66.44 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Of Sphinx and Sands edb650.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Of Sphinx and Sands edb650.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Of Sphinx and Sands edb650.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Of Sphinx and Sands edb650.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Of Sphinx and Sands edb650.yaml deleted file mode 100644 index 1e07ac3e0..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Of Sphinx and Sands edb650.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1705159936395227290/3E915F544AB47D63A4B1D05B0412216586EFA34A/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_of_sphinx_and_sands.json -GUID: edb650 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Of Sphinx and Sands edb650.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Of Sphinx and Sands -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.65 - posY: 1.63 - posZ: 69.45 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ordo Templi Orientis 608bea.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ordo Templi Orientis 608bea.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ordo Templi Orientis 608bea.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ordo Templi Orientis 608bea.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ordo Templi Orientis 608bea.yaml deleted file mode 100644 index ca1d20940..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Ordo Templi Orientis 608bea.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1017195498765395843/F0F85DBE17C72D5D09BD012DEDBB9E154EB07E7B/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_ordo_templi_orientis.json -GUID: 608bea -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Ordo Templi Orientis 608bea.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Ordo Templi Orientis -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.52 - posY: 1.63 - posZ: 67.75 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Parallel Universe 28e0a1.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Parallel Universe 28e0a1.ttslua deleted file mode 100644 index e6f67c6af..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Parallel Universe 28e0a1.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Parallel Universe 28e0a1.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Parallel Universe 28e0a1.yaml deleted file mode 100644 index 515311545..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Parallel Universe 28e0a1.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142944953/7A5D3A94BF4A7798157C999A3E1CEAAFC3652CAC/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_parallel_universe.json -GUID: 28e0a1 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Parallel Universe 28e0a1.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Parallel Universe -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -8.77 - posY: 1.63 - posZ: 70.12 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Pokemon Eldritch Edition 75fe78.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Pokemon Eldritch Edition 75fe78.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Pokemon Eldritch Edition 75fe78.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Pokemon Eldritch Edition 75fe78.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Pokemon Eldritch Edition 75fe78.yaml deleted file mode 100644 index c30e97b0c..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Pokemon Eldritch Edition 75fe78.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1597043896926982160/40A0068DAB05395205E184765110430CAADDA2CF/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_pokemon_eldrich_edition.json -GUID: 75fe78 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Pokemon Eldritch Edition 75fe78.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Pokemon Eldritch Edition -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.74 - posY: 1.63 - posZ: 67.22 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Souls of Darkness a94e6b.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Souls of Darkness a94e6b.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Souls of Darkness a94e6b.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Souls of Darkness a94e6b.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Souls of Darkness a94e6b.yaml deleted file mode 100644 index b31d3ae3d..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Souls of Darkness a94e6b.yaml +++ /dev/null @@ -1,72 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - b: 0.40592 - g: 0.40592 - r: 0.40592 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://i.ibb.co/SrtzMNN/souls-of-darkness.png - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_souls_of_darkness.json -GUID: a94e6b -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Souls of Darkness a94e6b.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Souls of Darkness -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 18.63 - posY: 1.85 - posZ: 24.43 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Strange Aeons 2abdd6.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Strange Aeons 2abdd6.ttslua deleted file mode 100644 index e6f67c6af..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Strange Aeons 2abdd6.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Strange Aeons 2abdd6.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Strange Aeons 2abdd6.yaml deleted file mode 100644 index 16a4c98f9..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Strange Aeons 2abdd6.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142947772/120E2BA8DF8C4E2AAC9E059FA046CC3A6229ECDF/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: A Pathfinder Adventure for Arkham Horror -DragSelectable: true -GMNotes: fancreations/campaign_strange_aeons.json -GUID: 2abdd6 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Strange Aeons 2abdd6.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Strange Aeons -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.02 - posY: 1.63 - posZ: 68.43 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The (Unofficial) Return to The Innsmouth Conspiracy bba2b6.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The (Unofficial) Return to The Innsmouth Conspiracy bba2b6.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The (Unofficial) Return to The Innsmouth Conspiracy bba2b6.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The (Unofficial) Return to The Innsmouth Conspiracy bba2b6.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The (Unofficial) Return to The Innsmouth Conspiracy bba2b6.yaml deleted file mode 100644 index f84027c81..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The (Unofficial) Return to The Innsmouth Conspiracy bba2b6.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 0 - rotZ: 0 - scaleX: 2 - scaleY: 2 - scaleZ: 2 -Autoraise: true -ColorDiffuse: - a: 0.27843 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2021606446230436832/9485F353EEE9717261DC545E0AE772A33A9E7E73/ - MaterialIndex: 3 - MeshURL: http://pastebin.com/raw.php?i=uWAmuNZ2 - NormalURL: '' - TypeIndex: 0 -Description: v3 -DragSelectable: true -GMNotes: fancreations/campaign_unofficial_return_to_tic.json -GUID: bba2b6 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The (Unofficial) Return to The Innsmouth Conspiracy bba2b6.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: 'The (Unofficial) Return to The Innsmouth Conspiracy ' -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -16.34 - posY: 3.32 - posZ: -73.44 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2 - scaleY: 0.11 - scaleZ: 1.69 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Approaching Storm ab6b9a.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Approaching Storm ab6b9a.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Approaching Storm ab6b9a.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Approaching Storm ab6b9a.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Approaching Storm ab6b9a.yaml deleted file mode 100644 index bc20e20d4..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Approaching Storm ab6b9a.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142917748/FA44959693A82787BC34D6FA2487911AB24E619B/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_approaching_storm.json -GUID: ab6b9a -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Approaching Storm ab6b9a.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Approaching Storm -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -8.54 - posY: 1.63 - posZ: 69.14 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Color Out of Oz be7d21.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Color Out of Oz be7d21.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Color Out of Oz be7d21.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Color Out of Oz be7d21.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Color Out of Oz be7d21.yaml deleted file mode 100644 index 3a6958928..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Color Out of Oz be7d21.yaml +++ /dev/null @@ -1,72 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: 0 - posY: 0 - posZ: 0 - rotX: 270 - rotY: 0 - rotZ: 0 - scaleX: 2 - scaleY: 2 - scaleZ: 2 -Autoraise: true -ColorDiffuse: - b: 0.40592 - g: 0.40592 - r: 0.40592 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1972044023032948791/D32BECDAF5C9309577EE0CE585E980F62EFBCEF3/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_color_out_of_oz.json -GUID: be7d21 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Color Out of Oz be7d21.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Color Out of Oz -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -37.7 - posY: 3.22 - posZ: -97.69 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Dying Star bcfff6.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Dying Star bcfff6.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Dying Star bcfff6.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Dying Star bcfff6.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Dying Star bcfff6.yaml deleted file mode 100644 index 0c7d7b971..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Dying Star bcfff6.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142922162/AD09D68EC542F778CCA3A4F5B33E17EF50AFE31B/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_dying_star.json -GUID: bcfff6 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Dying Star bcfff6.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Dying Star -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -8.44 - posY: 1.63 - posZ: 68.4 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Ghosts Of Onigawa Campaign Expansion 8daa73.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Ghosts Of Onigawa Campaign Expansion 8daa73.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Ghosts Of Onigawa Campaign Expansion 8daa73.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Ghosts Of Onigawa Campaign Expansion 8daa73.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Ghosts Of Onigawa Campaign Expansion 8daa73.yaml deleted file mode 100644 index 03a948287..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Ghosts Of Onigawa Campaign Expansion 8daa73.yaml +++ /dev/null @@ -1,60 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://uploads-ssl.webflow.com/608a6a98b5956379a9c9e768/60eb7c9fb63de7d60d8d67ec_boxart-defuse.png - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_onigawa.json -GUID: 8daa73 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Ghosts Of Onigawa Campaign Expansion 8daa73.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Ghosts Of Onigawa Campaign Expansion -Snap: true -Sticky: true -Tags: -- LargeBox -Tooltip: true -Transform: - posX: -1.06 - posY: 4.29 - posZ: 4.03 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1 - scaleY: 0.14 - scaleZ: 1 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The London Set 0f96ac.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The London Set 0f96ac.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The London Set 0f96ac.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The London Set 0f96ac.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The London Set 0f96ac.yaml deleted file mode 100644 index 7aab8c21f..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The London Set 0f96ac.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142939236/70113DAB44263CD5EA5A0913B4325A57B8113A4C/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_london_set.json -GUID: 0f96ac -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The London Set 0f96ac.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The London Set -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -7.64 - posY: 1.63 - posZ: 68.55 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Outsider 3c175c.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Outsider 3c175c.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Outsider 3c175c.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Outsider 3c175c.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Outsider 3c175c.yaml deleted file mode 100644 index fb6389041..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Outsider 3c175c.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142944372/7F67F8FDAD99C9C2A6A6A5E98C548681117D092C/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_outsider.json -GUID: 3c175c -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Outsider 3c175c.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Outsider -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -8.83 - posY: 1.63 - posZ: 67.76 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Sands Of Memphis Campaign Expansion 2634e3.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Sands Of Memphis Campaign Expansion 2634e3.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Sands Of Memphis Campaign Expansion 2634e3.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Sands Of Memphis Campaign Expansion 2634e3.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Sands Of Memphis Campaign Expansion 2634e3.yaml deleted file mode 100644 index e4426a130..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Sands Of Memphis Campaign Expansion 2634e3.yaml +++ /dev/null @@ -1,60 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://i.imgur.com/uGpKv09.png - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_memphis.json -GUID: 2634e3 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Sands Of Memphis Campaign Expansion 2634e3.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Sands Of Memphis Campaign Expansion -Snap: true -Sticky: true -Tags: -- LargeBox -Tooltip: true -Transform: - posX: 0 - posY: 1.5 - posZ: -5 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 1 - scaleY: 0.14 - scaleZ: 1 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The War of the Worlds 19d469.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The War of the Worlds 19d469.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The War of the Worlds 19d469.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The War of the Worlds 19d469.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The War of the Worlds 19d469.yaml deleted file mode 100644 index 8b72e09f1..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The War of the Worlds 19d469.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1461933574036562700/261026F89C2322BF6390608AAB7DE43BEFB6240A/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_war_of_the_world.json -GUID: 19d469 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The War of the Worlds 19d469.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The War of the Worlds -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.1 - posY: 1.62 - posZ: 67.41 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Winter Winds 754057.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Winter Winds 754057.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Winter Winds 754057.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Winter Winds 754057.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Winter Winds 754057.yaml deleted file mode 100644 index 39197fe47..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model Winter Winds 754057.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142974098/BF07864708BDE2804C0495637DDD55E85CC883EA/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/campaign_winter_winds.json -GUID: '754057' -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Winter Winds 754057.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Winter Winds -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -20.94 - posY: 1.61 - posZ: 76.41 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Crown of Egil 7458b7.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Crown of Egil 7458b7.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Crown of Egil 7458b7.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Crown of Egil 7458b7.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Crown of Egil 7458b7.yaml deleted file mode 100644 index ff1ee631b..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Campaigns 89c32e/Custom_Model The Crown of Egil 7458b7.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://i.imgur.com/Vn2CXra.png - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: version 1.1 -DragSelectable: true -GMNotes: fancreations/campaign_crown_of_egil.json -GUID: 7458b7 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include "Custom_Model \uF729The Crown of Egil 7458b7.ttslua" -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: "\uF729The Crown of Egil" -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -7.14 - posY: 1.62 - posZ: 68.8 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c.yaml deleted file mode 100644 index 99d03904d..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c.yaml +++ /dev/null @@ -1,142 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -Bag: - Order: 0 -ColorDiffuse: - b: 1 - g: 1 - r: 1 -ContainedObjects: -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Undying 965030.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Thing in the Woods c90c49.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Symphony of Erich Zann b7c6be.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Svalbard Event 7bc42b.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Strange Case of Dr. Jekyll and Mr. Hyde 695a4d.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Stolen Baillius bfefd4.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Red Room fa4327.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Pensher Wyrm 504f38.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Nephew Calls 3ddd12.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Nameless City 9d3083.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Legend of Sleepy Hollow 0500f1.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Invisible Man 17d01a.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Grand Oak Hotel 5ccf55.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Festival 29d22a.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Fall of the House of Usher 42bdd3.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Facts in the Case of M. Valdemar 238d6f.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Curse of Amulotep 0d7a8d.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Colour out of Space 5b81ff.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The - Collector 9810eb.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Stranger - Things 408301.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return - to the Wendigo 33f0f3.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return - to Consternation on the Constellation 34ec55.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Miskatonic - Mouse 6defb8.yaml' -- !include "Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Masks - of Nyarlathotep \u2013 New York 94a1f8.yaml" -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Last - Call at Roxie''s c6a1ca.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Knightfall - df62e8.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Jenny''s - Choice a61b48.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model In - Blackest Pits 68380c.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Happy''s - Funhouse e7d9f8.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Fortune - or Folly - Parallel Rex Murphy Set 7fa06f.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Don''t - Starve ffc7ef.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Delta - Green Convergence ac164e.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Darkness - Falls c6a612.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Cosmic - Pantheon ec74df.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Consternation - on the Constellation 0ec730.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Carnevale - of Spiders e57017.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Bridge - of Sighs 578e97.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Blood - Spilled in Salem 4237da.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Arkham - Incidents f1bfa2.yaml' -- !include 'Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Against - the Wendigo 4d5fa0.yaml' -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1758068588410864087/97EBA1F7BA51181A664CE5A733AB092BA843E32D/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/core_h_MSH.obj - NormalURL: '' - TypeIndex: 6 -Description: '' -DragSelectable: true -GMNotes: '' -GUID: 5db60c -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: '' -LuaScriptState: '{"ml":[]}' -MaterialIndex: -1 -MeasureMovement: false -MeshIndex: -1 -Name: Custom_Model_Bag -Nickname: Fan-Made Standalone Scenarios -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9 - posY: 1.48 - posZ: -50 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 0.5 - scaleY: 0.1 - scaleZ: 0.5 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Against the Wendigo 4d5fa0.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Against the Wendigo 4d5fa0.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Against the Wendigo 4d5fa0.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Against the Wendigo 4d5fa0.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Against the Wendigo 4d5fa0.yaml deleted file mode 100644 index 80b73e2bc..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Against the Wendigo 4d5fa0.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142901599/7EE6EF24852C443DF5E92CF9498881E321CEE75A/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_wendigo.json -GUID: 4d5fa0 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Against the Wendigo 4d5fa0.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Against the Wendigo -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 20.3 - posY: 1.81 - posZ: 7.55 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Arkham Incidents f1bfa2.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Arkham Incidents f1bfa2.ttslua deleted file mode 100644 index e6f67c6af..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Arkham Incidents f1bfa2.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Arkham Incidents f1bfa2.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Arkham Incidents f1bfa2.yaml deleted file mode 100644 index 524170609..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Arkham Incidents f1bfa2.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1865053883967763315/27C1F4299B5381DF5A40739696DC4CE6197D2BDC/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_incidents.json -GUID: f1bfa2 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Arkham Incidents f1bfa2.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Arkham Incidents -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 59.76 - posY: 3.4 - posZ: -68.94 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Blood Spilled in Salem 4237da.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Blood Spilled in Salem 4237da.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Blood Spilled in Salem 4237da.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Blood Spilled in Salem 4237da.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Blood Spilled in Salem 4237da.yaml deleted file mode 100644 index 547750568..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Blood Spilled in Salem 4237da.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142918658/204E105211839B1E202E834F4A5C69E8E6A50A28/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_salem.json -GUID: 4237da -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Blood Spilled in Salem 4237da.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Blood Spilled in Salem -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -10.62 - posY: 1.62 - posZ: 65.3 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Bridge of Sighs 578e97.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Bridge of Sighs 578e97.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Bridge of Sighs 578e97.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Bridge of Sighs 578e97.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Bridge of Sighs 578e97.yaml deleted file mode 100644 index 74ca40617..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Bridge of Sighs 578e97.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142919243/F3ED3E5B6B8725F536FCDA4FB2D40E1D11725037/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_bridge_of_sighs.json -GUID: 578e97 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Bridge of Sighs 578e97.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Bridge of Sighs -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -8.3 - posY: 1.62 - posZ: 66.34 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Carnevale of Spiders e57017.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Carnevale of Spiders e57017.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Carnevale of Spiders e57017.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Carnevale of Spiders e57017.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Carnevale of Spiders e57017.yaml deleted file mode 100644 index ac86ae88d..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Carnevale of Spiders e57017.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1474319121422110285/8BA9D8C5CFA6D4E35DFC2077002CB2256DCFB2D7/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: A Farkham-con Original. Requires 3 XP -DragSelectable: true -GMNotes: fancreations/scenario_carnevale_of_spiders.json -GUID: e57017 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Carnevale of Spiders e57017.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Carnevale of Spiders -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -8.96 - posY: 1.62 - posZ: 64.59 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Consternation on the Constellation 0ec730.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Consternation on the Constellation 0ec730.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Consternation on the Constellation 0ec730.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Consternation on the Constellation 0ec730.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Consternation on the Constellation 0ec730.yaml deleted file mode 100644 index 721771320..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Consternation on the Constellation 0ec730.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/762723517666349452/B8551E1479CED3BADEF4AF3B0A727EB7768C0289/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_consternation_on_the_constellation.json -GUID: 0ec730 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Consternation on the Constellation 0ec730.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Consternation on the Constellation -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.23 - posY: 1.66 - posZ: 64.3 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Cosmic Pantheon ec74df.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Cosmic Pantheon ec74df.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Cosmic Pantheon ec74df.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Cosmic Pantheon ec74df.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Cosmic Pantheon ec74df.yaml deleted file mode 100644 index d014e3c2e..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Cosmic Pantheon ec74df.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1844797993644656426/EC19A65BD3119D5FA229F502D65D1D8DAA9E0ECB/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: Mint Tea Fan & Hauke -DragSelectable: true -GMNotes: fancreations/scenario_cosmic_pantheon.json -GUID: ec74df -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Cosmic Pantheon ec74df.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Cosmic Pantheon -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 28.57 - posY: 2.71 - posZ: -13.99 - rotX: 0 - rotY: 270 - rotZ: 357 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Darkness Falls c6a612.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Darkness Falls c6a612.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Darkness Falls c6a612.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Darkness Falls c6a612.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Darkness Falls c6a612.yaml deleted file mode 100644 index 7732c1bbf..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Darkness Falls c6a612.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1487830597915523099/252BD2089F9DEF3F337BB8AE681939DE98C1EFA7/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_darkness_falls.json -GUID: c6a612 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Darkness Falls c6a612.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Darkness Falls -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.27 - posY: 1.63 - posZ: 66.13 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Delta Green Convergence ac164e.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Delta Green Convergence ac164e.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Delta Green Convergence ac164e.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Delta Green Convergence ac164e.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Delta Green Convergence ac164e.yaml deleted file mode 100644 index b9dc67f77..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Delta Green Convergence ac164e.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142900469/BDA1068C5A88459AE805540FE05B8092C4F8F392/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_delta_green.json -GUID: ac164e -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Delta Green Convergence ac164e.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Delta Green Convergence -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -10.23 - posY: 1.62 - posZ: 66.49 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Don't Starve ffc7ef.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Don't Starve ffc7ef.ttslua deleted file mode 100644 index e6f67c6af..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Don't Starve ffc7ef.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Don't Starve ffc7ef.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Don't Starve ffc7ef.yaml deleted file mode 100644 index dd32e03b9..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Don't Starve ffc7ef.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1646593716898209387/B827263B809A6C8E1042BDF1C8D33E58458C2EF4/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_dont_starve.json -GUID: ffc7ef -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Don''t Starve ffc7ef.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Don't Starve -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -10.84 - posY: 1.62 - posZ: 65.41 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Fortune or Folly - Parallel Rex Murphy Set 7fa06f.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Fortune or Folly - Parallel Rex Murphy Set 7fa06f.ttslua deleted file mode 100644 index e6f67c6af..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Fortune or Folly - Parallel Rex Murphy Set 7fa06f.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Happy's Funhouse e7d9f8.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Happy's Funhouse e7d9f8.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Happy's Funhouse e7d9f8.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Happy's Funhouse e7d9f8.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Happy's Funhouse e7d9f8.yaml deleted file mode 100644 index 748462e7c..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Happy's Funhouse e7d9f8.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142976303/C24C7169FD11E5D151DD2F754D5B9A5563D5DABB/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_happys_funhouse.json -GUID: e7d9f8 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Happy''s Funhouse e7d9f8.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Happy's Funhouse -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.66 - posY: 1.63 - posZ: 67.68 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model In Blackest Pits 68380c.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model In Blackest Pits 68380c.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model In Blackest Pits 68380c.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model In Blackest Pits 68380c.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model In Blackest Pits 68380c.yaml deleted file mode 100644 index 3a37f19c3..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model In Blackest Pits 68380c.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1016065907889320438/3DC5DD89D5DB56BE6EFDAC4A96E8063765576EA1/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_in_blackest_pits.json -GUID: 68380c -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model In Blackest Pits 68380c.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: In Blackest Pits -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -10.33 - posY: 1.62 - posZ: 65.72 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Jenny's Choice a61b48.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Jenny's Choice a61b48.ttslua deleted file mode 100644 index e6f67c6af..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Jenny's Choice a61b48.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Jenny's Choice a61b48.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Jenny's Choice a61b48.yaml deleted file mode 100644 index 88464994e..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Jenny's Choice a61b48.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/790858329422808079/1407B0AB89A9DBCFEE07A84A0979829556D84A78/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_jennys_choice.json -GUID: a61b48 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Jenny''s Choice a61b48.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Jenny's Choice -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -7.72 - posY: 1.62 - posZ: 66.96 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Knightfall df62e8.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Knightfall df62e8.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Knightfall df62e8.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Knightfall df62e8.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Knightfall df62e8.yaml deleted file mode 100644 index bc84bd12a..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Knightfall df62e8.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142937041/3253F31B9483C3B5D0A98BA7E479E006FBF8D270/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_knightfall.json -GUID: df62e8 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Knightfall df62e8.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Knightfall -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -8.95 - posY: 1.62 - posZ: 65.45 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Last Call at Roxie's c6a1ca.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Last Call at Roxie's c6a1ca.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Last Call at Roxie's c6a1ca.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Last Call at Roxie's c6a1ca.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Last Call at Roxie's c6a1ca.yaml deleted file mode 100644 index fed5573d8..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Last Call at Roxie's c6a1ca.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142938527/354E6204BB01AED91EAEB19D99E4D95620F99C56/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: An Android Universe crossover adventure -DragSelectable: true -GMNotes: fancreations/scenario_last_call_at_roxies.json -GUID: c6a1ca -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Last Call at Roxie''s c6a1ca.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Last Call at Roxie's -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.76 - posY: 1.62 - posZ: 64.39 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Masks of Nyarlathotep – New York 94a1f8.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Masks of Nyarlathotep – New York 94a1f8.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Masks of Nyarlathotep – New York 94a1f8.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Masks of Nyarlathotep – New York 94a1f8.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Masks of Nyarlathotep – New York 94a1f8.yaml deleted file mode 100644 index 5ebd5045d..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Masks of Nyarlathotep – New York 94a1f8.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142939810/7A53406FA1EFA9D556EF559B24A679E566114745/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_masks_of_nyarlathotep.json -GUID: 94a1f8 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include "Custom_Model Masks of Nyarlathotep \u2013 New York 94a1f8.ttslua" -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: "Masks of Nyarlathotep \u2013 New York" -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -10.84 - posY: 1.62 - posZ: 67.31 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Miskatonic Mouse 6defb8.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Miskatonic Mouse 6defb8.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Miskatonic Mouse 6defb8.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Miskatonic Mouse 6defb8.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Miskatonic Mouse 6defb8.yaml deleted file mode 100644 index 579270de2..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Miskatonic Mouse 6defb8.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1620690956766119953/F8003A1B5AC39F2D2DABFF6D0AA2168CEC8BFA2C/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_miskatonic_mouse.json -GUID: 6defb8 -Grid: true -GridProjection: false -Hands: true -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Miskatonic Mouse 6defb8.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Miskatonic Mouse -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.06 - posY: 1.63 - posZ: 67.74 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to Consternation on the Constellation 34ec55.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to Consternation on the Constellation 34ec55.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to Consternation on the Constellation 34ec55.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to Consternation on the Constellation 34ec55.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to Consternation on the Constellation 34ec55.yaml deleted file mode 100644 index cb6102d02..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to Consternation on the Constellation 34ec55.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: 0 - posY: 0 - posZ: 0 - rotX: 270 - rotY: 0 - rotZ: 0 - scaleX: 2 - scaleY: 2 - scaleZ: 2 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://github.com/ArkhamDotCards/returntoconsternationontheconstellation/blob/main/product/enUS/constellation-boxart-difuse.png?raw=true - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_return_to_consternation_on_the_constellation.json -GUID: 34ec55 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Return to Consternation on the Constellation 34ec55.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Return to Consternation on the Constellation -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 20 - posY: 1.5 - posZ: -5 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to the Wendigo 33f0f3.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to the Wendigo 33f0f3.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to the Wendigo 33f0f3.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to the Wendigo 33f0f3.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to the Wendigo 33f0f3.yaml deleted file mode 100644 index 273a8dc5b..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Return to the Wendigo 33f0f3.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: 0 - posY: 0 - posZ: 0 - rotX: 270 - rotY: 0 - rotZ: 0 - scaleX: 2 - scaleY: 2 - scaleZ: 2 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: https://github.com/ArkhamDotCards/returntothewendigo/blob/main/product/enUS/wendigo-boxart-difuse.png?raw=true - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_return_to_the_wendigo.json -GUID: 33f0f3 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Return to the Wendigo 33f0f3.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Return to the Wendigo -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 20 - posY: 1.5 - posZ: 5 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Stranger Things 408301.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Stranger Things 408301.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Stranger Things 408301.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Stranger Things 408301.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Stranger Things 408301.yaml deleted file mode 100644 index 6a39c8a19..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model Stranger Things 408301.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142948271/A763104B91306431654FBA9E3D88FE0E23CE6E6E/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_stranger_things.json -GUID: '408301' -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model Stranger Things 408301.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: Stranger Things -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -11.22 - posY: 1.62 - posZ: 66.5 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Collector 9810eb.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Collector 9810eb.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Collector 9810eb.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Collector 9810eb.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Collector 9810eb.yaml deleted file mode 100644 index d1e0e47b2..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Collector 9810eb.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142920786/52ED9B6276539BF3E1F332C363B21B3D7F6960AA/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_the_collector.json -GUID: 9810eb -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Collector 9810eb.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Collector -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -10.6 - posY: 1.68 - posZ: 64.25 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Colour out of Space 5b81ff.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Colour out of Space 5b81ff.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Colour out of Space 5b81ff.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Colour out of Space 5b81ff.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Colour out of Space 5b81ff.yaml deleted file mode 100644 index e98bc7fdd..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Colour out of Space 5b81ff.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142919895/4026718A421BE11AC64320BE9BC2515B364D066E/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_color_out_of_space.json -GUID: 5b81ff -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Colour out of Space 5b81ff.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Colour out of Space -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.93 - posY: 1.62 - posZ: 64.8 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Curse of Amulotep 0d7a8d.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Curse of Amulotep 0d7a8d.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Curse of Amulotep 0d7a8d.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Curse of Amulotep 0d7a8d.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Curse of Amulotep 0d7a8d.yaml deleted file mode 100644 index 26f5e87d6..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Curse of Amulotep 0d7a8d.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142921541/F138D6DF73FB79AC6D1C420869299A481AFA7B90/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_the_curse_of_amulotep.json -GUID: 0d7a8d -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Curse of Amulotep 0d7a8d.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Curse of Amulotep -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -6.7 - posY: 1.62 - posZ: 66.35 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Facts in the Case of M. Valdemar 238d6f.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Facts in the Case of M. Valdemar 238d6f.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Facts in the Case of M. Valdemar 238d6f.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Facts in the Case of M. Valdemar 238d6f.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Facts in the Case of M. Valdemar 238d6f.yaml deleted file mode 100644 index 23e5e871a..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Facts in the Case of M. Valdemar 238d6f.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1870695908503531344/DE3BBAD0CF8FCE5B05B8B18B44F049ECF06BCA5A/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_valdemar.json -GUID: 238d6f -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Facts in the Case of M. Valdemar 238d6f.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Facts in the Case of M. Valdemar -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -10.6 - posY: 1.68 - posZ: 64.25 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Fall of the House of Usher 42bdd3.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Fall of the House of Usher 42bdd3.ttslua deleted file mode 100644 index e6f67c6af..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Fall of the House of Usher 42bdd3.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Fall of the House of Usher 42bdd3.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Fall of the House of Usher 42bdd3.yaml deleted file mode 100644 index 4baced204..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Fall of the House of Usher 42bdd3.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1771580824970152646/1C2D909AF92814C33B43D22F0EE1D6B8FD260998/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_house_of_usher.json -GUID: 42bdd3 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Fall of the House of Usher 42bdd3.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Fall of the House of Usher -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 15.11 - posY: 3.18 - posZ: -58.67 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Festival 29d22a.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Festival 29d22a.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Festival 29d22a.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Festival 29d22a.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Festival 29d22a.yaml deleted file mode 100644 index ed00fd27e..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Festival 29d22a.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142936385/DCE942F9A1172E9C55A36E4593F5CDC71D9BC3AD/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_the_festival.json -GUID: 29d22a -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Festival 29d22a.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Festival -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.31 - posY: 1.62 - posZ: 64.66 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Grand Oak Hotel 5ccf55.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Grand Oak Hotel 5ccf55.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Grand Oak Hotel 5ccf55.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Grand Oak Hotel 5ccf55.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Grand Oak Hotel 5ccf55.yaml deleted file mode 100644 index f7c3a72e2..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Grand Oak Hotel 5ccf55.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142935568/34A42BC3AEF7764F8D7BB242DB08FD36B8EC6DCB/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_grand_oak_hotel.json -GUID: 5ccf55 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Grand Oak Hotel 5ccf55.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Grand Oak Hotel -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -7.46 - posY: 1.62 - posZ: 64.61 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Invisible Man 17d01a.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Invisible Man 17d01a.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Invisible Man 17d01a.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Legend of Sleepy Hollow 0500f1.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Legend of Sleepy Hollow 0500f1.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Legend of Sleepy Hollow 0500f1.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Legend of Sleepy Hollow 0500f1.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Legend of Sleepy Hollow 0500f1.yaml deleted file mode 100644 index bc9d47afe..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Legend of Sleepy Hollow 0500f1.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1617311203420460064/3D20A71D13F484BEEBCF572E827CD38FF3DF57E4/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_sleepy_hollow.json -GUID: 0500f1 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Legend of Sleepy Hollow 0500f1.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Legend of Sleepy Hollow -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: 7.67 - posY: 3.37 - posZ: -40.85 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nameless City 9d3083.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nameless City 9d3083.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nameless City 9d3083.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nameless City 9d3083.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nameless City 9d3083.yaml deleted file mode 100644 index 316c9b958..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nameless City 9d3083.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1797477398306699180/7C5363FFCCDCD4A1AF2A0C71B2A7E5F96D5ACCA4/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_the_nameless_city.json -GUID: 9d3083 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Nameless City 9d3083.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Nameless City -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -10.53 - posY: 1.62 - posZ: 65.91 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.45 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nephew Calls 3ddd12.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nephew Calls 3ddd12.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nephew Calls 3ddd12.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nephew Calls 3ddd12.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nephew Calls 3ddd12.yaml deleted file mode 100644 index 8ee98f6b2..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Nephew Calls 3ddd12.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142940439/EE68DD668C18F8F8C61B0F2BABA6D548B17A6EA7/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_the_nephew_calls.json -GUID: 3ddd12 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Nephew Calls 3ddd12.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Nephew Calls -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.29 - posY: 1.62 - posZ: 65.33 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Pensher Wyrm 504f38.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Pensher Wyrm 504f38.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Pensher Wyrm 504f38.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Pensher Wyrm 504f38.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Pensher Wyrm 504f38.yaml deleted file mode 100644 index 81a719b65..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Pensher Wyrm 504f38.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142945578/6BA34FBD61F7AD38DE8B2B9E5D5F067406B7CC77/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_the_pensher_wyrm.json -GUID: 504f38 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Pensher Wyrm 504f38.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Pensher Wyrm -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.37 - posY: 1.62 - posZ: 65.42 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.2 - scaleZ: 2.46 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Red Room fa4327.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Red Room fa4327.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Red Room fa4327.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Red Room fa4327.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Red Room fa4327.yaml deleted file mode 100644 index 4b2378ea7..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Red Room fa4327.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142946225/F5A6228957B37E945B425681115D09E7B8543BC6/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_the_red_room.json -GUID: fa4327 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Red Room fa4327.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Red Room -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -11.09 - posY: 1.62 - posZ: 66.55 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Stolen Baillius bfefd4.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Stolen Baillius bfefd4.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Stolen Baillius bfefd4.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Stolen Baillius bfefd4.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Stolen Baillius bfefd4.yaml deleted file mode 100644 index 0ecb63e49..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Stolen Baillius bfefd4.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142943616/2B7B73A110A3EC225C854F85AB009F04859E3806/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_stolen_bacillus.json -GUID: bfefd4 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Stolen Baillius bfefd4.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Stolen Baillius -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -9.01 - posY: 1.61 - posZ: 66.4 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Strange Case of Dr. Jekyll and Mr. Hyde 695a4d.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Strange Case of Dr. Jekyll and Mr. Hyde 695a4d.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Strange Case of Dr. Jekyll and Mr. Hyde 695a4d.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Strange Case of Dr. Jekyll and Mr. Hyde 695a4d.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Strange Case of Dr. Jekyll and Mr. Hyde 695a4d.yaml deleted file mode 100644 index d4b934bad..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Strange Case of Dr. Jekyll and Mr. Hyde 695a4d.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1845919769156839538/7ED48DF559525AF388EDAABCDEED4EE9D25E872A/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_jekyll.json -GUID: 695a4d -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Strange Case of Dr. Jekyll and Mr. Hyde 695a4d.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Strange Case of Dr. Jekyll and Mr. Hyde -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -26.2 - posY: 1.92 - posZ: -120.92 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Svalbard Event 7bc42b.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Svalbard Event 7bc42b.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Svalbard Event 7bc42b.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Svalbard Event 7bc42b.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Svalbard Event 7bc42b.yaml deleted file mode 100644 index 8f49b18a2..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Svalbard Event 7bc42b.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142948942/FA97D7EF94B715ADD1EEE40831114451FBED200B/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_the_svalbard_event.json -GUID: 7bc42b -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Svalbard Event 7bc42b.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Svalbard Event -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -10.24 - posY: 1.62 - posZ: 67.29 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Symphony of Erich Zann b7c6be.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Symphony of Erich Zann b7c6be.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Symphony of Erich Zann b7c6be.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Symphony of Erich Zann b7c6be.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Symphony of Erich Zann b7c6be.yaml deleted file mode 100644 index 59dd3233f..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Symphony of Erich Zann b7c6be.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1254763972105175718/5A09C7E8EBCC79DD9E405FF6F83E49C2C27D5F29/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_symphony_of_erich_zann.json -GUID: b7c6be -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Symphony of Erich Zann b7c6be.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Symphony of Erich Zann -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -10.14 - posY: 1.67 - posZ: 67.99 - rotX: 0 - rotY: 270 - rotZ: 357 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Thing in the Woods c90c49.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Thing in the Woods c90c49.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Thing in the Woods c90c49.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Thing in the Woods c90c49.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Thing in the Woods c90c49.yaml deleted file mode 100644 index de772d0d3..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Thing in the Woods c90c49.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/798737729142949442/404A26E158B9EBC1069A5FBA9BA2331CBFD7851B/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_the_thing_in_the_woods.json -GUID: c90c49 -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Thing in the Woods c90c49.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Thing in the Woods -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -11.01 - posY: 1.62 - posZ: 67.68 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Undying 965030.ttslua b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Undying 965030.ttslua deleted file mode 100644 index 3c2a044ca..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Undying 965030.ttslua +++ /dev/null @@ -1,90 +0,0 @@ --- 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("core/DownloadBox") -end) -__bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) -function onLoad() - local notes = self.getGMNotes() - - -- default parameters (e.g. scenarios) - local buttonParameters = { - label = "Download", - click_function = "buttonClick_download", - function_owner = self, - position = { x = 0, y = 0.1, z = 2.1 }, - height = 250, - width = 800, - font_size = 150, - color = { 0, 0, 0 }, - font_color = { 1, 1, 1 } - } - - -- return to boxes - if string.match(notes, "................") == "campaigns/return" then - buttonParameters.position.z = 2 - - -- official campaign boxes - elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then - buttonParameters.position.z = 6 - buttonParameters.height = 500 - buttonParameters.width = 1700 - buttonParameters.font_size = 350 - - -- investigator boxes - elseif string.match(notes, ".............") == "investigators" then - buttonParameters.position.z = 7 - buttonParameters.height = 850 - buttonParameters.width = 3400 - buttonParameters.font_size = 700 - end - - self.createButton(buttonParameters) -end - -function buttonClick_download() - Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) -end -end) -return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Undying 965030.yaml b/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Undying 965030.yaml deleted file mode 100644 index 2ae737fd1..000000000 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Undying 965030.yaml +++ /dev/null @@ -1,73 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -AttachedDecals: -- CustomDecal: - ImageURL: http://cloud-3.steamusercontent.com/ugc/959719855119695911/931B9829687A20F4DEADB36DA57B7E6D76792231/ - Name: dunwich_back - Size: 7.4 - Transform: - posX: -0.0021877822 - posY: -0.08963572 - posZ: -0.00288731651 - rotX: 270 - rotY: 359.869568 - rotZ: 0 - scaleX: 2.00000215 - scaleY: 2.00000238 - scaleZ: 2.00000262 -Autoraise: true -ColorDiffuse: - a: 0.27451 - b: 1 - g: 1 - r: 1 -CustomMesh: - CastShadows: true - ColliderURL: '' - Convex: true - CustomShader: - FresnelStrength: 0 - SpecularColor: - b: 1 - g: 1 - r: 1 - SpecularIntensity: 0 - SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/1824531491067739120/4AD2D51DAC6215F2866BB2AD15D47109B432B999/ - MaterialIndex: 3 - MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj - NormalURL: '' - TypeIndex: 0 -Description: '' -DragSelectable: true -GMNotes: fancreations/scenario_the_undying.json -GUID: '965030' -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: !include 'Custom_Model The Undying 965030.ttslua' -LuaScriptState: '' -MeasureMovement: false -Name: Custom_Model -Nickname: The Undying -Snap: true -Sticky: true -Tooltip: true -Transform: - posX: -55.36 - posY: 6.3 - posZ: -85.71 - rotX: 0 - rotY: 270 - rotZ: 0 - scaleX: 2.21 - scaleY: 0.46 - scaleZ: 2.42 -Value: 0 -XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801.yaml b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801.yaml index ebabd826d..7b625a4ee 100644 --- a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801.yaml +++ b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801.yaml @@ -10,13 +10,15 @@ ColorDiffuse: g: 1 r: 1 ContainedObjects: -- !include 'Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Bad Blood 451eaa.yaml' -- !include 'Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Red Tide Rising - 5302f2.yaml' - !include 'Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model All or Nothing 72ab92.yaml' -- !include 'Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Read or Die 9e73fa.yaml' +- !include 'Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Bad Blood 451eaa.yaml' - !include 'Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model By the Book cc7eb3.yaml' +- !include 'Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Laid to Rest + e2dd57.yaml' +- !include 'Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Read or Die 9e73fa.yaml' +- !include 'Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Red Tide Rising + 5302f2.yaml' CustomMesh: CastShadows: true ColliderURL: '' @@ -46,7 +48,7 @@ IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: false LuaScript: !include 'Custom_Model_Bag Challenge Scenarios 9f6801.ttslua' -LuaScriptState: "{\"ml\":{\"451eaa\":{\"lock\":false,\"pos\":{\"x\":12.2499580383301,\"y\":1.46560525894165,\"z\":3.98636198043823},\"rot\":{\"x\":359.920135498047,\"y\":269.999908447266,\"z\":0.016873624175787}},\"5302f2\":{\"lock\":false,\"pos\":{\"x\":12.2504663467407,\"y\":1.45853757858276,\"z\":-20.013650894165},\"rot\":{\"x\":359.920135498047,\"y\":270.00146484375,\"z\":0.0168716721236706}},\"72ab92\":{\"lock\":false,\"pos\":{\"x\":12.2520532608032,\"y\":1.4679582118988,\"z\":11.9863719940186},\"rot\":{\"x\":359.920135498047,\"y\":270,\"z\":0.0168737415224314}},\"9e73fa\":{\"lock\":false,\"pos\":{\"x\":12.2500581741333,\"y\":1.46089386940002,\"z\":-12.0136384963989},\"rot\":{\"x\":359.920135498047,\"y\":269.999847412109,\"z\":0.0168744903057814}},\"cc7eb3\":{\"lock\":false,\"pos\":{\"x\":12.2495565414429,\"y\":1.46325027942657,\"z\":-4.01364088058472},\"rot\":{\"x\":359.920135498047,\"y\":269.999908447266,\"z\":0.0168744102120399}}}}\r" +LuaScriptState: '{"ml":{"451eaa":{"lock":false,"pos":{"x":12.252,"y":1.4815,"z":11.986},"rot":{"x":0,"y":269.9999,"z":0}},"5302f2":{"lock":false,"pos":{"x":12.2505,"y":1.4815,"z":-20.0137},"rot":{"x":0,"y":270.0014,"z":0}},"72ab92":{"lock":false,"pos":{"x":12.25,"y":1.4815,"z":19.986},"rot":{"x":0,"y":269.9999,"z":0}},"9e73fa":{"lock":false,"pos":{"x":12.2501,"y":1.4815,"z":-12.0137},"rot":{"x":0,"y":269.9998,"z":0}},"cc7eb3":{"lock":false,"pos":{"x":12.25,"y":1.4815,"z":3.986},"rot":{"x":0,"y":269.9999,"z":0}},"e2dd57":{"lock":false,"pos":{"x":12.25,"y":1.4815,"z":-4.014},"rot":{"x":0,"y":270,"z":0}}}}' MaterialIndex: -1 MeasureMovement: false MeshIndex: -1 diff --git a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model All or Nothing 72ab92.yaml b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model All or Nothing 72ab92.yaml index 59cca5e6f..41798351b 100644 --- a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model All or Nothing 72ab92.yaml +++ b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model All or Nothing 72ab92.yaml @@ -61,8 +61,8 @@ Sticky: true Tooltip: true Transform: posX: 12.25 - posY: 1.47 - posZ: 11.99 + posY: 1.48 + posZ: 19.99 rotX: 0 rotY: 270 rotZ: 0 diff --git a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Bad Blood 451eaa.yaml b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Bad Blood 451eaa.yaml index ba7a1d0c0..21f59416c 100644 --- a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Bad Blood 451eaa.yaml +++ b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Bad Blood 451eaa.yaml @@ -61,8 +61,8 @@ Sticky: true Tooltip: true Transform: posX: 12.25 - posY: 1.47 - posZ: 3.99 + posY: 1.48 + posZ: 11.99 rotX: 0 rotY: 270 rotZ: 0 diff --git a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model By the Book cc7eb3.yaml b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model By the Book cc7eb3.yaml index 9cff9d14e..f9856b8f3 100644 --- a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model By the Book cc7eb3.yaml +++ b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model By the Book cc7eb3.yaml @@ -61,8 +61,8 @@ Sticky: true Tooltip: true Transform: posX: 12.25 - posY: 1.46 - posZ: -4.01 + posY: 1.48 + posZ: 3.99 rotX: 0 rotY: 270 rotZ: 0 diff --git a/unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Aespa Investigators ec74df.ttslua b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Laid to Rest e2dd57.ttslua similarity index 100% rename from unpacked/Custom_Model_Bag Community-Created Player CardsInvestigators ed4ca7/Custom_Model Aespa Investigators ec74df.ttslua rename to unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Laid to Rest e2dd57.ttslua diff --git a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Invisible Man 17d01a.yaml b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Laid to Rest e2dd57.yaml similarity index 76% rename from unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Invisible Man 17d01a.yaml rename to unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Laid to Rest e2dd57.yaml index 1cf3a06ec..a36ff214a 100644 --- a/unpacked/Custom_Model_Bag Fan-Made ScenariosCampaignsMiscellany 66e97c/Custom_Model_Bag Fan-Made Standalone Scenarios 5db60c/Custom_Model The Invisible Man 17d01a.yaml +++ b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Laid to Rest e2dd57.yaml @@ -35,34 +35,34 @@ CustomMesh: r: 1 SpecularIntensity: 0 SpecularSharpness: 2 - DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2005838139148126671/D2A8004B560ED3623F3326F3F97B8B181AEC6371/ + DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2115061845788468343/B7611EC7DCD2008B87D6518EBEFF0AD36EFE5B54/ MaterialIndex: 3 MeshURL: https://raw.githubusercontent.com/RobMayer/TTSLibrary/master/advboxes/tuckbox_h_MSH.obj NormalURL: '' TypeIndex: 0 -Description: '' +Description: Challenge Scenario DragSelectable: true -GMNotes: fancreations/scenario_the_invisible_man.json -GUID: 17d01a +GMNotes: scenarios/challenge_laid_to_rest.json +GUID: e2dd57 Grid: true GridProjection: false -Hands: false +Hands: true HideWhenFaceDown: false IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: false -LuaScript: !include 'Custom_Model The Invisible Man 17d01a.ttslua' +LuaScript: !include 'Custom_Model Laid to Rest e2dd57.ttslua' LuaScriptState: '' MeasureMovement: false Name: Custom_Model -Nickname: The Invisible Man +Nickname: Laid to Rest Snap: true Sticky: true Tooltip: true Transform: - posX: 20 - posY: 1.5 - posZ: 0 + posX: 12.25 + posY: 1.48 + posZ: -4.01 rotX: 0 rotY: 270 rotZ: 0 diff --git a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Read or Die 9e73fa.ttslua b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Read or Die 9e73fa.ttslua index e6f67c6af..3c2a044ca 100644 --- a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Read or Die 9e73fa.ttslua +++ b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Read or Die 9e73fa.ttslua @@ -41,6 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/DownloadBox") +end) __bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) function onLoad() local notes = self.getGMNotes() @@ -84,7 +87,4 @@ function buttonClick_download() Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Read or Die 9e73fa.yaml b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Read or Die 9e73fa.yaml index 3ebd98663..b428cd4e6 100644 --- a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Read or Die 9e73fa.yaml +++ b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Read or Die 9e73fa.yaml @@ -61,7 +61,7 @@ Sticky: true Tooltip: true Transform: posX: 12.25 - posY: 1.46 + posY: 1.48 posZ: -12.01 rotX: 0 rotY: 270 diff --git a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Red Tide Rising 5302f2.yaml b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Red Tide Rising 5302f2.yaml index f52ac90c5..cff363110 100644 --- a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Red Tide Rising 5302f2.yaml +++ b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Challenge Scenarios 9f6801/Custom_Model Red Tide Rising 5302f2.yaml @@ -61,7 +61,7 @@ Sticky: true Tooltip: true Transform: posX: 12.25 - posY: 1.46 + posY: 1.48 posZ: -20.01 rotX: 0 rotY: 270 diff --git a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Standalone Scenarios 77a5f9/Custom_Model Fortune and Folly 0dce91.ttslua b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Standalone Scenarios 77a5f9/Custom_Model Fortune and Folly 0dce91.ttslua index e6f67c6af..3c2a044ca 100644 --- a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Standalone Scenarios 77a5f9/Custom_Model Fortune and Folly 0dce91.ttslua +++ b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Standalone Scenarios 77a5f9/Custom_Model Fortune and Folly 0dce91.ttslua @@ -41,6 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/DownloadBox") +end) __bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) function onLoad() local notes = self.getGMNotes() @@ -84,7 +87,4 @@ function buttonClick_download() Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Standalone Scenarios 77a5f9/Custom_Model The Labyrinths of Lunacy 4c173f.ttslua b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Standalone Scenarios 77a5f9/Custom_Model The Labyrinths of Lunacy 4c173f.ttslua index e6f67c6af..3c2a044ca 100644 --- a/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Standalone Scenarios 77a5f9/Custom_Model The Labyrinths of Lunacy 4c173f.ttslua +++ b/unpacked/Custom_Model_Bag Official StandaloneChallenge Scenarios 0ef5c8/Custom_Model_Bag Standalone Scenarios 77a5f9/Custom_Model The Labyrinths of Lunacy 4c173f.ttslua @@ -41,6 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/DownloadBox") +end) __bundle_register("core/DownloadBox", function(require, _LOADED, __bundle_register, __bundle_modules) function onLoad() local notes = self.getGMNotes() @@ -84,7 +87,4 @@ function buttonClick_download() Global.call('placeholder_download', { url = self.getGMNotes(), replace = self.guid }) end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/DownloadBox") -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Model_Bag Trash 147e80.yaml b/unpacked/Custom_Model_Bag Trash 147e80.yaml index ed0cf23f1..035bc9d4b 100644 --- a/unpacked/Custom_Model_Bag Trash 147e80.yaml +++ b/unpacked/Custom_Model_Bag Trash 147e80.yaml @@ -6,16 +6,16 @@ Autoraise: true Bag: Order: 0 ColorDiffuse: - b: 0.99796 - g: 0.99623 + b: 1 + g: 1 r: 1 CustomMesh: CastShadows: true ColliderURL: '' Convex: true - DiffuseURL: '' + DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2172484009093064421/956617F74D651E2B2CD1F7E7EC6B34C3A30617B2/ MaterialIndex: 0 - MeshURL: http://cloud-3.steamusercontent.com/ugc/1293045649230453355/2F68BC7FA71E051E2BBA46C0D1B06A5972D52E7C/ + MeshURL: http://cloud-3.steamusercontent.com/ugc/2172484009093064278/BFF258FC90A0E56581C5C302752CF67C4947A540/ NormalURL: '' TypeIndex: 6 Description: '' @@ -42,13 +42,13 @@ Sticky: true Tooltip: true Transform: posX: -47.73 - posY: 1.62 + posY: 1.55 posZ: 4 rotX: 0 - rotY: 0 + rotY: 270 rotZ: 0 - scaleX: 0.3 - scaleY: 0.3 - scaleZ: 0.3 + scaleX: 0.75 + scaleY: 1 + scaleZ: 0.75 Value: 0 XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Trash 4b8594.yaml b/unpacked/Custom_Model_Bag Trash 4b8594.yaml index 980603225..23eccb938 100644 --- a/unpacked/Custom_Model_Bag Trash 4b8594.yaml +++ b/unpacked/Custom_Model_Bag Trash 4b8594.yaml @@ -6,16 +6,16 @@ Autoraise: true Bag: Order: 0 ColorDiffuse: - b: 0.99796 - g: 0.99623 + b: 1 + g: 1 r: 1 CustomMesh: CastShadows: true ColliderURL: '' Convex: true - DiffuseURL: '' + DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2172484009093064421/956617F74D651E2B2CD1F7E7EC6B34C3A30617B2/ MaterialIndex: 0 - MeshURL: http://cloud-3.steamusercontent.com/ugc/1293045649230453355/2F68BC7FA71E051E2BBA46C0D1B06A5972D52E7C/ + MeshURL: http://cloud-3.steamusercontent.com/ugc/2172484009093064278/BFF258FC90A0E56581C5C302752CF67C4947A540/ NormalURL: '' TypeIndex: 6 Description: '' @@ -42,13 +42,13 @@ Sticky: true Tooltip: true Transform: posX: -42.25 - posY: 1.65 + posY: 1.55 posZ: -19.3 rotX: 0 - rotY: 0 + rotY: 180 rotZ: 0 - scaleX: 0.3 - scaleY: 0.3 - scaleZ: 0.3 + scaleX: 0.75 + scaleY: 1 + scaleZ: 0.75 Value: 0 XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Trash 5f896a.yaml b/unpacked/Custom_Model_Bag Trash 5f896a.yaml index 7a37af152..046de63c4 100644 --- a/unpacked/Custom_Model_Bag Trash 5f896a.yaml +++ b/unpacked/Custom_Model_Bag Trash 5f896a.yaml @@ -6,16 +6,16 @@ Autoraise: true Bag: Order: 0 ColorDiffuse: - b: 0.99796 - g: 0.99623 + b: 1 + g: 1 r: 1 CustomMesh: CastShadows: true ColliderURL: '' Convex: true - DiffuseURL: '' + DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2172484009093064421/956617F74D651E2B2CD1F7E7EC6B34C3A30617B2/ MaterialIndex: 0 - MeshURL: http://cloud-3.steamusercontent.com/ugc/1293045649230453355/2F68BC7FA71E051E2BBA46C0D1B06A5972D52E7C/ + MeshURL: http://cloud-3.steamusercontent.com/ugc/2172484009093064278/BFF258FC90A0E56581C5C302752CF67C4947A540/ NormalURL: '' TypeIndex: 6 Description: '' @@ -42,13 +42,13 @@ Sticky: true Tooltip: true Transform: posX: -42.25 - posY: 1.66 + posY: 1.55 posZ: 19.3 rotX: 0 rotY: 0 rotZ: 0 - scaleX: 0.3 - scaleY: 0.3 - scaleZ: 0.3 + scaleX: 0.75 + scaleY: 1 + scaleZ: 0.75 Value: 0 XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Trash 70b9f6.yaml b/unpacked/Custom_Model_Bag Trash 70b9f6.yaml index ab036de51..44d59c9eb 100644 --- a/unpacked/Custom_Model_Bag Trash 70b9f6.yaml +++ b/unpacked/Custom_Model_Bag Trash 70b9f6.yaml @@ -6,16 +6,16 @@ Autoraise: true Bag: Order: 0 ColorDiffuse: - b: 0.99796 - g: 0.99623 + b: 1 + g: 1 r: 1 CustomMesh: CastShadows: true ColliderURL: '' Convex: true - DiffuseURL: '' + DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2172484009093064421/956617F74D651E2B2CD1F7E7EC6B34C3A30617B2/ MaterialIndex: 0 - MeshURL: http://cloud-3.steamusercontent.com/ugc/1293045649230453355/2F68BC7FA71E051E2BBA46C0D1B06A5972D52E7C/ + MeshURL: http://cloud-3.steamusercontent.com/ugc/2172484009093064278/BFF258FC90A0E56581C5C302752CF67C4947A540/ NormalURL: '' TypeIndex: 6 Description: '' @@ -42,13 +42,13 @@ Sticky: true Tooltip: true Transform: posX: 0.49 - posY: 1.66 + posY: 1.55 posZ: 0 rotX: 0 - rotY: 0 + rotY: 270 rotZ: 0 - scaleX: 0.4 - scaleY: 0.3 - scaleZ: 0.4 + scaleX: 0.75 + scaleY: 1 + scaleZ: 0.75 Value: 0 XmlUI: '' diff --git a/unpacked/Custom_Model_Bag Trash f7b6c8.yaml b/unpacked/Custom_Model_Bag Trash f7b6c8.yaml index e6f50241c..a00fe6928 100644 --- a/unpacked/Custom_Model_Bag Trash f7b6c8.yaml +++ b/unpacked/Custom_Model_Bag Trash f7b6c8.yaml @@ -6,16 +6,16 @@ Autoraise: true Bag: Order: 0 ColorDiffuse: - b: 0.99796 - g: 0.99623 + b: 1 + g: 1 r: 1 CustomMesh: CastShadows: true ColliderURL: '' Convex: true - DiffuseURL: '' + DiffuseURL: http://cloud-3.steamusercontent.com/ugc/2172484009093064421/956617F74D651E2B2CD1F7E7EC6B34C3A30617B2/ MaterialIndex: 0 - MeshURL: http://cloud-3.steamusercontent.com/ugc/1293045649230453355/2F68BC7FA71E051E2BBA46C0D1B06A5972D52E7C/ + MeshURL: http://cloud-3.steamusercontent.com/ugc/2172484009093064278/BFF258FC90A0E56581C5C302752CF67C4947A540/ NormalURL: '' TypeIndex: 6 Description: '' @@ -42,13 +42,13 @@ Sticky: true Tooltip: true Transform: posX: -47.73 - posY: 1.62 + posY: 1.55 posZ: -4 rotX: 0 - rotY: 0 + rotY: 270 rotZ: 0 - scaleX: 0.3 - scaleY: 0.3 - scaleZ: 0.3 + scaleX: 0.75 + scaleY: 1 + scaleZ: 0.75 Value: 0 XmlUI: '' diff --git a/unpacked/Custom_Model_Infinite_Bag Clue tokens 11e0cf.yaml b/unpacked/Custom_Model_Infinite_Bag Clue tokens 11e0cf.yaml index d1101b29a..84c141d10 100644 --- a/unpacked/Custom_Model_Infinite_Bag Clue tokens 11e0cf.yaml +++ b/unpacked/Custom_Model_Infinite_Bag Clue tokens 11e0cf.yaml @@ -88,6 +88,8 @@ Name: Custom_Model_Infinite_Bag Nickname: Clue tokens Snap: true Sticky: true +Tags: +- CleanUpHelper_ignore Tooltip: true Transform: posX: 2.86 diff --git a/unpacked/Custom_Model_Infinite_Bag Connection markers 170f10.yaml b/unpacked/Custom_Model_Infinite_Bag Connection markers 170f10.yaml index b47b022b1..390379af7 100644 --- a/unpacked/Custom_Model_Infinite_Bag Connection markers 170f10.yaml +++ b/unpacked/Custom_Model_Infinite_Bag Connection markers 170f10.yaml @@ -197,6 +197,8 @@ Name: Custom_Model_Infinite_Bag Nickname: Connection markers Snap: true Sticky: true +Tags: +- CleanUpHelper_ignore Tooltip: true Transform: posX: -51 diff --git a/unpacked/Custom_Model_Infinite_Bag Doom tokens 47ffc3.yaml b/unpacked/Custom_Model_Infinite_Bag Doom tokens 47ffc3.yaml index 487276e8a..cb572727b 100644 --- a/unpacked/Custom_Model_Infinite_Bag Doom tokens 47ffc3.yaml +++ b/unpacked/Custom_Model_Infinite_Bag Doom tokens 47ffc3.yaml @@ -88,6 +88,8 @@ Name: Custom_Model_Infinite_Bag Nickname: Doom tokens Snap: true Sticky: true +Tags: +- CleanUpHelper_ignore Tooltip: true Transform: posX: -55.48 diff --git a/unpacked/Custom_Model_Infinite_Bag Doom tokens b015d8.yaml b/unpacked/Custom_Model_Infinite_Bag Doom tokens b015d8.yaml index b7cf32363..e86042049 100644 --- a/unpacked/Custom_Model_Infinite_Bag Doom tokens b015d8.yaml +++ b/unpacked/Custom_Model_Infinite_Bag Doom tokens b015d8.yaml @@ -88,6 +88,8 @@ Name: Custom_Model_Infinite_Bag Nickname: Doom tokens Snap: true Sticky: true +Tags: +- CleanUpHelper_ignore Tooltip: true Transform: posX: 2.76 diff --git a/unpacked/Custom_PDF Rules Reference d99993.yaml b/unpacked/Custom_PDF Rules Reference d99993.yaml index 820ea0b16..e089e8a3a 100644 --- a/unpacked/Custom_PDF Rules Reference d99993.yaml +++ b/unpacked/Custom_PDF Rules Reference d99993.yaml @@ -11,7 +11,7 @@ CustomPDF: PDFPage: 0 PDFPageOffset: 0 PDFPassword: '' - PDFUrl: https://images-cdn.fantasyflightgames.com/filer_public/c4/b0/c4b0d66c-d79e-411b-bdb5-b5d8c457d4bc/ahc01_rules_reference_web.pdf + PDFUrl: http://cloud-3.steamusercontent.com/ugc/2115061845793806189/6FC67F9AF9224452E2D8F25E63B88D702B21B0DC/ Description: '' DragSelectable: true GMNotes: '' diff --git a/unpacked/Custom_Tile ArkhamDB Deck Importer a28140.ttslua b/unpacked/Custom_Tile ArkhamDB Deck Importer a28140.ttslua index 1c510f16c..1e6b0143e 100644 --- a/unpacked/Custom_Tile ArkhamDB Deck Importer a28140.ttslua +++ b/unpacked/Custom_Tile ArkhamDB Deck Importer a28140.ttslua @@ -44,6 +44,769 @@ end)(nil) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("arkhamdb/DeckImporterMain") end) +__bundle_register("arkhamdb/DeckImporterMain", function(require, _LOADED, __bundle_register, __bundle_modules) +require("arkhamdb/DeckImporterUi") +require("playercards/PlayerCardSpawner") + +local allCardsBagApi = require("playercards/AllCardsBagApi") +local arkhamDb = require("arkhamdb/ArkhamDb") +local playAreaApi = require("core/PlayAreaApi") +local playmatApi = require("playermat/PlaymatApi") +local zones = require("playermat/Zones") + +function onLoad(script_state) + initializeUi(JSON.decode(script_state)) + math.randomseed(os.time()) + arkhamDb.initialize() +end + +function onSave() return JSON.encode(getUiState()) end + +-- Returns the zone name where the specified card should be placed, based on its metadata. +---@param cardMetadata Table of card metadata. +---@return Zone String Name of the zone such as "Deck", "SetAside1", etc. +-- See Zones object documentation for a list of valid zones. +function getDefaultCardZone(cardMetadata, bondedList) + if (cardMetadata.id == "09080-m") then -- Have to check the Servitor before other minicards + return "SetAside6" + elseif (cardMetadata.id == "09006") then -- On The Mend is set aside + return "SetAside2" + elseif cardMetadata.type == "Investigator" then + return "Investigator" + elseif cardMetadata.type == "Minicard" then + return "Minicard" + elseif cardMetadata.type == "UpgradeSheet" then + return "SetAside4" + elseif cardMetadata.startsInPlay then + return "BlankTop" + elseif cardMetadata.permanent then + return "SetAside1" + elseif bondedList[cardMetadata.id] then + return "SetAside2" + -- SetAside3 is used for Ancestral Knowledge / Underworld Market + else + return "Deck" + end +end + +function buildDeck(playerColor, deckId) + local uiState = getUiState() + arkhamDb.getDecklist( + playerColor, + deckId, + uiState.private, + uiState.loadNewest, + uiState.investigators, + loadCards) +end + +-- Process the slot list, which defines the card Ids and counts of cards to load. Spawn those cards +-- at the appropriate zones and report an error to the user if any could not be loaded. +-- This is a callback function which handles the results of ArkhamDb.getDecklist() +-- This method uses an encapsulated coroutine with yields to make the card spawning cleaner. +-- +---@param slots Table Key-Value table of cardId:count. cardId is the ArkhamDB ID of the card to spawn, +-- and count is the number which should be spawned +---@param investigatorId String ArkhamDB ID (code) for this deck's investigator. +-- Investigator cards should already be added to the slots list if they +-- should be spawned, but this value is separate to check for special +-- handling for certain investigators +---@param bondedList Table A table of cardID keys to meaningless values. Card IDs in this list were added +-- from a parent bonded card. +---@param customizations String ArkhamDB data for customizations on customizable cards +---@param playerColor String Color name of the player mat to place this deck on (e.g. "Red") +---@param loadAltInvestigator String Contains the name of alternative art for the investigator ("normal", "revised" or "promo") +function loadCards(slots, investigatorId, bondedList, customizations, playerColor, loadAltInvestigator) + function coinside() + local yPos = {} + local cardsToSpawn = {} + for cardId, cardCount in pairs(slots) do + local card = allCardsBagApi.getCardById(cardId) + if card ~= nil then + local cardZone = getDefaultCardZone(card.metadata, bondedList) + for i = 1, cardCount do + table.insert(cardsToSpawn, { data = card.data, metadata = card.metadata, zone = cardZone }) + end + + slots[cardId] = 0 + end + end + + handleAncestralKnowledge(cardsToSpawn) + handleUnderworldMarket(cardsToSpawn, playerColor) + handleHunchDeck(investigatorId, cardsToSpawn, playerColor) + handleSpiritDeck(investigatorId, cardsToSpawn, playerColor) + handleCustomizableUpgrades(cardsToSpawn, customizations) + handlePeteSignatureAssets(investigatorId, cardsToSpawn) + + -- Split the card list into separate lists for each zone + local zoneDecks = buildZoneLists(cardsToSpawn) + -- Spawn the list for each zone + for zone, zoneCards in pairs(zoneDecks) do + local deckPos = zones.getZonePosition(playerColor, zone) + deckPos.y = 3 + + local callback = nil + -- If cards are spread too close together TTS groups them weirdly, selecting multiples + -- when hovering over a single card. This distance is the minimum to avoid that + local spreadDistance = 1.15 + if (zone == "SetAside4") then + -- SetAside4 is reserved for customization cards, and we want them spread on the table + -- so their checkboxes are visible + -- TO-DO: take into account that spreading will make multiple rows + -- (this is affected by the user's local settings!) + if (playerColor == "White") then + deckPos.z = deckPos.z + (#zoneCards - 1) * spreadDistance + elseif (playerColor == "Green") then + deckPos.x = deckPos.x + (#zoneCards - 1) * spreadDistance + end + callback = function(deck) deck.spread(spreadDistance) end + elseif zone == "Deck" then + callback = function(deck) deckSpawned(deck, playerColor) end + elseif zone == "Investigator" or zone == "Minicard" then + callback = function(card) loadAltArt(card, loadAltInvestigator) end + end + Spawner.spawnCards( + zoneCards, + deckPos, + zones.getDefaultCardRotation(playerColor, zone), + true, -- Sort deck + callback) + + coroutine.yield(0) + end + + -- Look for any cards which haven't been loaded + local hadError = false + for cardId, remainingCount in pairs(slots) do + if remainingCount > 0 then + hadError = true + arkhamDb.logCardNotFound(cardId, playerColor) + end + end + if (not hadError) then + printToAll("Deck loaded successfully!", playerColor) + end + return 1 + end + + startLuaCoroutine(self, "coinside") +end + +-- Callback handler for the main deck spawning. Looks for cards which should start in hand, and +-- draws them for the appropriate player. +---@param deck Object Callback-provided spawned deck object +---@param playerColor String Color of the player to draw the cards to +function deckSpawned(deck, playerColor) + local player = Player[playmatApi.getPlayerColor(playerColor)] + local handPos = player.getHandTransform(1).position -- Only one hand zone per player + local deckCards = deck.getData().ContainedObjects + -- Process in reverse order so taking cards out doesn't upset the indexing + for i = #deckCards, 1, -1 do + local cardMetadata = JSON.decode(deckCards[i].GMNotes) or { } + if cardMetadata.startsInHand then + deck.takeObject({ index = i - 1, position = handPos, flip = true, smooth = true}) + end + end +end + +-- Converts the Raven Quill's selections from card IDs to card names. This could be more elegant +-- but the inputs are very static so we're using some brute force. +---@param selectionString String provided by ArkhamDB, indicates the customization selections +-- Should be either a single card ID or two separated by a ^ (e.g. XXXXX^YYYYY) +function convertRavenQuillSelections(selectionString) + if (string.len(selectionString) == 5) then + return getCardName(selectionString) + elseif (string.len(selectionString) == 11) then + return getCardName(string.sub(selectionString, 1, 5)) .. ", " .. getCardName(string.sub(selectionString, 7)) + end +end + +-- Converts Grizzled's selections from a single string with "^". +---@param selectionString String provided by ArkhamDB, indicates the customization selections +-- Should be two Traits separated by a ^ (e.g. XXXXX^YYYYY) +function convertGrizzledSelections(selectionString) + return selectionString:gsub("%^", ", ") +end + +-- Returns the simple name of a card given its ID. This will find the card and strip any trailing +-- SCED-specific suffixes such as (Taboo) or (Level) +function getCardName(cardId) + local card = allCardsBagApi.getCardById(cardId) + if (card ~= nil) then + local name = card.data.Nickname + if (string.find(name, " %(")) then + return string.sub(name, 1, string.find(name, " %(") - 1) + else + return name + end + end +end + +-- Split a single list of cards into a separate table of lists, keyed by the zone +---@param cards: Table of {cardData, cardMetadata, zone} +---@return: Table of {zoneName=card list} +function buildZoneLists(cards) + local zoneList = {} + for _, card in ipairs(cards) do + if zoneList[card.zone] == nil then + zoneList[card.zone] = {} + end + table.insert(zoneList[card.zone], card) + end + + return zoneList +end + +-- Check to see if the deck list has Ancestral Knowledge. If it does, move 5 random skills to SetAside3 +---@param cardList Table Deck list being created +function handleAncestralKnowledge(cardList) + local hasAncestralKnowledge = false + local skillList = {} + -- Have to process the entire list to check for Ancestral Knowledge and get all possible skills, so do both in one pass + for i, card in ipairs(cardList) do + if card.metadata.id == "07303" then + hasAncestralKnowledge = true + card.zone = "SetAside3" + elseif (card.metadata.type == "Skill" + and card.zone == "Deck" + and not card.metadata.weakness) then + table.insert(skillList, i) + end + end + if hasAncestralKnowledge then + for i = 1, 5 do + -- Move 5 random skills to SetAside3 + local skillListIndex = math.random(#skillList) + cardList[skillList[skillListIndex]].zone = "UnderSetAside3" + table.remove(skillList, skillListIndex) + end + end +end + +-- Check for and handle Underworld Market by moving all Illicit cards to UnderSetAside3 +---@param cardList Table Deck list being created +---@param playerColor String Color this deck is being loaded for +function handleUnderworldMarket(cardList, playerColor) + local hasMarket = false + local illicitList = {} + -- Process the entire list to check for Underworld Market and get all possible skills, doing both in one pass + for i, card in ipairs(cardList) do + if card.metadata.id == "09077" then + -- Underworld Market found + hasMarket = true + card.zone = "SetAside3" + elseif card.metadata.traits ~= nil and string.find(card.metadata.traits, "Illicit", 1, true) and card.zone == "Deck" then + table.insert(illicitList, i) + end + end + + if hasMarket then + if #illicitList < 10 then + printToAll("Only " .. #illicitList .. + " Illicit cards in your deck, you can't trigger Underworld Market's ability.", + playerColor) + else + -- Process cards to move them to the market deck. This is done in reverse + -- order because the sorting needs to be reversed (deck sorts for face down) + -- Performance here may be an issue, as table.remove() is an O(n) operation + -- which makes the full shift O(n^2). But keep it simple unless it becomes + -- a problem + for i = #illicitList, 1, -1 do + local moving = cardList[illicitList[i]] + moving.zone = "UnderSetAside3" + table.remove(cardList, illicitList[i]) + table.insert(cardList, moving) + end + + if #illicitList > 10 then + printToAll("Moved all " .. #illicitList .. + " Illicit cards to the Market deck, reduce it to 10", + playerColor) + else + printToAll("Built the Market deck", playerColor) + end + end + end +end + +-- If the investigator is Joe Diamond, extract all Insight events to SetAside5 to build the Hunch +-- Deck. +---@param investigatorId String ID for the deck's investigator card. Passed separately because the +--- investigator may not be included in the cardList +---@param cardList Table Deck list being created +---@param playerColor String Color this deck is being loaded for +function handleHunchDeck(investigatorId, cardList, playerColor) + if investigatorId == "05002" then -- Joe Diamond + local insightList = {} + for i, card in ipairs(cardList) do + if (card.metadata.type == "Event" + and card.metadata.traits ~= nil + and string.match(card.metadata.traits, "Insight") + and card.metadata.bonded_to == nil) then + table.insert(insightList, i) + end + end + -- Process insights to move them to the hunch deck. This is done in reverse + -- order because the sorting needs to be reversed (deck sorts for face down) + -- Performance here may be an issue, as table.remove() is an O(n) operation + -- which makes the full shift O(n^2). But keep it simple unless it becomes + -- a problem + for i = #insightList, 1, -1 do + local moving = cardList[insightList[i]] + moving.zone = "SetAside5" + table.remove(cardList, insightList[i]) + table.insert(cardList, moving) + end + if #insightList < 11 then + printToAll("Joe's hunch deck must have 11 cards but the deck only has " .. #insightList .. + " Insight events.", playerColor) + elseif #insightList > 11 then + printToAll("Moved all " .. #insightList .. + " Insight events to the hunch deck, reduce it to 11.", playerColor) + else + printToAll("Built Joe's hunch deck", playerColor) + end + end +end + +-- If the investigator is Parallel Jim Culver, extract all Ally assets to SetAside5 to build the Spirit +-- Deck. +---@param investigatorId String ID for the deck's investigator card. Passed separately because the +--- investigator may not be included in the cardList +---@param cardList Table Deck list being created +---@param playerColor String Color this deck is being loaded for +function handleSpiritDeck(investigatorId, cardList, playerColor) + if investigatorId == "02004-p" or investigatorId == "02004-pb" then -- Parallel Jim Culver + local spiritList = {} + for i, card in ipairs(cardList) do + if card.metadata.id == "90053" or ( + card.metadata.type == "Asset" + and card.metadata.traits ~= nil + and string.match(card.metadata.traits, "Ally") + and card.metadata.level ~= nil + and card.metadata.level < 3) then + table.insert(spiritList, i) + end + end + -- Process allies to move them to the spirit deck. This is done in reverse + -- order because the sorting needs to be reversed (deck sorts for face down) + -- Performance here may be an issue, as table.remove() is an O(n) operation + -- which makes the full shift O(n^2). But keep it simple unless it becomes + -- a problem + for i = #spiritList, 1, -1 do + local moving = cardList[spiritList[i]] + moving.zone = "SetAside5" + table.remove(cardList, spiritList[i]) + table.insert(cardList, moving) + end + if #spiritList < 10 then + printToAll("Jim's spirit deck must have 9 Ally assets but the deck only has " .. (#spiritList - 1) .. + " Ally assets.", playerColor) + elseif #spiritList > 11 then + printToAll("Moved all " .. (#spiritList - 1) .. + " Ally assets to the spirit deck, reduce it to 10 (including Vengeful Shade).", playerColor) + else + printToAll("Built Jim's spirit deck", playerColor) + end + end +end + +-- For any customization upgrade cards in the card list, process the metadata from the deck to +-- set the save state to show the correct checkboxes/text field values +---@param cardList Table Deck list being created +---@param customizations Table Deck's meta table, extracted from ArkhamDB's deck structure +function handleCustomizableUpgrades(cardList, customizations) + for _, card in ipairs(cardList) do + if card.metadata.type == "UpgradeSheet" then + local baseId = string.sub(card.metadata.id, 1, 5) + local upgrades = customizations["cus_" .. baseId] + + if upgrades ~= nil then + -- initialize tables + -- markedBoxes: contains the amount of markedBoxes (left to right) per row (starting at row 1) + -- inputValues: contains the amount of inputValues per row (starting at row 0) + local selectedUpgrades = { } + local index_xp = {} + + -- get the index and xp values (looks like this: X|X,X|X, ..) + -- input string from ArkhamDB is split by "," + for str in string.gmatch(customizations["cus_" .. baseId], "([^,]+)") do + table.insert(index_xp, str) + end + + -- split each pair and assign it to the proper position in markedBoxes + for _, entry in ipairs(index_xp) do + -- counter increments from 1 to 3 and indicates the part of the string we are on + -- usually: 1 = row, 2 = amount of check boxes, 3 = entry in inputfield + local counter = 0 + local row = 0 + + -- parsing the string for each row + for str in entry:gmatch("([^|]+)") do + counter = counter + 1 + + if counter == 1 then + row = tonumber(str) + 1 + elseif counter == 2 then + if selectedUpgrades[row] == nil then + selectedUpgrades[row] = { } + end + selectedUpgrades[row].xp = tonumber(str) + elseif counter == 3 and str ~= "" then + if baseId == "09042" then + selectedUpgrades[row].text = convertRavenQuillSelections(str) + elseif baseId == "09101" then + selectedUpgrades[row].text = convertGrizzledSelections(str) + elseif baseId == "09079" then -- Living Ink skill selection + -- All skills, regardless of row, are placed in upgrade slot 1 as a comma-delimited + -- list + if selectedUpgrades[1].text == nil then + selectedUpgrades[1].text = str + else + selectedUpgrades[1].text = selectedUpgrades[1].text .. "," .. str + end + else + selectedUpgrades[row].text = str + end + end + end + end + + -- write the loaded values to the save_data of the sheets + card.data["LuaScriptState"] = JSON.encode({ selections = selectedUpgrades }) + end + end + end +end + +-- Handles cards that start in play under specific conditions for Ashcan Pete (Regular Pete - Duke, Parallel Pete - Guitar) +---@param investigatorId String ID for the deck's investigator card. Passed separately because the +--- investigator may not be included in the cardList +---@param cardList Table Deck list being created +function handlePeteSignatureAssets(investigatorId, cardList) + if investigatorId == "02005" or investigatorId == "02005-pb" then -- regular Pete's front + for i, card in ipairs(cardList) do + if card.metadata.id == "02014" then -- Duke + card.zone = "BlankTop" + end + end + elseif investigatorId == "02005-p" or investigatorId == "02005-pf" then -- parallel Pete's front + for i, card in ipairs(cardList) do + if card.metadata.id == "90047" then -- Pete's Guitar + card.zone = "BlankTop" + end + end + end +end + +-- Callback function for investigator cards and minicards to set the correct state for alt art +---@param card Object Card which needs to be set the state for +---@param loadAltInvestigator String Contains the name of alternative art for the investigator ("normal", "revised" or "promo") +function loadAltArt(card, loadAltInvestigator) + -- states are set up this way: + -- 1 - normal, 2 - revised/promo, 3 - promo (if 2 is revised) + -- This means we can always load the 2nd state for revised and just get the last state for promo + if loadAltInvestigator == "normal" then + return + elseif loadAltInvestigator == "revised" then + card.setState(2) + elseif loadAltInvestigator == "promo" then + local states = card.getStates() + card.setState(#states) + end +end +end) +__bundle_register("arkhamdb/DeckImporterUi", function(require, _LOADED, __bundle_register, __bundle_modules) +local allCardsBagApi = require("playercards/AllCardsBagApi") + +local INPUT_FIELD_HEIGHT = 340 +local INPUT_FIELD_WIDTH = 1500 +local FIELD_COLOR = { 0.9, 0.7, 0.5 } + +local PRIVATE_TOGGLE_LABELS = {} +PRIVATE_TOGGLE_LABELS[true] = "Private" +PRIVATE_TOGGLE_LABELS[false] = "Published" + +local UPGRADED_TOGGLE_LABELS = {} +UPGRADED_TOGGLE_LABELS[true] = "Upgraded" +UPGRADED_TOGGLE_LABELS[false] = "Specific" + +local LOAD_INVESTIGATOR_TOGGLE_LABELS = {} +LOAD_INVESTIGATOR_TOGGLE_LABELS[true] = "Yes" +LOAD_INVESTIGATOR_TOGGLE_LABELS[false] = "No" + +local redDeckId = "" +local orangeDeckId = "" +local whiteDeckId = "" +local greenDeckId = "" + +local privateDeck = true +local loadNewestDeck = true +local loadInvestigators = false + +-- Returns a table with the full state of the UI, including options and deck IDs. +-- This can be used to persist via onSave(), or provide values for a load operation +-- Table values: +-- redDeck: Deck ID to load for the red player +-- orangeDeck: Deck ID to load for the orange player +-- whiteDeck: Deck ID to load for the white player +-- greenDeck: Deck ID to load for the green player +-- private: True to load a private deck, false to load a public deck +-- loadNewest: True if the most upgraded version of the deck should be loaded +-- investigators: True if investigator cards should be spawned +function getUiState() + return { + redDeck = redDeckId, + orangeDeck = orangeDeckId, + whiteDeck = whiteDeckId, + greenDeck = greenDeckId, + private = privateDeck, + loadNewest = loadNewestDeck, + investigators = loadInvestigators + } +end + +-- Updates the state of the UI based on the provided table. Any values not provided will be left the same. +---@param uiStateTable Table of values to update on importer +-- Table values: +-- redDeck: Deck ID to load for the red player +-- orangeDeck: Deck ID to load for the orange player +-- whiteDeck: Deck ID to load for the white player +-- greenDeck: Deck ID to load for the green player +-- private: True to load a private deck, false to load a public deck +-- loadNewest: True if the most upgraded version of the deck should be loaded +-- investigators: True if investigator cards should be spawned +function setUiState(uiStateTable) + self.clearButtons() + self.clearInputs() + initializeUi(uiStateTable) +end + +-- Sets up the UI for the deck loader, populating fields from the given save state table decoded from onLoad() +function initializeUi(savedUiState) + if savedUiState ~= nil then + redDeckId = savedUiState.redDeck + orangeDeckId = savedUiState.orangeDeck + whiteDeckId = savedUiState.whiteDeck + greenDeckId = savedUiState.greenDeck + privateDeck = savedUiState.private + loadNewestDeck = savedUiState.loadNewest + loadInvestigators = savedUiState.investigators + end + + makeOptionToggles() + makeDeckIdFields() + makeBuildButton() +end + +function makeOptionToggles() + -- common parameters + local checkbox_parameters = {} + checkbox_parameters.function_owner = self + checkbox_parameters.width = INPUT_FIELD_WIDTH + checkbox_parameters.height = INPUT_FIELD_HEIGHT + checkbox_parameters.scale = { 0.1, 0.1, 0.1 } + checkbox_parameters.font_size = 240 + checkbox_parameters.hover_color = { 0.4, 0.6, 0.8 } + checkbox_parameters.color = FIELD_COLOR + + -- public / private deck + checkbox_parameters.click_function = "publicPrivateChanged" + checkbox_parameters.position = { 0.25, 0.1, -0.102 } + checkbox_parameters.tooltip = "Published or private deck?\n\nPLEASE USE A PRIVATE DECK IF JUST FOR TTS TO AVOID FLOODING ARKHAMDB PUBLISHED DECK LISTS!" + checkbox_parameters.label = PRIVATE_TOGGLE_LABELS[privateDeck] + self.createButton(checkbox_parameters) + + -- load upgraded? + checkbox_parameters.click_function = "loadUpgradedChanged" + checkbox_parameters.position = { 0.25, 0.1, -0.01 } + checkbox_parameters.tooltip = "Load newest upgrade or exact deck?" + checkbox_parameters.label = UPGRADED_TOGGLE_LABELS[loadNewestDeck] + self.createButton(checkbox_parameters) + + -- load investigators? + checkbox_parameters.click_function = "loadInvestigatorsChanged" + checkbox_parameters.position = { 0.25, 0.1, 0.081 } + checkbox_parameters.tooltip = "Spawn investigator cards?" + checkbox_parameters.label = LOAD_INVESTIGATOR_TOGGLE_LABELS[loadInvestigators] + self.createButton(checkbox_parameters) +end + +-- Create the four deck ID entry fields +function makeDeckIdFields() + local input_parameters = {} + -- Parameters common to all entry fields + input_parameters.function_owner = self + input_parameters.scale = { 0.1, 0.1, 0.1 } + input_parameters.width = INPUT_FIELD_WIDTH + input_parameters.height = INPUT_FIELD_HEIGHT + input_parameters.font_size = 320 + input_parameters.tooltip = "Deck ID from ArkhamDB URL of the deck\nPublic URL: 'https://arkhamdb.com/decklist/view/101/knowledge-overwhelming-solo-deck-1.0' = '101'\nPrivate URL: 'https://arkhamdb.com/deck/view/102' = '102'" + input_parameters.alignment = 3 -- Center + input_parameters.color = FIELD_COLOR + input_parameters.font_color = { 0, 0, 0 } + input_parameters.validation = 2 -- Integer + + -- Green + input_parameters.input_function = "greenDeckChanged" + input_parameters.position = { -0.166, 0.1, 0.385 } + input_parameters.value = greenDeckId + self.createInput(input_parameters) + -- Red + input_parameters.input_function = "redDeckChanged" + input_parameters.position = { 0.171, 0.1, 0.385 } + input_parameters.value = redDeckId + self.createInput(input_parameters) + -- White + input_parameters.input_function = "whiteDeckChanged" + input_parameters.position = { -0.166, 0.1, 0.474 } + input_parameters.value = whiteDeckId + self.createInput(input_parameters) + -- Orange + input_parameters.input_function = "orangeDeckChanged" + input_parameters.position = { 0.171, 0.1, 0.474 } + input_parameters.value = orangeDeckId + self.createInput(input_parameters) +end + +-- Create the Build All button. This is a transparent button which covers the Build All portion of the background graphic +function makeBuildButton() + local button_parameters = {} + button_parameters.click_function = "loadDecks" + button_parameters.function_owner = self + button_parameters.position = { 0, 0.1, 0.71 } + button_parameters.width = 320 + button_parameters.height = 30 + button_parameters.color = { 0, 0, 0, 0 } + button_parameters.tooltip = "Click to build all four decks!" + self.createButton(button_parameters) +end + +-- Event handlers for deck ID change +function redDeckChanged(_, _, inputValue) redDeckId = inputValue end + +function orangeDeckChanged(_, _, inputValue) orangeDeckId = inputValue end + +function whiteDeckChanged(_, _, inputValue) whiteDeckId = inputValue end + +function greenDeckChanged(_, _, inputValue) greenDeckId = inputValue end + +-- Event handlers for toggle buttons +function publicPrivateChanged() + privateDeck = not privateDeck + self.editButton { index = 0, label = PRIVATE_TOGGLE_LABELS[privateDeck] } +end + +function loadUpgradedChanged() + loadNewestDeck = not loadNewestDeck + self.editButton { index = 1, label = UPGRADED_TOGGLE_LABELS[loadNewestDeck] } +end + +function loadInvestigatorsChanged() + loadInvestigators = not loadInvestigators + self.editButton { index = 2, label = LOAD_INVESTIGATOR_TOGGLE_LABELS[loadInvestigators] } +end + +function loadDecks() + -- testLoadLotsOfDecks() + -- Method in DeckImporterMain, visible due to inclusion + + local indexReady = allCardsBagApi.isIndexReady() + if (not indexReady) then + broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2}) + return + end + if (redDeckId ~= nil and redDeckId ~= "") then + buildDeck("Red", redDeckId) + end + if (orangeDeckId ~= nil and orangeDeckId ~= "") then + buildDeck("Orange", orangeDeckId) + end + if (whiteDeckId ~= nil and whiteDeckId ~= "") then + buildDeck("White", whiteDeckId) + end + if (greenDeckId ~= nil and greenDeckId ~= "") then + buildDeck("Green", greenDeckId) + end +end +end) +__bundle_register("playercards/AllCardsBagApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local AllCardsBagApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getAllCardsBag() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "AllCardsBag") + end + + -- Returns a specific card from the bag, based on ArkhamDB ID + ---@param id table String ID of the card to retrieve + ---@return table table + -- If the indexes are still being constructed, an empty table is + -- returned. Otherwise, a single table with the following fields + -- cardData: TTS object data, suitable for spawning the card + -- cardMetadata: Table of parsed metadata + AllCardsBagApi.getCardById = function(id) + return getAllCardsBag().call("getCardById", {id = id}) + end + + -- Gets a random basic weakness from the bag. Once a given ID has been returned + -- it will be removed from the list and cannot be selected again until a reload + -- occurs or the indexes are rebuilt, which will refresh the list to include all + -- weaknesses. + ---@return id String ID of the selected weakness. + AllCardsBagApi.getRandomWeaknessId = function() + return getAllCardsBag().call("getRandomWeaknessId") + end + + AllCardsBagApi.isIndexReady = function() + return getAllCardsBag().call("isIndexReady") + end + + -- Called by Hotfix bags when they load. If we are still loading indexes, then + -- the all cards and hotfix bags are being loaded together, and we can ignore + -- this call as the hotfix will be included in the initial indexing. If it is + -- called once indexing is complete it means the hotfix bag has been added + -- later, and we should rebuild the index to integrate the hotfix bag. + AllCardsBagApi.rebuildIndexForHotfix = function() + return getAllCardsBag().call("rebuildIndexForHotfix") + end + + -- Searches the bag for cards which match the given name and returns a list. Note that this is + -- an O(n) search without index support. It may be slow. + ---@param name String or string fragment to search for names + ---@param exact Boolean Whether the name match should be exact + AllCardsBagApi.getCardsByName = function(name, exact) + return getAllCardsBag().call("getCardsByName", {name = name, exact = exact}) + end + + AllCardsBagApi.isBagPresent = function() + return getAllCardsBag() and true + end + + -- Returns a list of cards from the bag matching a class and level (0 or upgraded) + ---@param class String class to retrieve ("Guardian", "Seeker", etc) + ---@param upgraded Boolean true for upgraded cards (Level 1-5), false for Level 0 + ---@return: If the indexes are still being constructed, returns an empty table. + -- Otherwise, a list of tables, each with the following fields + -- cardData: TTS object data, suitable for spawning the card + -- cardMetadata: Table of parsed metadata + AllCardsBagApi.getCardsByClassAndLevel = function(class, upgraded) + return getAllCardsBag().call("getCardsByClassAndLevel", {class = class, upgraded = upgraded}) + end + + AllCardsBagApi.getCardsByCycle = function(cycle) + return getAllCardsBag().call("getCardsByCycle", cycle) + end + + AllCardsBagApi.getUniqueWeaknesses = function() + return getAllCardsBag().call("getUniqueWeaknesses") + end + + return AllCardsBagApi +end +end) __bundle_register("playercards/PlayerCardSpawner", function(require, _LOADED, __bundle_register, __bundle_modules) -- Amount to shift for the next card (zShift) or next row of cards (xShift) -- Note that the table rotation is weird, and the X axis is vertical while the @@ -287,233 +1050,6 @@ Spawner.cardComparator = function(card1, card2) end end end) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlaymatApi = { } - local internal = { } - - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end - end - - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi -end -end) __bundle_register("playermat/Zones", function(require, _LOADED, __bundle_register, __bundle_modules) -- Sets up and returns coordinates for all possible spawn zones. Because Lua assigns tables by reference -- and there is no built-in function to copy a table this is relatively brute force. @@ -537,32 +1073,27 @@ __bundle_register("playermat/Zones", function(require, _LOADED, __bundle_registe -- SetAside5: Hunch Deck for Joe Diamond -- SetAside6: currently unused do + local playmatApi = require("playermat/PlaymatApi") local Zones = { } - local playerMatGuids = {} - playerMatGuids["Red"] = "0840d5" - playerMatGuids["Orange"] = "bd0ff4" - playerMatGuids["White"] = "8b081b" - playerMatGuids["Green"] = "383d8b" - local commonZones = {} - commonZones["Investigator"] = { -1.17702, 0, 0.00209 } - commonZones["Deck"] = { -1.822724, 0, -0.02940192 } - commonZones["Discard"] = { -1.822451, 0, 0.6092291 } - commonZones["Ally"] = { -0.6157398, 0, 0.02435675 } - commonZones["Body"] = { -0.6306521, 0, 0.553170 } - commonZones["Hand1"] = { 0.2155387, 0, 0.04257287 } - commonZones["Hand2"] = { -0.1803701, 0, 0.03745948 } - commonZones["Arcane1"] = { 0.2124223, 0, 0.5596902 } - commonZones["Arcane2"] = { -0.1711275, 0, 0.5567944 } - commonZones["Tarot"] = { 0.6016169, 0, 0.03273106 } - commonZones["Accessory"] = { 0.6049907, 0, 0.5546234 } - commonZones["BlankTop"] = { 1.758446, 0, 0.03965336 } - commonZones["BlankBottom"] = { 1.754469, 0, 0.5634764 } - commonZones["Threat1"] = { -0.9116555, 0, -0.6446251 } - commonZones["Threat2"] = { -0.4544126, 0, -0.6428719 } - commonZones["Threat3"] = { 0.002246313, 0, -0.6430681 } - commonZones["Threat4"] = { 0.4590618, 0, -0.6432732 } + commonZones["Investigator"] = { -1.177, 0, 0.002 } + commonZones["Deck"] = { -1.82, 0, 0 } + commonZones["Discard"] = { -1.82, 0, 0.61 } + commonZones["Ally"] = { -0.615, 0, 0.024 } + commonZones["Body"] = { -0.630, 0, 0.553 } + commonZones["Hand1"] = { 0.215, 0, 0.042 } + commonZones["Hand2"] = { -0.180, 0, 0.037 } + commonZones["Arcane1"] = { 0.212, 0, 0.559 } + commonZones["Arcane2"] = { -0.171, 0, 0.557 } + commonZones["Tarot"] = { 0.602, 0, 0.033 } + commonZones["Accessory"] = { 0.602, 0, 0.555 } + commonZones["BlankTop"] = { 1.758, 0, 0.040 } + commonZones["BlankBottom"] = { 1.754, 0, 0.563 } + commonZones["Threat1"] = { -0.911, 0, -0.625 } + commonZones["Threat2"] = { -0.454, 0, -0.625 } + commonZones["Threat3"] = { 0.002, 0, -0.625 } + commonZones["Threat4"] = { 0.459, 0, -0.625 } local zoneData = {} zoneData["White"] = {} @@ -584,14 +1115,14 @@ do zoneData["White"]["Threat3"] = commonZones["Threat3"] zoneData["White"]["Threat4"] = commonZones["Threat4"] zoneData["White"]["Minicard"] = { -1, 0, -1.45 } - zoneData["White"]["SetAside1"] = { 2.345893, 0, -0.520315 } - zoneData["White"]["SetAside2"] = { 2.345893, 0, 0.042552 } - zoneData["White"]["SetAside3"] = { 2.345893, 0, 0.605419 } - zoneData["White"]["UnderSetAside3"] = { 2.495893, 0, 0.805419 } - zoneData["White"]["SetAside4"] = { 2.775893, 0, -0.520315 } - zoneData["White"]["SetAside5"] = { 2.775893, 0, 0.042552 } - zoneData["White"]["SetAside6"] = { 2.775893, 0, 0.605419 } - zoneData["White"]["UnderSetAside6"] = { 2.925893, 0, 0.805419 } + zoneData["White"]["SetAside1"] = { 2.35, 0, -0.520 } + zoneData["White"]["SetAside2"] = { 2.35, 0, 0.042 } + zoneData["White"]["SetAside3"] = { 2.35, 0, 0.605 } + zoneData["White"]["UnderSetAside3"] = { 2.50, 0, 0.805 } + zoneData["White"]["SetAside4"] = { 2.78, 0, -0.520 } + zoneData["White"]["SetAside5"] = { 2.78, 0, 0.042 } + zoneData["White"]["SetAside6"] = { 2.78, 0, 0.605 } + zoneData["White"]["UnderSetAside6"] = { 2.93, 0, 0.805 } zoneData["Orange"] = {} zoneData["Orange"]["Investigator"] = commonZones["Investigator"] @@ -612,14 +1143,14 @@ do zoneData["Orange"]["Threat3"] = commonZones["Threat3"] zoneData["Orange"]["Threat4"] = commonZones["Threat4"] zoneData["Orange"]["Minicard"] = { 1, 0, -1.45 } - zoneData["Orange"]["SetAside1"] = { -2.350362, 0, -0.520315 } - zoneData["Orange"]["SetAside2"] = { -2.350362, 0, 0.042552 } - zoneData["Orange"]["SetAside3"] = { -2.350362, 0, 0.605419 } - zoneData["Orange"]["UnderSetAside3"] = { -2.500362, 0, 0.80419 } - zoneData["Orange"]["SetAside4"] = { -2.7803627, 0, -0.520315 } - zoneData["Orange"]["SetAside5"] = { -2.7803627, 0, 0.042552 } - zoneData["Orange"]["SetAside6"] = { -2.7803627, 0, 0.605419 } - zoneData["Orange"]["UnderSetAside6"] = { -2.9303627, 0, 0.80419 } + zoneData["Orange"]["SetAside1"] = { -2.35, 0, -0.520 } + zoneData["Orange"]["SetAside2"] = { -2.35, 0, 0.042} + zoneData["Orange"]["SetAside3"] = { -2.35, 0, 0.605 } + zoneData["Orange"]["UnderSetAside3"] = { -2.50, 0, 0.805 } + zoneData["Orange"]["SetAside4"] = { -2.78, 0, -0.520 } + zoneData["Orange"]["SetAside5"] = { -2.78, 0, 0.042 } + zoneData["Orange"]["SetAside6"] = { -2.78, 0, 0.605 } + zoneData["Orange"]["UnderSetAside6"] = { -2.93, 0, 0.805 } -- Green positions are the same as White and Red the same as Orange zoneData["Red"] = zoneData["Orange"] @@ -636,7 +1167,7 @@ do and playerColor ~= "Green") then return nil end - return getObjectFromGUID(playerMatGuids[playerColor]).positionToWorld(zoneData[playerColor][zoneName]) + return playmatApi.transformLocalPosition(zoneData[playerColor][zoneName], playerColor) end -- Return the global rotation for a card on the given player mat, based on its metadata. @@ -646,446 +1177,44 @@ do -- Y rotation to orient the card on the given player mat as well as a -- Z rotation to place the card face up or face down. Zones.getDefaultCardRotation = function(playerColor, zone) - local deckRotation = getObjectFromGUID(playerMatGuids[playerColor]).getRotation() - + local cardRotation = playmatApi.returnRotation(playerColor) if zone == "Deck" then - deckRotation = deckRotation + Vector(0, 0, 180) + cardRotation = cardRotation + Vector(0, 0, 180) end - - return deckRotation + return cardRotation end return Zones end end) -__bundle_register("arkhamdb/DeckImporterMain", function(require, _LOADED, __bundle_register, __bundle_modules) -require("arkhamdb/DeckImporterUi") -require("playercards/PlayerCardSpawner") +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local GUIDReferenceApi = {} -local allCardsBagApi = require("playercards/AllCardsBagApi") -local arkhamDb = require("arkhamdb/ArkhamDb") -local playAreaApi = require("core/PlayAreaApi") -local playmatApi = require("playermat/PlaymatApi") -local zones = require("playermat/Zones") - -function onLoad(script_state) - initializeUi(JSON.decode(script_state)) - math.randomseed(os.time()) - arkhamDb.initialize() -end - -function onSave() return JSON.encode(getUiState()) end - --- Returns the zone name where the specified card should be placed, based on its metadata. ----@param cardMetadata Table of card metadata. ----@return Zone String Name of the zone such as "Deck", "SetAside1", etc. --- See Zones object documentation for a list of valid zones. -function getDefaultCardZone(cardMetadata, bondedList) - if (cardMetadata.id == "09080-m") then -- Have to check the Servitor before other minicards - return "SetAside6" - elseif (cardMetadata.id == "09006") then -- On The Mend is set aside - return "SetAside2" - elseif cardMetadata.type == "Investigator" then - return "Investigator" - elseif cardMetadata.type == "Minicard" then - return "Minicard" - elseif cardMetadata.type == "UpgradeSheet" then - return "SetAside4" - elseif cardMetadata.startsInPlay then - return "BlankTop" - elseif cardMetadata.permanent then - return "SetAside1" - elseif bondedList[cardMetadata.id] then - return "SetAside2" - -- SetAside3 is used for Ancestral Knowledge / Underworld Market - else - return "Deck" - end -end - -function buildDeck(playerColor, deckId) - local uiState = getUiState() - arkhamDb.getDecklist( - playerColor, - deckId, - uiState.private, - uiState.loadNewest, - uiState.investigators, - loadCards) -end - --- Process the slot list, which defines the card Ids and counts of cards to load. Spawn those cards --- at the appropriate zones and report an error to the user if any could not be loaded. --- This is a callback function which handles the results of ArkhamDb.getDecklist() --- This method uses an encapsulated coroutine with yields to make the card spawning cleaner. --- ----@param slots Table Key-Value table of cardId:count. cardId is the ArkhamDB ID of the card to spawn, --- and count is the number which should be spawned ----@param investigatorId String ArkhamDB ID (code) for this deck's investigator. --- Investigator cards should already be added to the slots list if they --- should be spawned, but this value is separate to check for special --- handling for certain investigators ----@param bondedList Table A table of cardID keys to meaningless values. Card IDs in this list were added --- from a parent bonded card. ----@param customizations String ArkhamDB data for customizations on customizable cards ----@param playerColor String Color name of the player mat to place this deck on (e.g. "Red") ----@param loadAltInvestigator String Contains the name of alternative art for the investigator ("normal", "revised" or "promo") -function loadCards(slots, investigatorId, bondedList, customizations, playerColor, loadAltInvestigator) - function coinside() - local yPos = {} - local cardsToSpawn = {} - for cardId, cardCount in pairs(slots) do - local card = allCardsBagApi.getCardById(cardId) - if card ~= nil then - local cardZone = getDefaultCardZone(card.metadata, bondedList) - for i = 1, cardCount do - table.insert(cardsToSpawn, { data = card.data, metadata = card.metadata, zone = cardZone }) - end - - slots[cardId] = 0 - end - end - - handleAncestralKnowledge(cardsToSpawn) - handleUnderworldMarket(cardsToSpawn, playerColor) - handleHunchDeck(investigatorId, cardsToSpawn, playerColor) - handleCustomizableUpgrades(cardsToSpawn, customizations) - handlePeteSignatureAssets(investigatorId, cardsToSpawn) - - -- Split the card list into separate lists for each zone - local zoneDecks = buildZoneLists(cardsToSpawn) - -- Spawn the list for each zone - for zone, zoneCards in pairs(zoneDecks) do - local deckPos = zones.getZonePosition(playerColor, zone) - deckPos.y = 3 - - local callback = nil - -- If cards are spread too close together TTS groups them weirdly, selecting multiples - -- when hovering over a single card. This distance is the minimum to avoid that - local spreadDistance = 1.15 - if (zone == "SetAside4") then - -- SetAside4 is reserved for customization cards, and we want them spread on the table - -- so their checkboxes are visible - -- TO-DO: take into account that spreading will make multiple rows - -- (this is affected by the user's local settings!) - if (playerColor == "White") then - deckPos.z = deckPos.z + (#zoneCards - 1) * spreadDistance - elseif (playerColor == "Green") then - deckPos.x = deckPos.x + (#zoneCards - 1) * spreadDistance - end - callback = function(deck) deck.spread(spreadDistance) end - elseif zone == "Deck" then - callback = function(deck) deckSpawned(deck, playerColor) end - elseif zone == "Investigator" or zone == "Minicard" then - callback = function(card) loadAltArt(card, loadAltInvestigator) end - end - Spawner.spawnCards( - zoneCards, - deckPos, - zones.getDefaultCardRotation(playerColor, zone), - true, -- Sort deck - callback) - - coroutine.yield(0) - end - - -- Look for any cards which haven't been loaded - local hadError = false - for cardId, remainingCount in pairs(slots) do - if remainingCount > 0 then - hadError = true - arkhamDb.logCardNotFound(cardId, playerColor) - end - end - if (not hadError) then - printToAll("Deck loaded successfully!", playerColor) - end - return 1 + local function getGuidHandler() + return getObjectFromGUID("123456") end - startLuaCoroutine(self, "coinside") -end - --- Callback handler for the main deck spawning. Looks for cards which should start in hand, and --- draws them for the appropriate player. ----@param deck Object Callback-provided spawned deck object ----@param playerColor String Color of the player to draw the cards to -function deckSpawned(deck, playerColor) - local player = Player[playmatApi.getPlayerColor(playerColor)] - local handPos = player.getHandTransform(1).position -- Only one hand zone per player - local deckCards = deck.getData().ContainedObjects - -- Process in reverse order so taking cards out doesn't upset the indexing - for i = #deckCards, 1, -1 do - local cardMetadata = JSON.decode(deckCards[i].GMNotes) or { } - if cardMetadata.startsInHand then - deck.takeObject({ index = i - 1, position = handPos, flip = true, smooth = true}) - end - end -end - --- Converts the Raven Quill's selections from card IDs to card names. This could be more elegant --- but the inputs are very static so we're using some brute force. ----@param selectionString String provided by ArkhamDB, indicates the customization selections --- Should be either a single card ID or two separated by a ^ (e.g. XXXXX^YYYYY) -function convertRavenQuillSelections(selectionString) - if (string.len(selectionString) == 5) then - return getCardName(selectionString) - elseif (string.len(selectionString) == 11) then - return getCardName(string.sub(selectionString, 1, 5)) .. ", " .. getCardName(string.sub(selectionString, 7)) - end -end - --- Converts Grizzled's selections from a single string with "^". ----@param selectionString String provided by ArkhamDB, indicates the customization selections --- Should be two Traits separated by a ^ (e.g. XXXXX^YYYYY) -function convertGrizzledSelections(selectionString) - return selectionString:gsub("%^", ", ") -end - --- Returns the simple name of a card given its ID. This will find the card and strip any trailing --- SCED-specific suffixes such as (Taboo) or (Level) -function getCardName(cardId) - local card = allCardsBagApi.getCardById(cardId) - if (card ~= nil) then - local name = card.data.Nickname - if (string.find(name, " %(")) then - return string.sub(name, 1, string.find(name, " %(") - 1) - else - return name - end - end -end - --- Split a single list of cards into a separate table of lists, keyed by the zone ----@param cards: Table of {cardData, cardMetadata, zone} ----@return: Table of {zoneName=card list} -function buildZoneLists(cards) - local zoneList = {} - for _, card in ipairs(cards) do - if zoneList[card.zone] == nil then - zoneList[card.zone] = {} - end - table.insert(zoneList[card.zone], card) + -- 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 - return zoneList -end - --- Check to see if the deck list has Ancestral Knowledge. If it does, move 5 random skills to SetAside3 ----@param cardList Table Deck list being created -function handleAncestralKnowledge(cardList) - local hasAncestralKnowledge = false - local skillList = {} - -- Have to process the entire list to check for Ancestral Knowledge and get all possible skills, so do both in one pass - for i, card in ipairs(cardList) do - if card.metadata.id == "07303" then - hasAncestralKnowledge = true - card.zone = "SetAside3" - elseif (card.metadata.type == "Skill" - and card.zone == "Deck" - and not card.metadata.weakness) then - table.insert(skillList, i) - end - end - if hasAncestralKnowledge then - for i = 1, 5 do - -- Move 5 random skills to SetAside3 - local skillListIndex = math.random(#skillList) - cardList[skillList[skillListIndex]].zone = "UnderSetAside3" - table.remove(skillList, skillListIndex) - end - end -end - --- Check for and handle Underworld Market by moving all Illicit cards to UnderSetAside3 ----@param cardList Table Deck list being created ----@param playerColor String Color this deck is being loaded for -function handleUnderworldMarket(cardList, playerColor) - local hasMarket = false - local illicitList = {} - -- Process the entire list to check for Underworld Market and get all possible skills, doing both in one pass - for i, card in ipairs(cardList) do - if card.metadata.id == "09077" then - -- Underworld Market found - hasMarket = true - card.zone = "SetAside3" - elseif card.metadata.traits ~= nil and string.find(card.metadata.traits, "Illicit", 1, true) and card.zone == "Deck" then - table.insert(illicitList, i) - 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 - if hasMarket then - if #illicitList < 10 then - printToAll("Only " .. #illicitList .. - " Illicit cards in your deck, you can't trigger Underworld Market's ability.", - playerColor) - else - -- Process cards to move them to the market deck. This is done in reverse - -- order because the sorting needs to be reversed (deck sorts for face down) - -- Performance here may be an issue, as table.remove() is an O(n) operation - -- which makes the full shift O(n^2). But keep it simple unless it becomes - -- a problem - for i = #illicitList, 1, -1 do - local moving = cardList[illicitList[i]] - moving.zone = "UnderSetAside3" - table.remove(cardList, illicitList[i]) - table.insert(cardList, moving) - end - - if #illicitList > 10 then - printToAll("Moved all " .. #illicitList .. - " Illicit cards to the Market deck, reduce it to 10", - playerColor) - else - printToAll("Built the Market deck", playerColor) - end - 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 -end --- If the investigator is Joe Diamond, extract all Insight events to SetAside5 to build the Hunch --- Deck. ----@param investigatorId String ID for the deck's investigator card. Passed separately because the ---- investigator may not be included in the cardList ----@param cardList Table Deck list being created ----@param playerColor String Color this deck is being loaded for -function handleHunchDeck(investigatorId, cardList, playerColor) - if investigatorId == "05002" then -- Joe Diamond - local insightList = {} - for i, card in ipairs(cardList) do - if (card.metadata.type == "Event" - and card.metadata.traits ~= nil - and string.match(card.metadata.traits, "Insight") - and card.metadata.bonded_to == nil) then - table.insert(insightList, i) - end - end - -- Process insights to move them to the hunch deck. This is done in reverse - -- order because the sorting needs to be reversed (deck sorts for face down) - -- Performance here may be an issue, as table.remove() is an O(n) operation - -- which makes the full shift O(n^2). But keep it simple unless it becomes - -- a problem - for i = #insightList, 1, -1 do - local moving = cardList[insightList[i]] - moving.zone = "SetAside5" - table.remove(cardList, insightList[i]) - table.insert(cardList, moving) - end - if #insightList < 11 then - printToAll("Joe's hunch deck must have 11 cards but the deck only has " .. #insightList .. - " Insight events.", playerColor) - elseif #insightList > 11 then - printToAll("Moved all " .. #insightList .. - " Insight events to the hunch deck, reduce it to 11.", playerColor) - else - printToAll("Built Joe's hunch deck", playerColor) - end - end -end - --- For any customization upgrade cards in the card list, process the metadata from the deck to --- set the save state to show the correct checkboxes/text field values ----@param cardList Table Deck list being created ----@param customizations Table Deck's meta table, extracted from ArkhamDB's deck structure -function handleCustomizableUpgrades(cardList, customizations) - for _, card in ipairs(cardList) do - if card.metadata.type == "UpgradeSheet" then - local baseId = string.sub(card.metadata.id, 1, 5) - local upgrades = customizations["cus_" .. baseId] - - if upgrades ~= nil then - -- initialize tables - -- markedBoxes: contains the amount of markedBoxes (left to right) per row (starting at row 1) - -- inputValues: contains the amount of inputValues per row (starting at row 0) - local selectedUpgrades = { } - local index_xp = {} - - -- get the index and xp values (looks like this: X|X,X|X, ..) - -- input string from ArkhamDB is split by "," - for str in string.gmatch(customizations["cus_" .. baseId], "([^,]+)") do - table.insert(index_xp, str) - end - - -- split each pair and assign it to the proper position in markedBoxes - for _, entry in ipairs(index_xp) do - -- counter increments from 1 to 3 and indicates the part of the string we are on - -- usually: 1 = row, 2 = amount of check boxes, 3 = entry in inputfield - local counter = 0 - local row = 0 - - -- parsing the string for each row - for str in entry:gmatch("([^|]+)") do - counter = counter + 1 - - if counter == 1 then - row = tonumber(str) + 1 - elseif counter == 2 then - if selectedUpgrades[row] == nil then - selectedUpgrades[row] = { } - end - selectedUpgrades[row].xp = tonumber(str) - elseif counter == 3 and str ~= "" then - if baseId == "09042" then - selectedUpgrades[row].text = convertRavenQuillSelections(str) - elseif baseId == "09101" then - selectedUpgrades[row].text = convertGrizzledSelections(str) - elseif baseId == "09079" then -- Living Ink skill selection - -- All skills, regardless of row, are placed in upgrade slot 1 as a comma-delimited - -- list - if selectedUpgrades[1].text == nil then - selectedUpgrades[1].text = str - else - selectedUpgrades[1].text = selectedUpgrades[1].text .. "," .. str - end - else - selectedUpgrades[row].text = str - end - end - end - end - - -- write the loaded values to the save_data of the sheets - card.data["LuaScriptState"] = JSON.encode({ selections = selectedUpgrades }) - end - end - end -end - --- Handles cards that start in play under specific conditions for Ashcan Pete (Regular Pete - Duke, Parallel Pete - Guitar) ----@param investigatorId String ID for the deck's investigator card. Passed separately because the ---- investigator may not be included in the cardList ----@param cardList Table Deck list being created -function handlePeteSignatureAssets(investigatorId, cardList) - if investigatorId == "02005" or investigatorId == "02005-pb" then -- regular Pete's front - for i, card in ipairs(cardList) do - if card.metadata.id == "02014" then -- Duke - card.zone = "BlankTop" - end - end - elseif investigatorId == "02005-p" or investigatorId == "02005-pf" then -- parallel Pete's front - for i, card in ipairs(cardList) do - if card.metadata.id == "90047" then -- Pete's Guitar - card.zone = "BlankTop" - end - end - end -end - --- Callback function for investigator cards and minicards to set the correct state for alt art ----@param card Object Card which needs to be set the state for ----@param loadAltInvestigator String Contains the name of alternative art for the investigator ("normal", "revised" or "promo") -function loadAltArt(card, loadAltInvestigator) - -- states are set up this way: - -- 1 - normal, 2 - revised/promo, 3 - promo (if 2 is revised) - -- This means we can always load the 2nd state for revised and just get the last state for promo - if loadAltInvestigator == "normal" then - return - elseif loadAltInvestigator == "revised" then - card.setState(2) - elseif loadAltInvestigator == "promo" then - local states = card.getStates() - card.setState(#states) - end + return GUIDReferenceApi end end) __bundle_register("arkhamdb/ArkhamDb", function(require, _LOADED, __bundle_register, __bundle_modules) @@ -1289,7 +1418,7 @@ do local altArt = { front = "normal", back = "normal" } -- translating front ID - if altFrontId > 90000 and altFrontId < 90047 then + if altFrontId > 90000 and altFrontId < 90100 then altArt.front = "parallel" elseif altFrontId > 01500 and altFrontId < 01506 then altArt.front = "revised" @@ -1298,7 +1427,7 @@ do end -- translating back ID - if altBackId > 90000 and altBackId < 90047 then + if altBackId > 90000 and altBackId < 90100 then altArt.back = "parallel" elseif altBackId > 01500 and altBackId < 01506 then altArt.back = "revised" @@ -1386,7 +1515,12 @@ do local card = allCardsBagApi.getCardById(cardId) if (card ~= nil and card.metadata.bonded ~= nil) then for _, bond in ipairs(card.metadata.bonded) do - bondedCards[bond.id] = bond.count + -- add a bonded card for each copy of the parent card (except for Pendant of the Queen) + if bond.id == "06022" then + bondedCards[bond.id] = bond.count + else + bondedCards[bond.id] = bond.count * cardCount + end -- We need to know which cards are bonded to determine their position, remember them bondedList[bond.id] = true -- Also adding taboo versions of bonded cards to the list @@ -1565,427 +1699,347 @@ do return ArkhamDb end end) -__bundle_register("arkhamdb/DeckImporterUi", function(require, _LOADED, __bundle_register, __bundle_modules) -local allCardsBagApi = require("playercards/AllCardsBagApi") - -local INPUT_FIELD_HEIGHT = 340 -local INPUT_FIELD_WIDTH = 1500 -local FIELD_COLOR = { 0.9, 0.7, 0.5 } - -local PRIVATE_TOGGLE_LABELS = {} -PRIVATE_TOGGLE_LABELS[true] = "Private" -PRIVATE_TOGGLE_LABELS[false] = "Published" - -local UPGRADED_TOGGLE_LABELS = {} -UPGRADED_TOGGLE_LABELS[true] = "Upgraded" -UPGRADED_TOGGLE_LABELS[false] = "Specific" - -local LOAD_INVESTIGATOR_TOGGLE_LABELS = {} -LOAD_INVESTIGATOR_TOGGLE_LABELS[true] = "Yes" -LOAD_INVESTIGATOR_TOGGLE_LABELS[false] = "No" - -local redDeckId = "" -local orangeDeckId = "" -local whiteDeckId = "" -local greenDeckId = "" - -local privateDeck = true -local loadNewestDeck = true -local loadInvestigators = false - --- Returns a table with the full state of the UI, including options and deck IDs. --- This can be used to persist via onSave(), or provide values for a load operation --- Table values: --- redDeck: Deck ID to load for the red player --- orangeDeck: Deck ID to load for the orange player --- whiteDeck: Deck ID to load for the white player --- greenDeck: Deck ID to load for the green player --- private: True to load a private deck, false to load a public deck --- loadNewest: True if the most upgraded version of the deck should be loaded --- investigators: True if investigator cards should be spawned -function getUiState() - return { - redDeck = redDeckId, - orangeDeck = orangeDeckId, - whiteDeck = whiteDeckId, - greenDeck = greenDeckId, - private = privateDeck, - loadNewest = loadNewestDeck, - investigators = loadInvestigators - } -end - --- Updates the state of the UI based on the provided table. Any values not provided will be left the same. ----@param uiStateTable Table of values to update on importer --- Table values: --- redDeck: Deck ID to load for the red player --- orangeDeck: Deck ID to load for the orange player --- whiteDeck: Deck ID to load for the white player --- greenDeck: Deck ID to load for the green player --- private: True to load a private deck, false to load a public deck --- loadNewest: True if the most upgraded version of the deck should be loaded --- investigators: True if investigator cards should be spawned -function setUiState(uiStateTable) - -- Callback functions aren't triggered when editing buttons/inputs so values must be set manually - - if uiStateTable["greenDeck"] then - greenDeckId = uiStateTable["greenDeck"] - self.editInput({index=0, value=greenDeckId}) - end - if uiStateTable["redDeck"] then - redDeckId = uiStateTable["redDeck"] - self.editInput({index=1, value=redDeckId}) - end - if uiStateTable["whiteDeck"] then - whiteDeckId = uiStateTable["whiteDeck"] - self.editInput({index=2, value=whiteDeckId}) - end - if uiStateTable["orangeDeck"]then - orangeDeckId = uiStateTable["orangeDeck"] - self.editInput({index=3, value=orangeDeckId}) - end - if uiStateTable["private"] then - privateDeck = uiStateTable["private"] - self.editButton { index = 0, label = PRIVATE_TOGGLE_LABELS[privateDeck] } - end - if uiStateTable["loadNewest"] then - loadNewestDeck = uiStateTable["loadNewest"] - self.editButton { index = 1, label = UPGRADED_TOGGLE_LABELS[loadNewestDeck] } - end - if uiStateTable["investigators"] then - loadInvestigators = uiStateTable["investigators"] - self.editButton { index = 2, label = LOAD_INVESTIGATOR_TOGGLE_LABELS[loadInvestigators] } - end -end - --- Sets up the UI for the deck loader, populating fields from the given save state table decoded from onLoad() -function initializeUi(savedUiState) - if savedUiState ~= nil then - redDeckId = savedUiState.redDeck - orangeDeckId = savedUiState.orangeDeck - whiteDeckId = savedUiState.whiteDeck - greenDeckId = savedUiState.greenDeck - privateDeck = savedUiState.private - loadNewestDeck = savedUiState.loadNewest - loadInvestigators = savedUiState.investigators - end - - makeOptionToggles() - makeDeckIdFields() - makeBuildButton() -end - -function makeOptionToggles() - -- common parameters - local checkbox_parameters = {} - checkbox_parameters.function_owner = self - checkbox_parameters.width = INPUT_FIELD_WIDTH - checkbox_parameters.height = INPUT_FIELD_HEIGHT - checkbox_parameters.scale = { 0.1, 0.1, 0.1 } - checkbox_parameters.font_size = 240 - checkbox_parameters.hover_color = { 0.4, 0.6, 0.8 } - checkbox_parameters.color = FIELD_COLOR - - -- public / private deck - checkbox_parameters.click_function = "publicPrivateChanged" - checkbox_parameters.position = { 0.25, 0.1, -0.102 } - checkbox_parameters.tooltip = "Published or private deck?\n\nPLEASE USE A PRIVATE DECK IF JUST FOR TTS TO AVOID FLOODING ARKHAMDB PUBLISHED DECK LISTS!" - checkbox_parameters.label = PRIVATE_TOGGLE_LABELS[privateDeck] - self.createButton(checkbox_parameters) - - -- load upgraded? - checkbox_parameters.click_function = "loadUpgradedChanged" - checkbox_parameters.position = { 0.25, 0.1, -0.01 } - checkbox_parameters.tooltip = "Load newest upgrade or exact deck?" - checkbox_parameters.label = UPGRADED_TOGGLE_LABELS[loadNewestDeck] - self.createButton(checkbox_parameters) - - -- load investigators? - checkbox_parameters.click_function = "loadInvestigatorsChanged" - checkbox_parameters.position = { 0.25, 0.1, 0.081 } - checkbox_parameters.tooltip = "Spawn investigator cards?" - checkbox_parameters.label = LOAD_INVESTIGATOR_TOGGLE_LABELS[loadInvestigators] - self.createButton(checkbox_parameters) -end - --- Create the four deck ID entry fields -function makeDeckIdFields() - local input_parameters = {} - -- Parameters common to all entry fields - input_parameters.function_owner = self - input_parameters.scale = { 0.1, 0.1, 0.1 } - input_parameters.width = INPUT_FIELD_WIDTH - input_parameters.height = INPUT_FIELD_HEIGHT - input_parameters.font_size = 320 - input_parameters.tooltip = "Deck ID from ArkhamDB URL of the deck\nPublic URL: 'https://arkhamdb.com/decklist/view/101/knowledge-overwhelming-solo-deck-1.0' = '101'\nPrivate URL: 'https://arkhamdb.com/deck/view/102' = '102'" - input_parameters.alignment = 3 -- Center - input_parameters.color = FIELD_COLOR - input_parameters.font_color = { 0, 0, 0 } - input_parameters.validation = 2 -- Integer - - -- Green - input_parameters.input_function = "greenDeckChanged" - input_parameters.position = { -0.166, 0.1, 0.385 } - input_parameters.value = greenDeckId - self.createInput(input_parameters) - -- Red - input_parameters.input_function = "redDeckChanged" - input_parameters.position = { 0.171, 0.1, 0.385 } - input_parameters.value = redDeckId - self.createInput(input_parameters) - -- White - input_parameters.input_function = "whiteDeckChanged" - input_parameters.position = { -0.166, 0.1, 0.474 } - input_parameters.value = whiteDeckId - self.createInput(input_parameters) - -- Orange - input_parameters.input_function = "orangeDeckChanged" - input_parameters.position = { 0.171, 0.1, 0.474 } - input_parameters.value = orangeDeckId - self.createInput(input_parameters) -end - --- Create the Build All button. This is a transparent button which covers the Build All portion of the background graphic -function makeBuildButton() - local button_parameters = {} - button_parameters.click_function = "loadDecks" - button_parameters.function_owner = self - button_parameters.position = { 0, 0.1, 0.71 } - button_parameters.width = 320 - button_parameters.height = 30 - button_parameters.color = { 0, 0, 0, 0 } - button_parameters.tooltip = "Click to build all four decks!" - self.createButton(button_parameters) -end - --- Event handlers for deck ID change -function redDeckChanged(_, _, inputValue) redDeckId = inputValue end - -function orangeDeckChanged(_, _, inputValue) orangeDeckId = inputValue end - -function whiteDeckChanged(_, _, inputValue) whiteDeckId = inputValue end - -function greenDeckChanged(_, _, inputValue) greenDeckId = inputValue end - --- Event handlers for toggle buttons -function publicPrivateChanged() - privateDeck = not privateDeck - self.editButton { index = 0, label = PRIVATE_TOGGLE_LABELS[privateDeck] } -end - -function loadUpgradedChanged() - loadNewestDeck = not loadNewestDeck - self.editButton { index = 1, label = UPGRADED_TOGGLE_LABELS[loadNewestDeck] } -end - -function loadInvestigatorsChanged() - loadInvestigators = not loadInvestigators - self.editButton { index = 2, label = LOAD_INVESTIGATOR_TOGGLE_LABELS[loadInvestigators] } -end - -function loadDecks() - -- testLoadLotsOfDecks() - -- Method in DeckImporterMain, visible due to inclusion - - local indexReady = allCardsBagApi.isIndexReady() - if (not indexReady) then - broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2}) - return - end - if (redDeckId ~= nil and redDeckId ~= "") then - buildDeck("Red", redDeckId) - end - if (orangeDeckId ~= nil and orangeDeckId ~= "") then - buildDeck("Orange", orangeDeckId) - end - if (whiteDeckId ~= nil and whiteDeckId ~= "") then - buildDeck("White", whiteDeckId) - end - if (greenDeckId ~= nil and greenDeckId ~= "") then - buildDeck("Green", greenDeckId) - end -end -end) __bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end -- Returns the current value of the investigator counter from the playmat ---@return Integer. Number of investigators currently set on the counter PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") + return getInvestigatorCounter().getVar("val") end -- Updates the current value of the investigator counter from the playmat ---@param count Number of investigators to set on the counter PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) + getInvestigatorCounter().call("updateVal", count) end -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) end PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) end PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) end PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) end -- Reset the play area's tracking of which cards have had tokens spawned. PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") + return getPlayArea().call("resetSpawnedCards") end -- Event to be called when the current scenario has changed. ---@param scenarioName Name of the new scenario PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) end -- Sets this playmat's snap points to limit snapping to locations or not. -- If matchTypes is false, snap points will be reset to snap all cards. ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) end -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged -- cards before they're destroyed by entering the container PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) end -- counts the VP on locations in the play area PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") + return getPlayArea().call("countVP") end -- highlights all locations in the play area without metadata ---@param state Boolean True if highlighting should be enabled PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) + return getPlayArea().call("highlightMissingData", state) end -- highlights all locations in the play area with VP ---@param state Boolean True if highlighting should be enabled PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) + return getPlayArea().call("countVP", state) end -- Checks if an object is in the play area (returns true or false) PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) + return getPlayArea().call("isInPlayArea", object) end PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image + return getPlayArea().getCustomObject().image end PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) + return getPlayArea().call("updateSurface", url) end -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the -- data to the local token manager instance. ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) + getPlayArea().call("updateLocations", args) end PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") + return getPlayArea().getVar("customDataHelper") end return PlayAreaApi end end) -__bundle_register("playercards/AllCardsBagApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local AllCardsBagApi = {} - local ALL_CARDS_BAG_GUID = "15bb07" + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - -- Returns a specific card from the bag, based on ArkhamDB ID - -- @param table: - -- id: String ID of the card to retrieve - -- @return: If the indexes are still being constructed, an empty table is - -- returned. Otherwise, a single table with the following fields - -- cardData: TTS object data, suitable for spawning the card - -- cardMetadata: Table of parsed metadata - AllCardsBagApi.getCardById = function(id) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardById", {id = id}) + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end end - -- Gets a random basic weakness from the bag. Once a given ID has been returned - -- it will be removed from the list and cannot be selected again until a reload - -- occurs or the indexes are rebuilt, which will refresh the list to include all - -- weaknesses. - -- @return: String ID of the selected weakness. - AllCardsBagApi.getRandomWeaknessId = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getRandomWeaknessId") + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result end - AllCardsBagApi.isIndexReady = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("isIndexReady") + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end end - -- Called by Hotfix bags when they load. If we are still loading indexes, then - -- the all cards and hotfix bags are being loaded together, and we can ignore - -- this call as the hotfix will be included in the initial indexing. If it is - -- called once indexing is complete it means the hotfix bag has been added - -- later, and we should rebuild the index to integrate the hotfix bag. - AllCardsBagApi.rebuildIndexForHotfix = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("rebuildIndexForHotfix") + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end end - -- Searches the bag for cards which match the given name and returns a list. Note that this is - -- an O(n) search without index support. It may be slow. - -- @param - -- name String or string fragment to search for names - -- exact Whether the name match should be exact - AllCardsBagApi.getCardsByName = function(name, exact) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardsByName", {name = name, exact = exact}) + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - AllCardsBagApi.isBagPresent = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID) and true + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end end - -- Returns a list of cards from the bag matching a class and level (0 or upgraded) - -- @param - -- class: String class to retrieve ("Guardian", "Seeker", etc) - -- upgraded: true for upgraded cards (Level 1-5), false for Level 0 - -- @return: If the indexes are still being constructed, returns an empty table. - -- Otherwise, a list of tables, each with the following fields - -- cardData: TTS object data, suitable for spawning the card - -- cardMetadata: Table of parsed metadata - AllCardsBagApi.getCardsByClassAndLevel = function(class, upgraded) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardsByClassAndLevel", {class = class, upgraded = upgraded}) + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end - AllCardsBagApi.getCardsByCycle = function(cycle) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardsByCycle", cycle) + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end - AllCardsBagApi.getUniqueWeaknesses = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getUniqueWeaknesses") + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end - return AllCardsBagApi + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi end end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Campaign ImporterExporter 334ee3.ttslua b/unpacked/Custom_Tile Campaign ImporterExporter 334ee3.ttslua index e7f900e0c..f380e2e9c 100644 --- a/unpacked/Custom_Tile Campaign ImporterExporter 334ee3.ttslua +++ b/unpacked/Custom_Tile Campaign ImporterExporter 334ee3.ttslua @@ -41,11 +41,415 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("accessories/CampaignImporterExporter") +end) +__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local OptionPanelApi = {} + + -- loads saved options + ---@param options Table New options table + OptionPanelApi.loadSettings = function(options) + return Global.call("loadSettings", options) + end + + -- returns option panel table + OptionPanelApi.getOptions = function() + return Global.getTable("optionPanel") + end + + return OptionPanelApi +end +end) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end + + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") + end + + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) + end + + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) + end + + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) + end + + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi +end +end) +__bundle_register("accessories/CampaignImporterExporter", function(require, _LOADED, __bundle_register, __bundle_modules) +local blessCurseApi = require("chaosbag/BlessCurseManagerApi") +local chaosBagApi = require("chaosbag/ChaosBagApi") +local deckImporterApi = require("arkhamdb/DeckImporterApi") +local guidReferenceApi = require("core/GUIDReferenceApi") +local optionPanelApi = require("core/OptionPanelApi") +local playAreaApi = require("core/PlayAreaApi") +local playmatApi = require("playermat/PlaymatApi") + +local campaignTokenData = { + Name = "Custom_Model", + Transform = { + posX = -21.25, + posY = 1.68, + posZ = 55.59, + rotX = 0, + rotY = 270, + rotZ = 0, + scaleX = 2, + scaleY = 2, + scaleZ = 2 + }, + Description = "SCED Importer Token", + Tags = { + "ImporterToken" + }, + CustomMesh = { + MeshURL = "http://cloud-3.steamusercontent.com/ugc/943949966265929204/A38BB5D72419E6298385556D931877C0A1A55C17/", + DiffuseURL = "http://cloud-3.steamusercontent.com/ugc/254843371583188147/920981125E37B5CEB6C400E3FD353A2C428DA969/", + NormalURL = "", + ColliderURL = "http://cloud-3.steamusercontent.com/ugc/943949966265929204/A38BB5D72419E6298385556D931877C0A1A55C17/", + Convex = true, + MaterialIndex = 2, + TypeIndex = 0, + CustomShader = { + SpecularColor = { + r = 0.7222887, + g = 0.507659256, + b = 0.339915335 + }, + SpecularIntensity = 0.4, + SpecularSharpness = 7.0, + FresnelStrength = 0.0 + }, + CastShadows = true + } +} +local COLORS = { "White", "Orange", "Green", "Red" } + +function onLoad() + self.createButton({ + click_function = "findCampaignFromToken", + function_owner = self, + label = "Import", + tooltip = "Load in a campaign save from a token!\n\n(Token can be anywhere on the table, but ensure there is only 1!)", + position = { x = -1, y = 0.2, z = 0 }, + font_size = 400, + width = 1400, + height = 600, + scale = { 0.5, 1, 0.5 }, + }) + self.createButton({ + click_function = "createCampaignToken", + function_owner = self, + label = "Export", + tooltip = "Create a campaign save token!\n\n(Ensure all chaos tokens have been unsealed!)", + position = { x = 1, y = 0.2, z = 0 }, + font_size = 400, + width = 1400, + height = 600, + scale = { 0.5, 1, 0.5 }, + }) +end + +--------------------------------------------------------- +-- main import functions (split up to allow for Wait conditions) +--------------------------------------------------------- + +-- Identifies import token, determines campaign box and downloads it (if needed) +function findCampaignFromToken(_, _, _) + local coin = nil + local coinObjects = getObjectsWithTag("ImporterToken") + if #coinObjects == 0 then + broadcastToAll("Could not find importer token", Color.Red) + elseif #coinObjects > 1 then + broadcastToAll("More than 1 importer token found. Please delete all but 1 importer token", Color.Yellow) + else + coin = coinObjects[1] + + local importData = JSON.decode(coin.getGMNotes()) + campaignBoxGUID = importData["box"] + + local campaignBox = getObjectFromGUID(campaignBoxGUID) + if campaignBox.type == "Generic" then + campaignBox.call("buttonClick_download") + end + Wait.condition( + function() + if #campaignBox.getObjects() > 0 then + placeCampaignFromToken(importData) + else + createCampaignFromToken(importData) + end + end, + function() + local obj = getObjectFromGUID(campaignBoxGUID) + if obj == nil then + return false + else + return obj.type == "Bag" and obj.getLuaScript() ~= "" + end + end, + 2, + function() broadcastToAll("Error loading campaign box") end + ) + end +end + +-- After box has been downloaded, places content on table +function placeCampaignFromToken(importData) + getObjectFromGUID(importData["box"]).call("buttonClick_place") + Wait.condition( + function() createCampaignFromToken(importData) end, + function() return findUniqueObjectWithTag("CampaignLog") ~= nil end, + 2, + function() broadcastToAll("Error placing campaign box") end + ) +end + +-- After content is placed on table, conducts all the other import operations +function createCampaignFromToken(importData) + -- destroy existing campaign log and load saved campaign log + findUniqueObjectWithTag("CampaignLog").destruct() + spawnObjectData({ data = importData["log"] }) + + chaosBagApi.setChaosBagState(importData["bag"]) + + -- populate trauma values + if importData["trauma"] then + setTrauma(importData["trauma"]) + end + + -- populate ArkhamDB deck IDs + if importData["decks"] then + deckImporterApi.setUiState(importData["decks"]) + end + + playAreaApi.setInvestigatorCount(importData["clueCount"]) + + -- set campaign guide page + local guide = findUniqueObjectWithTag("CampaignGuide") + if guide then + Wait.condition( + -- Called after the condition function returns true + function() log("Campaign Guide import successful!") end, + -- Condition function that is called continiously until returs true or timeout is reached + function() return guide.Book.setPage(importData["guide"]) end, + -- Amount of time in seconds until the Wait times out + 1, + -- Called if the Wait times out + function() log("Campaign Guide import failed!") end + ) + end + + Wait.time(function() optionPanelApi.loadSettings(importData["options"]) end, 0.5) + + -- destroy Tour Starter token + local tourStarter = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TourStarter") + tourStarter.destruct() + + -- restore PlayArea image + playAreaApi.updateSurface(importData["playmat"]) + + broadcastToAll("Campaign successfully imported!", Color.Green) +end + +-- Creates a campaign token with save data encoded into GM Notes based on the current state of the table +function createCampaignToken(_, playerColor, _) + -- clean up chaos tokens + blessCurseApi.removeAll(playerColor) + chaosBagApi.releaseAllSealedTokens(playerColor) + + -- find active campaign + local campaignBox + for _, obj in ipairs(getObjectsWithTag("CampaignBox")) do + if obj.type == "Bag" and #obj.getObjects() == 0 then + if not campaignBox then + campaignBox = obj + else + broadcastToAll("Multiple empty campaign box detected; delete all but one.", Color.Red) + return + end + end + end + if not campaignBox then + broadcastToAll("Campaign box with all placed objects not found!", Color.Red) + return + end + + local campaignLog = findUniqueObjectWithTag("CampaignLog") + if campaignLog == nil then + broadcastToAll("Campaign log not found!", Color.Red) + return + end + + local traumaValues = { + 0, 0, 0, 0, + 0, 0, 0, 0 + } + local counterData = campaignLog.getVar("ref_buttonData") + if counterData ~= nil then + printToAll("Trauma values found in campaign log!", "Green") + for i = 1, 10, 3 do + traumaValues[1 + (i - 1) / 3] = counterData.counter[i].value + traumaValues[5 + (i - 1) / 3] = counterData.counter[i + 1].value + end + else + printToAll("Trauma values could not be found in campaign log!", "Yellow") + printToAll("Default values for health and sanity loaded.", "Yellow") + end + + local campaignGuide = findUniqueObjectWithTag("CampaignGuide") + if campaignGuide == nil then + broadcastToAll("Campaign guide not found!", Color.Red) + return + end + + local campaignData = { + box = campaignBox.getGUID(), + log = campaignLog.getData(), + bag = chaosBagApi.getChaosBagState(), + trauma = traumaValues, + decks = deckImporterApi.getUiState(), + clueCount = playAreaApi.getInvestigatorCount(), + guide = campaignGuide.Book.getPage(), + options = optionPanelApi.getOptions(), + playmat = playAreaApi.getSurface() + } + campaignTokenData.GMNotes = JSON.encode(campaignData) + campaignTokenData.Nickname = os.date("%b %d ") .. campaignBox.getName() .. " Save" + spawnObjectData({ data = campaignTokenData }) + broadcastToAll("Campaign successfully exported! Save coin object to import on a fresh save", Color.Green) +end + +--------------------------------------------------------- +-- helper functions +--------------------------------------------------------- + +function findUniqueObjectWithTag(tag) + local objects = getObjectsWithTag(tag) + if not objects then return end + + if #objects == 1 then + return objects[1] + else + broadcastToAll("More than 1 " .. tag .. " detected; delete all but one.", Color.Red) + return nil + end +end + +function setTrauma(trauma) + for i = 1, 4 do + playmatApi.updateCounter(COLORS[i], "DamageCounter", trauma[i]) + playmatApi.updateCounter(COLORS[i], "HorrorCounter", trauma[i + 4]) + end +end +end) __bundle_register("arkhamdb/DeckImporterApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local DeckImporterApi = {} - local DECK_IMPORTER_GUID = "a28140" - + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getDeckImporter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "DeckImporter") + end + -- Returns a table with the full state of the UI, including options and deck IDs. -- This can be used to persist via onSave(), or provide values for a load operation -- Table values: @@ -58,7 +462,7 @@ do -- investigators: True if investigator cards should be spawned DeckImporterApi.getUiState = function() local passthroughTable = {} - for k,v in pairs(getObjectFromGUID(DECK_IMPORTER_GUID).call("getUiState")) do + for k,v in pairs(getDeckImporter().call("getUiState")) do passthroughTable[k] = v end return passthroughTable @@ -75,7 +479,7 @@ do -- loadNewest: True if the most upgraded version of the deck should be loaded -- investigators: True if investigator cards should be spawned DeckImporterApi.setUiState = function(uiStateTable) - return getObjectFromGUID(DECK_IMPORTER_GUID).call("setUiState", uiStateTable) + return getDeckImporter().call("setUiState", uiStateTable) end return DeckImporterApi @@ -84,11 +488,15 @@ end) __bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end -- removes all taken tokens and resets the counts BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) + local BlessCurseManager = getManager() Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) @@ -96,30 +504,30 @@ do -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) + getManager().call("sealedToken", { type = type, guid = guid }) end -- updates the internal count (called by cards that seal bless/curse tokens) BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) + getManager().call("releasedToken", { type = type, guid = guid }) end -- broadcasts the current status for bless/curse tokens ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) + getManager().call("broadcastStatus", playerColor) end -- removes all bless / curse tokens from the chaos bag and play ---@param playerColor String Color of the player to show the broadcast to BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) + getManager().call("doRemove", playerColor) end -- adds Wendy's menu to the hovered card (allows sealing of tokens) ---@param color String Color of the player to show the broadcast to BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) end return BlessCurseManagerApi @@ -201,432 +609,265 @@ do return ChaosBagApi end end) -__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local OptionPanelApi = {} + local GUIDReferenceApi = {} - -- loads saved options - ---@param options Table New options table - OptionPanelApi.loadSettings = function(options) - return Global.call("loadSettings", options) + local function getGuidHandler() + return getObjectFromGUID("123456") end - -- returns option panel table - OptionPanelApi.getOptions = function() - return Global.getTable("optionPanel") + -- 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 - return OptionPanelApi + -- 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) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") - end - - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) - end - - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) - end - - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) - end - - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) - end - - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) - end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") - end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("accessories/CampaignImporterExporter") -end) -__bundle_register("accessories/CampaignImporterExporter", function(require, _LOADED, __bundle_register, __bundle_modules) -local blessCurseApi = require("chaosbag/BlessCurseManagerApi") -local chaosBagApi = require("chaosbag/ChaosBagApi") -local deckImporterApi = require("arkhamdb/DeckImporterApi") -local optionPanelApi = require("core/OptionPanelApi") -local playAreaApi = require("core/PlayAreaApi") - -local campaignTokenData = { - GUID = "51b1c9", - Name = "Custom_Model", - Transform = { - posX = -21.25, - posY = 1.68, - posZ = 55.59, - rotX = 0, - rotY = 270, - rotZ = 0, - scaleX = 2, - scaleY = 2, - scaleZ = 2 - }, - Nickname = "Arkham Coin", - Description = "SCED Importer Token", - GMNotes = "", - Tags = { - "ImporterToken" - }, - CustomMesh = { - MeshURL = "http://cloud-3.steamusercontent.com/ugc/943949966265929204/A38BB5D72419E6298385556D931877C0A1A55C17/", - DiffuseURL = "http://cloud-3.steamusercontent.com/ugc/254843371583188147/920981125E37B5CEB6C400E3FD353A2C428DA969/", - NormalURL = "", - ColliderURL = "http://cloud-3.steamusercontent.com/ugc/943949966265929204/A38BB5D72419E6298385556D931877C0A1A55C17/", - Convex = true, - MaterialIndex = 2, - TypeIndex = 0, - CustomShader = { - SpecularColor = { - r = 0.7222887, - g = 0.507659256, - b = 0.339915335 - }, - SpecularIntensity = 0.4, - SpecularSharpness = 7.0, - FresnelStrength = 0.0 - }, - CastShadows = true - } -} - --- counter GUIDS (4x damage and 4x horror) -local DAMAGE_HORROR_GUIDS = { - "eb08d6"; "e64eec"; "1f5a0a"; "591a45"; - "468e88"; "0257d9"; "7b5729"; "beb964"; - } - -local TOUR_GUID = "0e5aa8" -local campaignBoxGUID - -function onLoad(save_state) - campaignBoxGUID = "" - - self.createButton({ - click_function = "findCampaignFromToken", - function_owner = self, - label = "Import", - tooltip = "Load in a campaign save from a token!\n\n(Token can be anywhere on the table, but ensure there is only 1!)", - position = {x=-1, y=0.2, z=0}, - font_size = 400, - width = 1400, - height = 600, - scale = {0.5, 1, 0.5}, - }) - self.createButton({ - click_function = "createCampaignToken", - function_owner = self, - label = "Export", - tooltip = "Create a campaign save token!\n\n(Ensure all chaos tokens have been unsealed!)", - position = {x=1, y=0.2, z=0}, - font_size = 400, - width = 1400, - height = 600, - scale = {0.5, 1, 0.5}, - }) -end - --- The main import functions. Due to timing concerns, has to be split up into several separate methods to allow for Wait conditions - --- Identifies import token, determines campaign box and downloads it (if needed) -function findCampaignFromToken(_, _, _) - local coin = nil - local coinObjects = getObjectsWithTag("ImporterToken") - if #coinObjects == 0 then - broadcastToAll("Could not find importer token", Color.Red) - elseif #coinObjects > 1 then - broadcastToAll("More than 1 importer token found. Please delete all but 1 importer token", Color.Yellow) - else - coin = coinObjects[1] - local importData = JSON.decode(coin.getGMNotes()) - campaignBoxGUID = importData["box"] - local campaignBox = getObjectFromGUID(campaignBoxGUID) - if campaignBox.type == "Generic" then - campaignBox.call("buttonClick_download") - end - Wait.condition( - function() - if #campaignBox.getObjects() > 0 then - placeCampaignFromToken(importData) - else - createCampaignFromToken(importData) - end - end, - function() - local obj = getObjectFromGUID(campaignBoxGUID) - if obj == nil then - return false - else - return obj.type == "Bag" and obj.getLuaScript() ~= "" - end - end, - 2, - function() broadcastToAll("Error loading campaign box") end - ) - end -end - --- After box has been downloaded, places content on table -function placeCampaignFromToken(importData) - getObjectFromGUID(campaignBoxGUID).call("buttonClick_place") - Wait.condition( - function() createCampaignFromToken(importData) end, - function() return findCampaignLog() ~= nil end, - 2, - function() broadcastToAll("Error placing campaign box") end - ) -end - --- After content is placed on table, conducts all the other import operations -function createCampaignFromToken(importData) - findCampaignLog().destruct() - --create campaign log - spawnObjectData({data = importData["log"]}) - --create chaos bag - chaosBagApi.setChaosBagState(importData["bag"]) - --populate trauma values - if importData["trauma"] then - updateCounters(importData["trauma"]) - end - --populate ArkhamDB deck IDs - if importData["decks"] then - deckImporterApi.setUiState(importData["decks"]) - end - --set investigator count - playAreaApi.setInvestigatorCount(importData["clueCount"]) - --set campaign guide page - local guide = findCampaignGuide() - if guide then - Wait.condition( - -- Called after the condition function returns true - function() - log("Campaign Guide import successful!") - end, - -- Condition function that is called continiously until returs true or timeout is reached - function() - guide.Book.setPage(importData["guide"]) - return guide.Book.getPage() == importData["guide"] - end, - -- Amount of time in seconds until the Wait times out - 1, - -- Called if the Wait times out - function() - log("Campaign Guide import failed!") - end - ) - end - Wait.time( - function() optionPanelApi.loadSettings(importData["options"]) end, - 0.5 - ) - getObjectFromGUID(TOUR_GUID).destruct() - playAreaApi.updateSurface(importData["playmat"]) - broadcastToAll("Campaign successfully imported!", Color.Green) -end - - --- Creates a campaign token with save data encoded into GM Notes based on the current state of the table -function createCampaignToken(_, playerColor, _) - -- clean up chaos tokens - blessCurseApi.removeAll(playerColor) - chaosBagApi.releaseAllSealedTokens(playerColor) - - local campaignBoxGUID = "" - -- find active campaign - for _, obj in ipairs(getObjectsWithTag("CampaignBox")) do - if obj.type == "Bag" and #obj.getObjects() == 0 then - if campaignBoxGUID ~= "" then - broadcastToAll("Multiple empty campaign box detected; delete all but one.", Color.Red) - return - end - campaignBoxGUID = obj.getGUID() - end - end - if campaignBoxGUID == "" then - broadcastToAll("Campaign box with all placed objects not found!", Color.Red) - return - end - local campaignLog = findCampaignLog() - if campaignLog == nil then - broadcastToAll("Campaign log not found!", Color.Red) - return - end - local traumaValues = nil - local counterData = campaignLog.getVar("ref_buttonData") - if counterData ~= nil then - traumaValues = {} - printToAll("Trauma values found in campaign log!", "Green") - for i = 1, 10, 3 do - traumaValues[1 + (i - 1) / 3] = counterData.counter[i].value - traumaValues[5 + (i - 1) / 3] = counterData.counter[i + 1].value - end - else - printToAll("Trauma values could not be found in campaign log!", "Yellow") - printToAll("Default values for health and sanity loaded.", "Yellow") - end - local campaignGuide = findCampaignGuide() - if campaignGuide == nil then - broadcastToAll("Campaign guide not found!", Color.Red) - return - end - local campaignGuidePage = campaignGuide.Book.getPage() - local campaignData = { - box = campaignBoxGUID, - log = campaignLog.getData(), - bag = chaosBagApi.getChaosBagState(), - trauma = traumaValues, - decks = deckImporterApi.getUiState(), - clueCount = playAreaApi.getInvestigatorCount(), - guide = campaignGuidePage, - options = optionPanelApi.getOptions(), - playmat = playAreaApi.getSurface() - } - campaignTokenData.GMNotes = JSON.encode(campaignData) - campaignTokenData.Nickname = os.date("%b %d ") .. getObjectFromGUID(campaignBoxGUID).getName() .. " Save" - spawnObjectData({ - data = campaignTokenData, - position = {-21.25, 1.68, 55.59} - }) - broadcastToAll("Campaign successfully exported! Save coin object to import on a fresh save", Color.Green) -end - - --- helper functions - -function findCampaignLog() - local campaignLog = getObjectsWithTag("CampaignLog") - if campaignLog then - if #campaignLog == 1 then - return campaignLog[1] + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - broadcastToAll("More than 1 campaign log detected; delete all but one.", Color.Red) - return nil + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } end - else - return nil end -end -function findCampaignGuide() - local campaignGuide = getObjectsWithTag("CampaignGuide") - if campaignGuide then - if #campaignGuide == 1 then - return campaignGuide[1] - else - broadcastToAll("More than 1 campaign guide detected; delete all but one.", Color.Red) - return nil + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor end - else - return nil + end + return result end -end -function updateCounters(tableOfNewValues) - if tonumber(tableOfNewValues) then - local value = tableOfNewValues - tableOfNewValues = {} - for i = 1, #DAMAGE_HORROR_GUIDS do - table.insert(tableOfNewValues, value) + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") end end - - for i, guid in ipairs(DAMAGE_HORROR_GUIDS) do - local TOKEN = getObjectFromGUID(guid) - if TOKEN ~= nil then - TOKEN.call("updateVal", tableOfNewValues[i]) - else - printToAll(": No. " .. i .. " could not be found.", "Yellow") + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end end end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi end end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Mythos Area 9f334f.ttslua b/unpacked/Custom_Tile Mythos Area 9f334f.ttslua index a7a4b813a..23c2cd01a 100644 --- a/unpacked/Custom_Tile Mythos Area 9f334f.ttslua +++ b/unpacked/Custom_Tile Mythos Area 9f334f.ttslua @@ -41,221 +41,8 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local TokenArrangerApi = {} - - -- 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) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] - 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) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" - - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") - end - - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) - end - - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) - end - - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) - end - - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) - end - - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) - end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") - end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi -end -end) -__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local CHAOS_TOKEN_NAMES = { - ["Elder Sign"] = true, - ["+1"] = true, - ["0"] = true, - ["-1"] = true, - ["-2"] = true, - ["-3"] = true, - ["-4"] = true, - ["-5"] = true, - ["-6"] = true, - ["-7"] = true, - ["-8"] = true, - ["Skull"] = true, - ["Cultist"] = true, - ["Tablet"] = true, - ["Elder Thing"] = true, - ["Auto-fail"] = true, - ["Bless"] = true, - ["Curse"] = true, - ["Frost"] = true - } - - local TokenChecker = {} - - -- returns true if the passed object is a chaos token (by name) - TokenChecker.isChaosToken = function(obj) - if CHAOS_TOKEN_NAMES[obj.getName()] then - return true - else - return false - end - end - - return TokenChecker -end -end) -__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local TokenSpawnTracker = { } - local SPAWN_TRACKER_GUID = "e3ffc9" - - TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("hasSpawnedTokens", cardGuid) - end - - TokenSpawnTracker.markTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("markTokensSpawned", cardGuid) - end - - TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetTokensSpawned", cardGuid) - end - - TokenSpawnTracker.resetAllAssetAndEvents = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllAssetAndEvents") - end - - TokenSpawnTracker.resetAllLocations = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllLocations") - end - - TokenSpawnTracker.resetAll = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAll") - end - - return TokenSpawnTracker -end -end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/MythosArea") -end) __bundle_register("core/MythosArea", function(require, _LOADED, __bundle_register, __bundle_modules) +local guidReferenceApi = require("core/GUIDReferenceApi") local playAreaApi = require("core/PlayAreaApi") local tokenArrangerApi = require("accessories/TokenArrangerApi") local tokenChecker = require("core/token/TokenChecker") @@ -278,11 +65,8 @@ local isReshuffling = false -- scenario metadata local currentScenario, useFrontData, tokenData --- GUID of data helper -local DATA_HELPER_GUID = "708279" - -local TRASHCAN -local TRASHCAN_GUID = "70b9f6" +-- object references +local TRASH, DATA_HELPER -- we use this to turn off collision handling until onLoad() is complete local collisionEnabled = false @@ -294,7 +78,8 @@ function onLoad(saveState) useFrontData = loadedState.useFrontData or true tokenData = loadedState.tokenData or {} end - TRASHCAN = getObjectFromGUID(TRASHCAN_GUID) + TRASH = guidReferenceApi.getObjectByOwnerAndType("Mythos", "Trash") + DATA_HELPER = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") collisionEnabled = true end @@ -386,20 +171,34 @@ end -- encounter card drawing --------------------------------------------------------- +-- gets the encounter deck (for internal functions and Api calls) +function getEncounterDeck() + local search = searchArea(ENCOUNTER_DECK_POS, { 3, 1, 4 }, isCardOrDeck) + + for _, v in ipairs(search) do + local obj = v.hit_object + if obj.type == 'Deck' then + return obj + end + end + + -- if no deck was found, return the first hit (a card) + if #search > 0 then + return search[1].hit_object + end +end + -- 'params' contains the position, rotation and a boolean to force a faceup draw function drawEncounterCard(params) local card - local items = searchArea(ENCOUNTER_DECK_POS, { 3, 1, 4 }, isCardOrDeck) - if #items > 0 then - for _, j in ipairs(items) do - local v = j.hit_object - if v.tag == 'Deck' then - card = v.takeObject({ index = 0 }) - break - end + local deck = getEncounterDeck() + + if deck then + if deck.type == "Deck" then + card = deck.takeObject() + else + card = deck end - -- we didn't find the deck so just pull the first thing we did find - if card == nil then card = items[1].hit_object end actualEncounterCardDraw(card, params) else -- nothing here, time to reshuffle @@ -411,7 +210,7 @@ function actualEncounterCardDraw(card, params) local faceUpRotation = 0 if not params.alwaysFaceUp then local metadata = JSON.decode(card.getGMNotes()) or {} - if metadata.hidden or getObjectFromGUID(DATA_HELPER_GUID).call('checkHiddenCard', card.getName()) then + if metadata.hidden or DATA_HELPER.call('checkHiddenCard', card.getName()) then faceUpRotation = 180 end end @@ -467,7 +266,7 @@ function removeTokensFromObject(object) obj.memo ~= nil and obj.getLock() == false and not tokenChecker.isChaosToken(obj) then - TRASHCAN.putObject(obj) + TRASH.putObject(obj) end end end @@ -501,4 +300,257 @@ function isDeck(x) return x.tag == 'Deck' end function isCardOrDeck(x) return x.tag == 'Card' or x.tag == 'Deck' end end) +__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 Variant 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 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) +__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) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end + + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") + end + + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) + end + + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) + end + + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) + end + + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi +end +end) +__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local CHAOS_TOKEN_NAMES = { + ["Elder Sign"] = true, + ["+1"] = true, + ["0"] = true, + ["-1"] = true, + ["-2"] = true, + ["-3"] = true, + ["-4"] = true, + ["-5"] = true, + ["-6"] = true, + ["-7"] = true, + ["-8"] = true, + ["Skull"] = true, + ["Cultist"] = true, + ["Tablet"] = true, + ["Elder Thing"] = true, + ["Auto-fail"] = true, + ["Bless"] = true, + ["Curse"] = true, + ["Frost"] = true + } + + local TokenChecker = {} + + -- returns true if the passed object is a chaos token (by name) + TokenChecker.isChaosToken = function(obj) + if CHAOS_TOKEN_NAMES[obj.getName()] then + return true + else + return false + end + end + + return TokenChecker +end +end) +__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local TokenSpawnTracker = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getSpawnTracker() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSpawnTracker") + end + + TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) + return getSpawnTracker().call("hasSpawnedTokens", cardGuid) + end + + TokenSpawnTracker.markTokensSpawned = function(cardGuid) + return getSpawnTracker().call("markTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetTokensSpawned = function(cardGuid) + return getSpawnTracker().call("resetTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetAllAssetAndEvents = function() + return getSpawnTracker().call("resetAllAssetAndEvents") + end + + TokenSpawnTracker.resetAllLocations = function() + return getSpawnTracker().call("resetAllLocations") + end + + TokenSpawnTracker.resetAll = function() + return getSpawnTracker().call("resetAll") + end + + return TokenSpawnTracker +end +end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/MythosArea") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Mythos Area 9f334f.yaml b/unpacked/Custom_Tile Mythos Area 9f334f.yaml index 6c0ba63b6..e541aef50 100644 --- a/unpacked/Custom_Tile Mythos Area 9f334f.yaml +++ b/unpacked/Custom_Tile Mythos Area 9f334f.yaml @@ -52,6 +52,8 @@ Name: Custom_Tile Nickname: Mythos Area Snap: true Sticky: true +Tags: +- CleanUpHelper_ignore Tooltip: false Transform: posX: -1.31 diff --git a/unpacked/Custom_Tile Player Cards 2d30ee.ttslua b/unpacked/Custom_Tile Player Cards 2d30ee.ttslua index 36cdfef3c..88cccd8aa 100644 --- a/unpacked/Custom_Tile Player Cards 2d30ee.ttslua +++ b/unpacked/Custom_Tile Player Cards 2d30ee.ttslua @@ -41,247 +41,628 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("playercards/PlayerCardSpawner", function(require, _LOADED, __bundle_register, __bundle_modules) --- Amount to shift for the next card (zShift) or next row of cards (xShift) --- Note that the table rotation is weird, and the X axis is vertical while the --- Z axis is horizontal -local SPREAD_Z_SHIFT = -2.3 -local SPREAD_X_SHIFT = -3.66 +__bundle_register("arkhamdb/ArkhamDb", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local allCardsBagApi = require("playercards/AllCardsBagApi") + local playAreaApi = require("core/PlayAreaApi") + + local ArkhamDb = { } + local internal = { } -Spawner = { } + local RANDOM_WEAKNESS_ID = "01000" --- Spawns a list of cards at the given position/rotation. This will separate cards by size - --- investigator, standard, and mini, spawning them in that order with larger cards on bottom. If --- there are different types, the provided callback will be called once for each type as it spawns --- either a card or deck. --- @param cardList: A list of Player Card data structures (data/metadata) --- @param pos Position table where the cards should be spawned (global) --- @param rot Rotation table for the orientation of the spawned cards (global) --- @param sort Boolean, true if this list of cards should be sorted before spawning --- @param callback Function, callback to be called after the card/deck spawns. -Spawner.spawnCards = function(cardList, pos, rot, sort, callback) - if (sort) then - table.sort(cardList, Spawner.cardComparator) - end + local tabooList = { } + --Forward declaration + ---@type Request + local Request = {} + local configuration - local miniCards = { } - local standardCards = { } - local investigatorCards = { } + -- Sets up the ArkhamDb interface. Should be called from the parent object on load. + ArkhamDb.initialize = function() + configuration = internal.getConfiguration() + Request.start({ configuration.api_uri, configuration.taboo }, function(status) + local json = JSON.decode(internal.fixUtf16String(status.text)) + for _, taboo in pairs(json) do + ---@type + local cards = {} - for _, card in ipairs(cardList) do - if (card.metadata.type == "Investigator") then - table.insert(investigatorCards, card) - elseif (card.metadata.type == "Minicard") then - table.insert(miniCards, card) - else - table.insert(standardCards, card) - end - end - -- Spawn each of the three types individually. Each Y position shift accounts for the thickness - -- of the spawned deck - local position = { x = pos.x, y = pos.y, z = pos.z } - Spawner.spawn(investigatorCards, position, { rot.x, rot.y - 90, rot.z }, callback) + for _, card in pairs(JSON.decode(taboo.cards)) do + cards[card.code] = true + end - position.y = position.y + (#investigatorCards + #standardCards) * 0.07 - Spawner.spawn(standardCards, position, rot, callback) - - position.y = position.y + (#standardCards + #miniCards) * 0.07 - Spawner.spawn(miniCards, position, rot, callback) -end - -Spawner.spawnCardSpread = function(cardList, startPos, maxCols, rot, sort, callback) - if (sort) then - table.sort(cardList, Spawner.cardComparator) - end - - local position = { x = startPos.x, y = startPos.y, z = startPos.z } - -- Special handle the first row if we have less than a full single row, but only if there's a - -- reasonable max column count. Single-row spreads will send a large value for maxCols - if maxCols < 100 and #cardList < maxCols then - position.z = startPos.z + ((maxCols - #cardList) / 2 * SPREAD_Z_SHIFT) - end - local cardsInRow = 0 - local rows = 0 - for _, card in ipairs(cardList) do - Spawner.spawn({ card }, position, rot, callback) - position.z = position.z + SPREAD_Z_SHIFT - cardsInRow = cardsInRow + 1 - if cardsInRow >= maxCols then - rows = rows + 1 - local cardsForRow = #cardList - rows * maxCols - if cardsForRow > maxCols then - cardsForRow = maxCols + tabooList[taboo.id] = { + date = taboo.date_start, + cards = cards + } end - position.z = startPos.z + ((maxCols - cardsForRow) / 2 * SPREAD_Z_SHIFT) - position.x = position.x + SPREAD_X_SHIFT - cardsInRow = 0 + return true, nil + end) + end + + -- Start the deck build process for the given player color and deck ID. This + -- will retrieve the deck from ArkhamDB, and pass to a callback for processing. + ---@param playerColor String. Color name of the player mat to place this deck on (e.g. "Red"). + ---@param deckId String. ArkhamDB deck id to be loaded + ---@param isPrivate Boolean. Whether this deck is published or private on ArkhamDB + ---@param loadNewest Boolean. Whether the newest version of this deck should be loaded + ---@param loadInvestigators Boolean. Whether investigator cards should be loaded as part of this + --- deck + ---@param callback Function. Callback which will be sent the results of this load. Parameters + --- to the callback will be: + --- slots Table. A map of card ID to count in the deck + --- investigatorCode String. ID of the investigator in this deck + --- customizations Table. The decoded table of customization upgrades in this deck + --- playerColor String. Color this deck is being loaded for + ArkhamDb.getDecklist = function( + playerColor, + deckId, + isPrivate, + loadNewest, + loadInvestigators, + callback) + -- Get a simple card to see if the bag indexes are complete. If not, abort + -- the deck load. The called method will handle player notification. + local checkCard = allCardsBagApi.getCardById("01001") + if (checkCard ~= nil and checkCard.data == nil) then + return + end + + local deckUri = { configuration.api_uri, + isPrivate and configuration.private_deck or configuration.public_deck, deckId } + + local deck = Request.start(deckUri, function(status) + if string.find(status.text, "") then + internal.maybePrint("Private deck ID " .. deckId .. " is not shared", playerColor) + return false, table.concat({ "Private deck ", deckId, " is not shared" }) + end + local json = JSON.decode(status.text) + + if not json then + internal.maybePrint("Deck ID " .. deckId .. " not found", playerColor) + return false, "Deck not found!" + end + + return true, json + end) + + deck:with(internal.onDeckResult, playerColor, loadNewest, loadInvestigators, callback) + end + + -- Logs that a card could not be loaded in the mod by printing it to the console in the given + -- color of the player owning the deck. Attempts to look up the name on ArkhamDB for clarity, + -- but prints the card ID if the name cannot be retrieved. + ---@param cardId String. ArkhamDB ID of the card that could not be found + ---@param playerColor String. Color of the player's deck that had the problem + ArkhamDb.logCardNotFound = function(cardId, playerColor) + local request = Request.start({ + configuration.api_uri, + configuration.cards, + cardId + }, + function(result) + local adbCardInfo = JSON.decode(internal.fixUtf16String(result.text)) + local cardName = adbCardInfo.real_name + if (cardName ~= nil) then + if (adbCardInfo.xp ~= nil and adbCardInfo.xp > 0) then + cardName = cardName .. " (" .. adbCardInfo.xp .. ")" + end + internal.maybePrint("Card not found: " .. cardName .. ", ArkhamDB ID " .. cardId, playerColor) + else + internal.maybePrint("Card not found in ArkhamDB, ID " .. cardId, playerColor) + end + end) + end + + -- Callback when the deck information is received from ArkhamDB. Parses the + -- response then applies standard transformations to the deck such as adding + -- random weaknesses and checking for taboos. Once the deck is processed, + -- passes to loadCards to actually spawn the defined deck. + ---@param deck ArkhamImportDeck + ---@param playerColor String Color name of the player mat to place this deck on (e.g. "Red") + ---@param loadNewest Boolean Whether the newest version of this deck should be loaded + ---@param loadInvestigators Boolean Whether investigator cards should be loaded as part of this + --- deck + ---@param callback Function Callback which will be sent the results of this load. Parameters + --- to the callback will be: + --- slots Table. A map of card ID to count in the deck + --- investigatorCode String. ID of the investigator in this deck + --- bondedList A table of cardID keys to meaningless values. Card IDs in this list were + --- added from a parent bonded card. + --- customizations Table. The decoded table of customization upgrades in this deck + --- playerColor String. Color this deck is being loaded for + internal.onDeckResult = function(deck, playerColor, loadNewest, loadInvestigators, callback) + -- Load the next deck in the upgrade path if the option is enabled + if (loadNewest and deck.next_deck ~= nil and deck.next_deck ~= "") then + buildDeck(playerColor, deck.next_deck) + return + end + + internal.maybePrint(table.concat({ "Found decklist: ", deck.name }), playerColor) + + -- Initialize deck slot table and perform common transformations. The order of these should not + -- be changed, as later steps may act on cards added in each. For example, a random weakness or + -- investigator may have bonded cards or taboo entries, and should be present + local slots = deck.slots + internal.maybeDrawRandomWeakness(slots, playerColor) + local loadAltInvestigator = "normal" + if loadInvestigators then + loadAltInvestigator = internal.addInvestigatorCards(deck, slots) + end + + internal.maybeAddSummonedServitor(slots) + internal.maybeAddOnTheMend(slots, playerColor) + internal.maybeAddRealityAcidReference(slots) + local bondList = internal.extractBondedCards(slots) + internal.checkTaboos(deck.taboo_id, slots, playerColor) + internal.maybeAddUpgradeSheets(slots) + + -- get upgrades for customizable cards + local customizations = {} + if deck.meta then + customizations = JSON.decode(deck.meta) + end + + callback(slots, deck.investigator_code, bondList, customizations, playerColor, loadAltInvestigator) + end + + -- Checks to see if the slot list includes the random weakness ID. If it does, + -- removes it from the deck and replaces it with the ID of a random basic weakness provided by the + -- all cards bag + ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number + --- of those cards which will be spawned + ---@param playerColor String Color of the player this deck is being loaded for. Used for broadcast + --- if a weakness is added. + internal.maybeDrawRandomWeakness = function(slots, playerColor) + local randomWeaknessAmount = slots[RANDOM_WEAKNESS_ID] or 0 + slots[RANDOM_WEAKNESS_ID] = nil + + if randomWeaknessAmount ~= 0 then + for i=1, randomWeaknessAmount do + local weaknessId = allCardsBagApi.getRandomWeaknessId() + slots[weaknessId] = (slots[weaknessId] or 0) + 1 + end + internal.maybePrint("Added " .. randomWeaknessAmount .. " random basic weakness(es) to deck", playerColor) end end -end --- Spawn a specific list of cards. This method is for internal use and should not be called --- directly, use spawnCards instead. ----@param cardList: A list of Player Card data structures (data/metadata) ----@param pos table Position where the cards should be spawned (global) ----@param rot table Rotation for the orientation of the spawned cards (global) ----@param callback function callback to be called after the card/deck spawns. -Spawner.spawn = function(cardList, pos, rot, callback) - if (#cardList == 0) then - return - end - -- Spawn a single card directly - if (#cardList == 1) then - spawnObjectData({ - data = cardList[1].data, - position = pos, - rotation = rot, - callback_function = callback, - }) - return - end - -- For multiple cards, construct a deck and spawn that - local deck = Spawner.buildDeckDataTemplate() - -- Decks won't inherently scale to the cards in them. The card list being spawned should be all - -- the same type/size by this point, so use the first card to set the size - deck.Transform = { - scaleX = cardList[1].data.Transform.scaleX, - scaleY = 1, - scaleZ = cardList[1].data.Transform.scaleZ, - } - local sidewaysDeck = true - for _, spawnCard in ipairs(cardList) do - Spawner.addCardToDeck(deck, spawnCard.data) - -- set sidewaysDeck to false if any card is not a sideways card - sidewaysDeck = (sidewaysDeck and spawnCard.data.SidewaysCard) - end - -- set the alt view angle for sideway decks - if sidewaysDeck then - deck.AltLookAngle = { x = 0, y = 180, z = 90 } - end - spawnObjectData({ - data = deck, - position = pos, - rotation = rot, - callback_function = callback, - }) -end + -- Adds both the investigator (XXXXX) and minicard (XXXXX-m) slots with one copy each + ---@param deck Table The processed ArkhamDB deck response + ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the + --- number of those cards which will be spawned + ---@return string: Contains the name of the art that should be loaded ("normal", "promo" or "revised") + internal.addInvestigatorCards = function(deck, slots) + local investigatorId = deck.investigator_code + slots[investigatorId .. "-m"] = 1 + local deckMeta = JSON.decode(deck.meta) + -- handling alternative investigator art and parallel investigators + local loadAltInvestigator = "normal" + if deckMeta ~= nil then + local altFrontId = tonumber(deckMeta.alternate_front) or 0 + local altBackId = tonumber(deckMeta.alternate_back) or 0 + local altArt = { front = "normal", back = "normal" } --- Inserts a card into the given deck. This does three things: --- 1. Add the card's data to ContainedObjects --- 2. Add the card's ID (the TTS CardID, not the Arkham ID) to the deck's --- ID list. Note that the deck's ID list is "DeckIDs" even though it --- contains a list of card Ids --- 3. Extract the card's CustomDeck table and add it to the deck. The deck's --- "CustomDeck" field is a list of all CustomDecks used by cards within the --- deck, keyed by the DeckID and referencing the custom deck table ----@param deck: TTS deck data structure to add to ----@param card: Data for the card to be inserted -Spawner.addCardToDeck = function(deck, cardData) - for customDeckId, customDeckData in pairs(cardData.CustomDeck) do - if (deck.CustomDeck[customDeckId] == nil) then - -- CustomDeck not added to deck yet, add it - deck.CustomDeck[customDeckId] = customDeckData - elseif (deck.CustomDeck[customDeckId].FaceURL == customDeckData.FaceURL) then - -- CustomDeck for this card matches the current one for the deck, do nothing - else - -- CustomDeck data conflict - local newDeckId = nil - for deckId, customDeck in pairs(deck.CustomDeck) do - if (customDeckData.FaceURL == customDeck.FaceURL) then - newDeckId = deckId + -- translating front ID + if altFrontId > 90000 and altFrontId < 90100 then + altArt.front = "parallel" + elseif altFrontId > 01500 and altFrontId < 01506 then + altArt.front = "revised" + elseif altFrontId > 98000 then + altArt.front = "promo" + end + + -- translating back ID + if altBackId > 90000 and altBackId < 90100 then + altArt.back = "parallel" + elseif altBackId > 01500 and altBackId < 01506 then + altArt.back = "revised" + elseif altBackId > 98000 then + altArt.back = "promo" + end + + -- updating investigatorID based on alt investigator selection + -- precedence: parallel > promo > revised + if altArt.front == "parallel" then + if altArt.back == "parallel" then + investigatorId = investigatorId .. "-p" + else + investigatorId = investigatorId .. "-pf" + end + elseif altArt.back == "parallel" then + investigatorId = investigatorId .. "-pb" + elseif altArt.front == "promo" or altArt.back == "promo" then + loadAltInvestigator = "promo" + elseif altArt.front == "revised" or altArt.back == "revised" then + loadAltInvestigator = "revised" + end + end + slots[investigatorId] = 1 + deck.investigator_code = investigatorId + return loadAltInvestigator + end + + -- Process the card list looking for the customizable cards, and add their upgrade sheets if needed + ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number + -- of those cards which will be spawned + internal.maybeAddUpgradeSheets = function(slots) + for cardId, _ in pairs(slots) do + -- upgrade sheets for customizable cards + local upgradesheet = allCardsBagApi.getCardById(cardId .. "-c") + if upgradesheet ~= nil then + slots[cardId .. "-c"] = 1 + end + end + end + + -- Process the card list looking for the Summoned Servitor, and add its minicard to the list if + -- needed + ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number + -- of those cards which will be spawned + internal.maybeAddSummonedServitor = function(slots) + if slots["09080"] ~= nil then + slots["09080-m"] = 1 + end + end + + -- On the Mend should have 1-per-investigator copies set aside, but ArkhamDB always sends 1. Update + -- the count based on the investigator count + ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number + -- of those cards which will be spawned + ---@param playerColor String Color of the player this deck is being loaded for. Used for broadcast if an error occurs + internal.maybeAddOnTheMend = function(slots, playerColor) + if slots["09006"] ~= nil then + local investigatorCount = playAreaApi.getInvestigatorCount() + if investigatorCount ~= nil then + slots["09006"] = investigatorCount + else + internal.maybePrint("Something went wrong with the load, adding 4 copies of On the Mend", playerColor) + slots["09006"] = 4 + end + end + end + + -- Process the card list looking for Reality Acid and adds the reference sheet when needed + ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number + -- of those cards which will be spawned + internal.maybeAddRealityAcidReference = function(slots) + if slots["89004"] ~= nil then + slots["89005"] = 1 + end + end + + -- Process the slot list and looks for any cards which are bonded to those in the deck. Adds those cards to the slot list. + ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number of those cards which will be spawned + internal.extractBondedCards = function(slots) + -- Create a list of bonded cards first so we don't modify slots while iterating + local bondedCards = { } + local bondedList = { } + for cardId, cardCount in pairs(slots) do + local card = allCardsBagApi.getCardById(cardId) + if (card ~= nil and card.metadata.bonded ~= nil) then + for _, bond in ipairs(card.metadata.bonded) do + -- add a bonded card for each copy of the parent card (except for Pendant of the Queen) + if bond.id == "06022" then + bondedCards[bond.id] = bond.count + else + bondedCards[bond.id] = bond.count * cardCount + end + -- We need to know which cards are bonded to determine their position, remember them + bondedList[bond.id] = true + -- Also adding taboo versions of bonded cards to the list + bondedList[bond.id .. "-t"] = true end end - if (newDeckId == nil) then - -- No non-conflicting custom deck for this card, add a new one - newDeckId = Spawner.findNextAvailableId(deck.CustomDeck, "1000") - deck.CustomDeck[newDeckId] = customDeckData + end + -- Add any bonded cards to the main slots list + for bondedId, bondedCount in pairs(bondedCards) do + slots[bondedId] = bondedCount + end + + return bondedList + end + + -- Check the deck for cards on its taboo list. If they're found, replace the entry in the slot with the Taboo id (i.e. "XXXX" becomes "XXXX-t") + ---@param tabooId String The deck's taboo ID, taken from the deck response taboo_id field. May be nil, indicating that no taboo list should be used + ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number of those cards which will be spawned + internal.checkTaboos = function(tabooId, slots, playerColor) + if tabooId then + for cardId, _ in pairs(tabooList[tabooId].cards) do + if slots[cardId] ~= nil then + -- Make sure there's a taboo version of the card before we replace it + -- SCED only maintains the most recent taboo cards. If a deck is using + -- an older taboo list it's possible the card isn't a taboo any more + local tabooCard = allCardsBagApi.getCardById(cardId .. "-t") + if tabooCard == nil then + local basicCard = allCardsBagApi.getCardById(cardId) + internal.maybePrint("Taboo version for " .. basicCard.data.Nickname .. " is not available. Using standard version", playerColor) + else + slots[cardId .. "-t"] = slots[cardId] + slots[cardId] = nil + end + end end - -- Update the card with the new CustomDeck info - cardData.CardID = newDeckId..string.sub(cardData.CardID, 5) - cardData.CustomDeck[customDeckId] = nil - cardData.CustomDeck[newDeckId] = customDeckData - break end end - table.insert(deck.ContainedObjects, cardData) - table.insert(deck.DeckIDs, cardData.CardID) -end --- Create an empty deck data table which can have cards added to it. This --- creates a new table on each call without using metatables or previous --- definitions because we can't be sure that TTS doesn't modify the structure ----@return: Table containing the minimal TTS deck data structure -Spawner.buildDeckDataTemplate = function() - local deck = {} - deck.Name = "Deck" + internal.maybePrint = function(message, playerColor) + if playerColor ~= "None" then + printToAll(message, playerColor) + end + end - -- Card data. DeckIDs and CustomDeck entries will be built from the cards - deck.ContainedObjects = {} - deck.DeckIDs = {} - deck.CustomDeck = {} + -- Gets the ArkhamDB config info from the configuration object. + ---@return Table. Configuration data + internal.getConfiguration = function() + local configuration = getObjectsWithTag("import_configuration_provider")[1]:getTable("configuration") + printPriority = configuration.priority + return configuration + end - -- Transform is required, Position and Rotation will be overridden by the spawn call so can be omitted here - deck.Transform = { - scaleX = 1, - scaleY = 1, - scaleZ = 1, + internal.fixUtf16String = function(str) + return str:gsub("\\u(%w%w%w%w)", function(match) + return string.char(tonumber(match, 16)) + end) + end + + ---@type Request + Request = { + is_done = false, + is_successful = false } - return deck -end + -- Creates a new instance of a Request. Should not be directly called. Instead use Request.start and Request.deferred. + ---@param uri string + ---@param configure fun(request: Request, status: WebRequestStatus) + ---@return Request + function Request:new(uri, configure) + local this = {} --- Returns the first ID which does not exist in the given table, starting at startId and increasing --- @param objectTable Table keyed by strings which are numbers --- @param startId First possible ID. --- @return String ID >= startId -Spawner.findNextAvailableId = function(objectTable, startId) - local id = startId - while (objectTable[id] ~= nil) do - id = tostring(tonumber(id) + 1) - end + setmetatable(this, self) + self.__index = self - return id -end - --- Get the PBCN (Permanent/Bonded/Customizable/Normal) value from the given metadata. ----@return: 1 for Permanent, 2 for Bonded or 4 for Normal. The actual values are --- irrelevant as they provide only grouping and the order between them doesn't matter. -Spawner.getpbcn = function(metadata) - if metadata.permanent then - return 1 - elseif metadata.bonded_to ~= nil then - return 2 - else -- Normal card - return 3 - end -end - --- Comparison function used to sort the cards in a deck. Groups bonded or --- permanent cards first, then sorts within theose types by name/subname. --- Normal cards will sort in standard alphabetical order, while --- permanent/bonded/customizable will be in reverse alphabetical order. --- --- Since cards spawn in the order provided by this comparator, with the first --- cards ending up at the bottom of a pile, this ordering will spawn in reverse --- alphabetical order. This presents the cards in order for non-face-down --- areas, and presents them in order when Searching the face-down deck. -Spawner.cardComparator = function(card1, card2) - local pbcn1 = Spawner.getpbcn(card1.metadata) - local pbcn2 = Spawner.getpbcn(card2.metadata) - if pbcn1 ~= pbcn2 then - return pbcn1 > pbcn2 - end - if pbcn1 == 3 then - if card1.data.Nickname ~= card2.data.Nickname then - return card1.data.Nickname < card2.data.Nickname + if type(uri) == "table" then + uri = table.concat(uri, "/") end - return card1.data.Description < card2.data.Description - else - if card1.data.Nickname ~= card2.data.Nickname then - return card1.data.Nickname > card2.data.Nickname - end - return card1.data.Description > card2.data.Description + + this.uri = uri + + WebRequest.get(uri, function(status) + configure(this, status) + end) + + return this end + + -- Creates a new request. on_success should set the request's is_done, is_successful, and content variables. + -- Deferred should be used when you don't want to set is_done immediately (such as if you want to wait for another request to finish) + ---@param uri string + ---@param on_success fun(request: Request, status: WebRequestStatus, vararg any) + ---@param on_error fun(status: WebRequestStatus)|nil + ---@vararg any[] + ---@return Request + function Request.deferred(uri, on_success, on_error, ...) + local parameters = table.pack(...) + return Request:new(uri, function(request, status) + if (status.is_done) then + if (status.is_error) then + request.error_message = on_error and on_error(status, table.unpack(parameters)) or status.error + request.is_successful = false + request.is_done = true + else + on_success(request, status) + end + end + end) + end + + -- Creates a new request. on_success should return weather the resultant data is as expected, and the processed content of the request. + ---@param uri string + ---@param on_success fun(status: WebRequestStatus, vararg any): boolean, any + ---@param on_error nil|fun(status: WebRequestStatus, vararg any): string + ---@vararg any[] + ---@return Request + function Request.start(uri, on_success, on_error, ...) + local parameters = table.pack(...) + return Request.deferred(uri, function(request, status) + local result, message = on_success(status, table.unpack(parameters)) + if not result then request.error_message = message else request.content = message end + request.is_successful = result + request.is_done = true + end, on_error, table.unpack(parameters)) + end + + ---@param requests Request[] + ---@param on_success fun(content: any[], vararg any[]) + ---@param on_error fun(requests: Request[], vararg any[])|nil + ---@vararg any + function Request.with_all(requests, on_success, on_error, ...) + local parameters = table.pack(...) + + Wait.condition(function() + ---@type any[] + local results = {} + + ---@type Request[] + local errors = {} + + for _, request in ipairs(requests) do + if request.is_successful then + table.insert(results, request.content) + else + table.insert(errors, request) + end + end + + if (#errors <= 0) then + on_success(results, table.unpack(parameters)) + elseif on_error == nil then + for _, request in ipairs(errors) do + internal.maybePrint(table.concat({ "[ERROR]", request.uri, ":", request.error_message })) + end + else + on_error(requests, table.unpack(parameters)) + end + end, function() + for _, request in ipairs(requests) do + if not request.is_done then return false end + end + return true + end) + end + + ---@param callback fun(content: any, vararg any) + function Request:with(callback, ...) + local arguments = table.pack(...) + Wait.condition(function() + if self.is_successful then + callback(self.content, table.unpack(arguments)) + end + end, function() return self.is_done + end) + end + + return ArkhamDb +end +end) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end + + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") + end + + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) + end + + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) + end + + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) + end + + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi +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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) @@ -340,7 +721,7 @@ local START_POSITIONS = { randomWeakness = Vector(0, 2, 1.4), -- Because the card spread is handled by the SpawnBag, we don't know (programatically) where this -- should be placed. If more customizable cards are added it will need to be moved. - summonedServitor = Vector(CARD_WIDTH * -6.5, 2, 1.7), + summonedServitor = Vector(CARD_WIDTH * -7.5, 2, 1.7), } -- Shifts to move rows of cards, and groups of rows, as different groupings are laid out @@ -1046,510 +1427,37 @@ function spawnRandomWeakness() }) end end) -__bundle_register("arkhamdb/ArkhamDb", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local allCardsBagApi = require("playercards/AllCardsBagApi") - local playAreaApi = require("core/PlayAreaApi") - - local ArkhamDb = { } - local internal = { } - - local RANDOM_WEAKNESS_ID = "01000" - - local tabooList = { } - --Forward declaration - ---@type Request - local Request = {} - local configuration - - -- Sets up the ArkhamDb interface. Should be called from the parent object on load. - ArkhamDb.initialize = function() - configuration = internal.getConfiguration() - Request.start({ configuration.api_uri, configuration.taboo }, function(status) - local json = JSON.decode(internal.fixUtf16String(status.text)) - for _, taboo in pairs(json) do - ---@type - local cards = {} - - for _, card in pairs(JSON.decode(taboo.cards)) do - cards[card.code] = true - end - - tabooList[taboo.id] = { - date = taboo.date_start, - cards = cards - } - end - return true, nil - end) - end - - -- Start the deck build process for the given player color and deck ID. This - -- will retrieve the deck from ArkhamDB, and pass to a callback for processing. - ---@param playerColor String. Color name of the player mat to place this deck on (e.g. "Red"). - ---@param deckId String. ArkhamDB deck id to be loaded - ---@param isPrivate Boolean. Whether this deck is published or private on ArkhamDB - ---@param loadNewest Boolean. Whether the newest version of this deck should be loaded - ---@param loadInvestigators Boolean. Whether investigator cards should be loaded as part of this - --- deck - ---@param callback Function. Callback which will be sent the results of this load. Parameters - --- to the callback will be: - --- slots Table. A map of card ID to count in the deck - --- investigatorCode String. ID of the investigator in this deck - --- customizations Table. The decoded table of customization upgrades in this deck - --- playerColor String. Color this deck is being loaded for - ArkhamDb.getDecklist = function( - playerColor, - deckId, - isPrivate, - loadNewest, - loadInvestigators, - callback) - -- Get a simple card to see if the bag indexes are complete. If not, abort - -- the deck load. The called method will handle player notification. - local checkCard = allCardsBagApi.getCardById("01001") - if (checkCard ~= nil and checkCard.data == nil) then - return - end - - local deckUri = { configuration.api_uri, - isPrivate and configuration.private_deck or configuration.public_deck, deckId } - - local deck = Request.start(deckUri, function(status) - if string.find(status.text, "") then - internal.maybePrint("Private deck ID " .. deckId .. " is not shared", playerColor) - return false, table.concat({ "Private deck ", deckId, " is not shared" }) - end - local json = JSON.decode(status.text) - - if not json then - internal.maybePrint("Deck ID " .. deckId .. " not found", playerColor) - return false, "Deck not found!" - end - - return true, json - end) - - deck:with(internal.onDeckResult, playerColor, loadNewest, loadInvestigators, callback) - end - - -- Logs that a card could not be loaded in the mod by printing it to the console in the given - -- color of the player owning the deck. Attempts to look up the name on ArkhamDB for clarity, - -- but prints the card ID if the name cannot be retrieved. - ---@param cardId String. ArkhamDB ID of the card that could not be found - ---@param playerColor String. Color of the player's deck that had the problem - ArkhamDb.logCardNotFound = function(cardId, playerColor) - local request = Request.start({ - configuration.api_uri, - configuration.cards, - cardId - }, - function(result) - local adbCardInfo = JSON.decode(internal.fixUtf16String(result.text)) - local cardName = adbCardInfo.real_name - if (cardName ~= nil) then - if (adbCardInfo.xp ~= nil and adbCardInfo.xp > 0) then - cardName = cardName .. " (" .. adbCardInfo.xp .. ")" - end - internal.maybePrint("Card not found: " .. cardName .. ", ArkhamDB ID " .. cardId, playerColor) - else - internal.maybePrint("Card not found in ArkhamDB, ID " .. cardId, playerColor) - end - end) - end - - -- Callback when the deck information is received from ArkhamDB. Parses the - -- response then applies standard transformations to the deck such as adding - -- random weaknesses and checking for taboos. Once the deck is processed, - -- passes to loadCards to actually spawn the defined deck. - ---@param deck ArkhamImportDeck - ---@param playerColor String Color name of the player mat to place this deck on (e.g. "Red") - ---@param loadNewest Boolean Whether the newest version of this deck should be loaded - ---@param loadInvestigators Boolean Whether investigator cards should be loaded as part of this - --- deck - ---@param callback Function Callback which will be sent the results of this load. Parameters - --- to the callback will be: - --- slots Table. A map of card ID to count in the deck - --- investigatorCode String. ID of the investigator in this deck - --- bondedList A table of cardID keys to meaningless values. Card IDs in this list were - --- added from a parent bonded card. - --- customizations Table. The decoded table of customization upgrades in this deck - --- playerColor String. Color this deck is being loaded for - internal.onDeckResult = function(deck, playerColor, loadNewest, loadInvestigators, callback) - -- Load the next deck in the upgrade path if the option is enabled - if (loadNewest and deck.next_deck ~= nil and deck.next_deck ~= "") then - buildDeck(playerColor, deck.next_deck) - return - end - - internal.maybePrint(table.concat({ "Found decklist: ", deck.name }), playerColor) - - -- Initialize deck slot table and perform common transformations. The order of these should not - -- be changed, as later steps may act on cards added in each. For example, a random weakness or - -- investigator may have bonded cards or taboo entries, and should be present - local slots = deck.slots - internal.maybeDrawRandomWeakness(slots, playerColor) - local loadAltInvestigator = "normal" - if loadInvestigators then - loadAltInvestigator = internal.addInvestigatorCards(deck, slots) - end - - internal.maybeAddSummonedServitor(slots) - internal.maybeAddOnTheMend(slots, playerColor) - internal.maybeAddRealityAcidReference(slots) - local bondList = internal.extractBondedCards(slots) - internal.checkTaboos(deck.taboo_id, slots, playerColor) - internal.maybeAddUpgradeSheets(slots) - - -- get upgrades for customizable cards - local customizations = {} - if deck.meta then - customizations = JSON.decode(deck.meta) - end - - callback(slots, deck.investigator_code, bondList, customizations, playerColor, loadAltInvestigator) - end - - -- Checks to see if the slot list includes the random weakness ID. If it does, - -- removes it from the deck and replaces it with the ID of a random basic weakness provided by the - -- all cards bag - ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number - --- of those cards which will be spawned - ---@param playerColor String Color of the player this deck is being loaded for. Used for broadcast - --- if a weakness is added. - internal.maybeDrawRandomWeakness = function(slots, playerColor) - local randomWeaknessAmount = slots[RANDOM_WEAKNESS_ID] or 0 - slots[RANDOM_WEAKNESS_ID] = nil - - if randomWeaknessAmount ~= 0 then - for i=1, randomWeaknessAmount do - local weaknessId = allCardsBagApi.getRandomWeaknessId() - slots[weaknessId] = (slots[weaknessId] or 0) + 1 - end - internal.maybePrint("Added " .. randomWeaknessAmount .. " random basic weakness(es) to deck", playerColor) - end - end - - -- Adds both the investigator (XXXXX) and minicard (XXXXX-m) slots with one copy each - ---@param deck Table The processed ArkhamDB deck response - ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the - --- number of those cards which will be spawned - ---@return string: Contains the name of the art that should be loaded ("normal", "promo" or "revised") - internal.addInvestigatorCards = function(deck, slots) - local investigatorId = deck.investigator_code - slots[investigatorId .. "-m"] = 1 - local deckMeta = JSON.decode(deck.meta) - -- handling alternative investigator art and parallel investigators - local loadAltInvestigator = "normal" - if deckMeta ~= nil then - local altFrontId = tonumber(deckMeta.alternate_front) or 0 - local altBackId = tonumber(deckMeta.alternate_back) or 0 - local altArt = { front = "normal", back = "normal" } - - -- translating front ID - if altFrontId > 90000 and altFrontId < 90047 then - altArt.front = "parallel" - elseif altFrontId > 01500 and altFrontId < 01506 then - altArt.front = "revised" - elseif altFrontId > 98000 then - altArt.front = "promo" - end - - -- translating back ID - if altBackId > 90000 and altBackId < 90047 then - altArt.back = "parallel" - elseif altBackId > 01500 and altBackId < 01506 then - altArt.back = "revised" - elseif altBackId > 98000 then - altArt.back = "promo" - end - - -- updating investigatorID based on alt investigator selection - -- precedence: parallel > promo > revised - if altArt.front == "parallel" then - if altArt.back == "parallel" then - investigatorId = investigatorId .. "-p" - else - investigatorId = investigatorId .. "-pf" - end - elseif altArt.back == "parallel" then - investigatorId = investigatorId .. "-pb" - elseif altArt.front == "promo" or altArt.back == "promo" then - loadAltInvestigator = "promo" - elseif altArt.front == "revised" or altArt.back == "revised" then - loadAltInvestigator = "revised" - end - end - slots[investigatorId] = 1 - deck.investigator_code = investigatorId - return loadAltInvestigator - end - - -- Process the card list looking for the customizable cards, and add their upgrade sheets if needed - ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number - -- of those cards which will be spawned - internal.maybeAddUpgradeSheets = function(slots) - for cardId, _ in pairs(slots) do - -- upgrade sheets for customizable cards - local upgradesheet = allCardsBagApi.getCardById(cardId .. "-c") - if upgradesheet ~= nil then - slots[cardId .. "-c"] = 1 - end - end - end - - -- Process the card list looking for the Summoned Servitor, and add its minicard to the list if - -- needed - ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number - -- of those cards which will be spawned - internal.maybeAddSummonedServitor = function(slots) - if slots["09080"] ~= nil then - slots["09080-m"] = 1 - end - end - - -- On the Mend should have 1-per-investigator copies set aside, but ArkhamDB always sends 1. Update - -- the count based on the investigator count - ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number - -- of those cards which will be spawned - ---@param playerColor String Color of the player this deck is being loaded for. Used for broadcast if an error occurs - internal.maybeAddOnTheMend = function(slots, playerColor) - if slots["09006"] ~= nil then - local investigatorCount = playAreaApi.getInvestigatorCount() - if investigatorCount ~= nil then - slots["09006"] = investigatorCount - else - internal.maybePrint("Something went wrong with the load, adding 4 copies of On the Mend", playerColor) - slots["09006"] = 4 - end - end - end - - -- Process the card list looking for Reality Acid and adds the reference sheet when needed - ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number - -- of those cards which will be spawned - internal.maybeAddRealityAcidReference = function(slots) - if slots["89004"] ~= nil then - slots["89005"] = 1 - end - end - - -- Process the slot list and looks for any cards which are bonded to those in the deck. Adds those cards to the slot list. - ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number of those cards which will be spawned - internal.extractBondedCards = function(slots) - -- Create a list of bonded cards first so we don't modify slots while iterating - local bondedCards = { } - local bondedList = { } - for cardId, cardCount in pairs(slots) do - local card = allCardsBagApi.getCardById(cardId) - if (card ~= nil and card.metadata.bonded ~= nil) then - for _, bond in ipairs(card.metadata.bonded) do - bondedCards[bond.id] = bond.count - -- We need to know which cards are bonded to determine their position, remember them - bondedList[bond.id] = true - -- Also adding taboo versions of bonded cards to the list - bondedList[bond.id .. "-t"] = true - end - end - end - -- Add any bonded cards to the main slots list - for bondedId, bondedCount in pairs(bondedCards) do - slots[bondedId] = bondedCount - end - - return bondedList - end - - -- Check the deck for cards on its taboo list. If they're found, replace the entry in the slot with the Taboo id (i.e. "XXXX" becomes "XXXX-t") - ---@param tabooId String The deck's taboo ID, taken from the deck response taboo_id field. May be nil, indicating that no taboo list should be used - ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number of those cards which will be spawned - internal.checkTaboos = function(tabooId, slots, playerColor) - if tabooId then - for cardId, _ in pairs(tabooList[tabooId].cards) do - if slots[cardId] ~= nil then - -- Make sure there's a taboo version of the card before we replace it - -- SCED only maintains the most recent taboo cards. If a deck is using - -- an older taboo list it's possible the card isn't a taboo any more - local tabooCard = allCardsBagApi.getCardById(cardId .. "-t") - if tabooCard == nil then - local basicCard = allCardsBagApi.getCardById(cardId) - internal.maybePrint("Taboo version for " .. basicCard.data.Nickname .. " is not available. Using standard version", playerColor) - else - slots[cardId .. "-t"] = slots[cardId] - slots[cardId] = nil - end - end - end - end - end - - internal.maybePrint = function(message, playerColor) - if playerColor ~= "None" then - printToAll(message, playerColor) - end - end - - -- Gets the ArkhamDB config info from the configuration object. - ---@return Table. Configuration data - internal.getConfiguration = function() - local configuration = getObjectsWithTag("import_configuration_provider")[1]:getTable("configuration") - printPriority = configuration.priority - return configuration - end - - internal.fixUtf16String = function(str) - return str:gsub("\\u(%w%w%w%w)", function(match) - return string.char(tonumber(match, 16)) - end) - end - - ---@type Request - Request = { - is_done = false, - is_successful = false - } - - -- Creates a new instance of a Request. Should not be directly called. Instead use Request.start and Request.deferred. - ---@param uri string - ---@param configure fun(request: Request, status: WebRequestStatus) - ---@return Request - function Request:new(uri, configure) - local this = {} - - setmetatable(this, self) - self.__index = self - - if type(uri) == "table" then - uri = table.concat(uri, "/") - end - - this.uri = uri - - WebRequest.get(uri, function(status) - configure(this, status) - end) - - return this - end - - -- Creates a new request. on_success should set the request's is_done, is_successful, and content variables. - -- Deferred should be used when you don't want to set is_done immediately (such as if you want to wait for another request to finish) - ---@param uri string - ---@param on_success fun(request: Request, status: WebRequestStatus, vararg any) - ---@param on_error fun(status: WebRequestStatus)|nil - ---@vararg any[] - ---@return Request - function Request.deferred(uri, on_success, on_error, ...) - local parameters = table.pack(...) - return Request:new(uri, function(request, status) - if (status.is_done) then - if (status.is_error) then - request.error_message = on_error and on_error(status, table.unpack(parameters)) or status.error - request.is_successful = false - request.is_done = true - else - on_success(request, status) - end - end - end) - end - - -- Creates a new request. on_success should return weather the resultant data is as expected, and the processed content of the request. - ---@param uri string - ---@param on_success fun(status: WebRequestStatus, vararg any): boolean, any - ---@param on_error nil|fun(status: WebRequestStatus, vararg any): string - ---@vararg any[] - ---@return Request - function Request.start(uri, on_success, on_error, ...) - local parameters = table.pack(...) - return Request.deferred(uri, function(request, status) - local result, message = on_success(status, table.unpack(parameters)) - if not result then request.error_message = message else request.content = message end - request.is_successful = result - request.is_done = true - end, on_error, table.unpack(parameters)) - end - - ---@param requests Request[] - ---@param on_success fun(content: any[], vararg any[]) - ---@param on_error fun(requests: Request[], vararg any[])|nil - ---@vararg any - function Request.with_all(requests, on_success, on_error, ...) - local parameters = table.pack(...) - - Wait.condition(function() - ---@type any[] - local results = {} - - ---@type Request[] - local errors = {} - - for _, request in ipairs(requests) do - if request.is_successful then - table.insert(results, request.content) - else - table.insert(errors, request) - end - end - - if (#errors <= 0) then - on_success(results, table.unpack(parameters)) - elseif on_error == nil then - for _, request in ipairs(errors) do - internal.maybePrint(table.concat({ "[ERROR]", request.uri, ":", request.error_message })) - end - else - on_error(requests, table.unpack(parameters)) - end - end, function() - for _, request in ipairs(requests) do - if not request.is_done then return false end - end - return true - end) - end - - ---@param callback fun(content: any, vararg any) - function Request:with(callback, ...) - local arguments = table.pack(...) - Wait.condition(function() - if self.is_successful then - callback(self.content, table.unpack(arguments)) - end - end, function() return self.is_done - end) - end - - return ArkhamDb -end -end) __bundle_register("playercards/AllCardsBagApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local AllCardsBagApi = {} - local ALL_CARDS_BAG_GUID = "15bb07" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getAllCardsBag() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "AllCardsBag") + end -- Returns a specific card from the bag, based on ArkhamDB ID - -- @param table: - -- id: String ID of the card to retrieve - -- @return: If the indexes are still being constructed, an empty table is - -- returned. Otherwise, a single table with the following fields - -- cardData: TTS object data, suitable for spawning the card - -- cardMetadata: Table of parsed metadata + ---@param id table String ID of the card to retrieve + ---@return table table + -- If the indexes are still being constructed, an empty table is + -- returned. Otherwise, a single table with the following fields + -- cardData: TTS object data, suitable for spawning the card + -- cardMetadata: Table of parsed metadata AllCardsBagApi.getCardById = function(id) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardById", {id = id}) + return getAllCardsBag().call("getCardById", {id = id}) end -- Gets a random basic weakness from the bag. Once a given ID has been returned -- it will be removed from the list and cannot be selected again until a reload -- occurs or the indexes are rebuilt, which will refresh the list to include all -- weaknesses. - -- @return: String ID of the selected weakness. + ---@return id String ID of the selected weakness. AllCardsBagApi.getRandomWeaknessId = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getRandomWeaknessId") + return getAllCardsBag().call("getRandomWeaknessId") end AllCardsBagApi.isIndexReady = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("isIndexReady") + return getAllCardsBag().call("isIndexReady") end -- Called by Hotfix bags when they load. If we are still loading indexes, then @@ -1558,40 +1466,38 @@ do -- called once indexing is complete it means the hotfix bag has been added -- later, and we should rebuild the index to integrate the hotfix bag. AllCardsBagApi.rebuildIndexForHotfix = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("rebuildIndexForHotfix") + return getAllCardsBag().call("rebuildIndexForHotfix") end -- Searches the bag for cards which match the given name and returns a list. Note that this is -- an O(n) search without index support. It may be slow. - -- @param - -- name String or string fragment to search for names - -- exact Whether the name match should be exact + ---@param name String or string fragment to search for names + ---@param exact Boolean Whether the name match should be exact AllCardsBagApi.getCardsByName = function(name, exact) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardsByName", {name = name, exact = exact}) + return getAllCardsBag().call("getCardsByName", {name = name, exact = exact}) end AllCardsBagApi.isBagPresent = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID) and true + return getAllCardsBag() and true end -- Returns a list of cards from the bag matching a class and level (0 or upgraded) - -- @param - -- class: String class to retrieve ("Guardian", "Seeker", etc) - -- upgraded: true for upgraded cards (Level 1-5), false for Level 0 - -- @return: If the indexes are still being constructed, returns an empty table. + ---@param class String class to retrieve ("Guardian", "Seeker", etc) + ---@param upgraded Boolean true for upgraded cards (Level 1-5), false for Level 0 + ---@return: If the indexes are still being constructed, returns an empty table. -- Otherwise, a list of tables, each with the following fields -- cardData: TTS object data, suitable for spawning the card -- cardMetadata: Table of parsed metadata AllCardsBagApi.getCardsByClassAndLevel = function(class, upgraded) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardsByClassAndLevel", {class = class, upgraded = upgraded}) + return getAllCardsBag().call("getCardsByClassAndLevel", {class = class, upgraded = upgraded}) end AllCardsBagApi.getCardsByCycle = function(cycle) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardsByCycle", cycle) + return getAllCardsBag().call("getCardsByCycle", cycle) end AllCardsBagApi.getUniqueWeaknesses = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getUniqueWeaknesses") + return getAllCardsBag().call("getUniqueWeaknesses") end return AllCardsBagApi @@ -1599,50 +1505,50 @@ end end) __bundle_register("playercards/PlayerCardPanelData", function(require, _LOADED, __bundle_register, __bundle_modules) BONDED_CARD_LIST = { - "05314", -- Soothing Melody - "06277", -- Wish Eater - "06019", -- Bloodlust - "06022", -- Pendant of the Queen - "05317", -- Blood-rite - "06113", -- Essence of the Dream - "06028", -- Stars Are Right - "06025", -- Guardian of the Crystallizer - "06283", -- Unbound Beast - "06032", -- Zeal - "06031", -- Hope - "06033", -- Augur - "06331", -- Dream Parasite - "06015a", -- Dream-Gate - "10045" -- Uncanny Growth + "05314", -- Soothing Melody + "06277", -- Wish Eater + "06019", -- Bloodlust + "06022", -- Pendant of the Queen + "05317", -- Blood-rite + "06113", -- Essence of the Dream + "06028", -- Stars Are Right + "06025", -- Guardian of the Crystallizer + "06283", -- Unbound Beast + "06032", -- Zeal + "06031", -- Hope + "06033", -- Augur + "06331", -- Dream Parasite + "06015a", -- Dream-Gate + "10045" -- Uncanny Growth } UPGRADE_SHEET_LIST = { - "09040-c", -- Alchemical Distillation - "09023-c", -- Custom Modifications - "09059-c", -- Damning Testimony - "09041-c", -- Emperical Hypothesis - "09060-c", -- Friends in Low Places - "09101-c", -- Grizzled - "09061-c", -- Honed Instinct - "09021-c", -- Hunter's Armor - "09119-c", -- Hyperphysical Shotcaster - "09079-c", -- Living Ink - "09100-c", -- Makeshift Trap - "09099-c", -- Pocket Multi Tool - "09081-c", -- Power Word + "09040-c", -- Alchemical Distillation + "09023-c", -- Custom Modifications + "09059-c", -- Damning Testimony + "09041-c", -- Emperical Hypothesis + "09060-c", -- Friends in Low Places + "09101-c", -- Grizzled + "09061-c", -- Honed Instinct + "09021-c", -- Hunter's Armor + "09119-c", -- Hyperphysical Shotcaster + "09079-c", -- Living Ink + "09100-c", -- Makeshift Trap + "09099-c", -- Pocket Multi Tool + "09081-c", -- Power Word "09081-t-c", -- Power Word (Taboo) - "09022-c", -- Runic Axe + "09022-c", -- Runic Axe "09022-t-c", -- Runic Axe (Taboo) - "09080-c", -- Summoned Servitor - "09042-c", -- Raven's Quill + "09080-c", -- Summoned Servitor + "09042-c", -- Raven's Quill } EVOLVED_WEAKNESSES = { - "04039", - "04041", - "04042", - "53014", - "53015", + "04039", + "04041", + "04042", + "53014", + "53015", } ------------------ START INVESTIGATOR DATA DEFINITION ------------------ @@ -1657,7 +1563,8 @@ INVESTIGATOR_GROUPS = { "Nathaniel Cho", "Sister Mary", "Daniela Reyes", - "Carson Sinclair" + "Carson Sinclair", + "Wilson Richards" }, ["Seeker"] = { "Daisy Walker", @@ -1681,7 +1588,8 @@ INVESTIGATOR_GROUPS = { "Winifred Habbamock", "Trish Scarborough", "Monterey Jack", - "Kymani Jones" + "Kymani Jones", + "Alessandra Zorzi" }, ["Mystic"] = { "Agnes Baker", @@ -1789,23 +1697,24 @@ INVESTIGATOR_GROUPS = { "Charlie Kane" }, ["The Feast of Hemlock Vale"] = { - -- placeholder for future addition of investigators once we have their backs - } + "Alessandra Zorzi", + "Wilson Richards" + } } -INVESTIGATORS = { } +INVESTIGATORS = {} --Core-- INVESTIGATORS["Roland Banks"] = { - cards = { "01001", "01001-p", "01001-pf", "01001-pb" }, - minicards = { "01001-m" }, - signatures = { "01006", "01007", "90030", "90031", "90025", "90026", "90027", "90028", "90029", "98005", "98006" }, - starterDeck = "2624931" + cards = { "01001", "01001-p", "01001-pf", "01001-pb" }, + minicards = { "01001-m" }, + signatures = { "01006", "01007", "90030", "90031", "90025", "90026", "90027", "90028", "90029", "98005", "98006" }, + starterDeck = "2624931" } INVESTIGATORS["Daisy Walker"] = { - cards = { "01002", "01002-p", "01002-pf", "01002-pb" }, - minicards = { "01002-m" }, - signatures = { "01008", "01009", "90002", "90003" }, - starterDeck = "2624938" + cards = { "01002", "01002-p", "01002-pf", "01002-pb" }, + minicards = { "01002-m" }, + signatures = { "01008", "01009", "90002", "90003" }, + starterDeck = "2624938" } INVESTIGATORS["\"Skids\" O'Toole"] = { cards = { "01003", "01003-p", "01003-pf", "01003-pb" }, @@ -1820,16 +1729,16 @@ INVESTIGATORS["Agnes Baker"] = { starterDeck = "2624944" } INVESTIGATORS["Wendy Adams"] = { - cards = { "01005", "01005-p", "01005-pf", "01005-pb"}, + cards = { "01005", "01005-p", "01005-pf", "01005-pb" }, minicards = { "01005-m" }, signatures = { "01014", "01015", "01515", "90039", "90040", "90038" }, starterDeck = "2624949" } --Dunwich-- INVESTIGATORS["Zoey Samaras"] = { - cards = { "02001" }, + cards = { "02001", "02001-p", "02001-pf", "02001-pb" }, minicards = { "02001-m" }, - signatures = { "02006", "02007" }, + signatures = { "02006", "02007", "90060", "90061" }, starterDeck = "2624950" } INVESTIGATORS["Rex Murphy"] = { @@ -1845,9 +1754,9 @@ INVESTIGATORS["Jenny Barnes"] = { starterDeck = "2624961" } INVESTIGATORS["Jim Culver"] = { - cards = { "02004" }, + cards = { "02004", "02004-p", "02004-pf", "02004-pb" }, minicards = { "02004-m" }, - signatures = { "02012", "02013" }, + signatures = { "02012", "02013", "90050", "90051", "90052", "90053" }, starterDeck = "2624965" } INVESTIGATORS["\"Ashcan\" Pete"] = { @@ -2058,7 +1967,7 @@ INVESTIGATORS["Silas Marsh"] = { INVESTIGATORS["Daniela Reyes"] = { cards = { "08001" }, minicards = { "08001-m" }, - signatures = {"08002", "08003" }, + signatures = { "08002", "08003" }, starterDeck = "2634588" } INVESTIGATORS["Norman Withers"] = { @@ -2090,7 +1999,7 @@ INVESTIGATORS["Carson Sinclair"] = { cards = { "09001" }, minicards = { "09001-m" }, signatures = { "09002", "09002", "09003" }, - starterDeck = "2634667 " + starterDeck = "2634667" } INVESTIGATORS["Vincent Lee"] = { cards = { "09004" }, @@ -2122,13 +2031,26 @@ INVESTIGATORS["Charlie Kane"] = { signatures = { "09019", "09020" }, starterDeck = "2634706" } +--Hemlock Vale-- +INVESTIGATORS["Alessandra Zorzi"] = { + cards = { "10009" }, + minicards = { "10009-m" }, + signatures = { "10010", "10010", "10010", "10011" }, + starterDeck = "2643931" --winifred deck as placeholder +} +INVESTIGATORS["Wilson Richards"] = { + cards = { "10001" }, + minicards = { "10001-m" }, + signatures = { "10002", "10003" }, + starterDeck = "2634667" --carson deck as placeholder +} +--PnP-- INVESTIGATORS["Subject 5U-21"] = { cards = { "89001" }, minicards = { "89001-m" }, signatures = { "89002", "89003", "89003", "89003", "89004", "89004", "89004", "89005" }, starterDeck = "2624990" -- Lola's deck id until Suzi is on ArkhamDB } - --Promo-- INVESTIGATORS["Gloria Goldberg"] = { cards = { "98019" }, @@ -2385,112 +2307,247 @@ do return SpawnBag end end) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" +__bundle_register("playercards/PlayerCardSpawner", function(require, _LOADED, __bundle_register, __bundle_modules) +-- Amount to shift for the next card (zShift) or next row of cards (xShift) +-- Note that the table rotation is weird, and the X axis is vertical while the +-- Z axis is horizontal +local SPREAD_Z_SHIFT = -2.3 +local SPREAD_X_SHIFT = -3.66 - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") +Spawner = { } + +-- Spawns a list of cards at the given position/rotation. This will separate cards by size - +-- investigator, standard, and mini, spawning them in that order with larger cards on bottom. If +-- there are different types, the provided callback will be called once for each type as it spawns +-- either a card or deck. +-- @param cardList: A list of Player Card data structures (data/metadata) +-- @param pos Position table where the cards should be spawned (global) +-- @param rot Rotation table for the orientation of the spawned cards (global) +-- @param sort Boolean, true if this list of cards should be sorted before spawning +-- @param callback Function, callback to be called after the card/deck spawns. +Spawner.spawnCards = function(cardList, pos, rot, sort, callback) + if (sort) then + table.sort(cardList, Spawner.cardComparator) end - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) + local miniCards = { } + local standardCards = { } + local investigatorCards = { } + + for _, card in ipairs(cardList) do + if (card.metadata.type == "Investigator") then + table.insert(investigatorCards, card) + elseif (card.metadata.type == "Minicard") then + table.insert(miniCards, card) + else + table.insert(standardCards, card) + end + end + -- Spawn each of the three types individually. Each Y position shift accounts for the thickness + -- of the spawned deck + local position = { x = pos.x, y = pos.y, z = pos.z } + Spawner.spawn(investigatorCards, position, { rot.x, rot.y - 90, rot.z }, callback) + + position.y = position.y + (#investigatorCards + #standardCards) * 0.07 + Spawner.spawn(standardCards, position, rot, callback) + + position.y = position.y + (#standardCards + #miniCards) * 0.07 + Spawner.spawn(miniCards, position, rot, callback) +end + +Spawner.spawnCardSpread = function(cardList, startPos, maxCols, rot, sort, callback) + if (sort) then + table.sort(cardList, Spawner.cardComparator) end - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) + local position = { x = startPos.x, y = startPos.y, z = startPos.z } + -- Special handle the first row if we have less than a full single row, but only if there's a + -- reasonable max column count. Single-row spreads will send a large value for maxCols + if maxCols < 100 and #cardList < maxCols then + position.z = startPos.z + ((maxCols - #cardList) / 2 * SPREAD_Z_SHIFT) + end + local cardsInRow = 0 + local rows = 0 + for _, card in ipairs(cardList) do + Spawner.spawn({ card }, position, rot, callback) + position.z = position.z + SPREAD_Z_SHIFT + cardsInRow = cardsInRow + 1 + if cardsInRow >= maxCols then + rows = rows + 1 + local cardsForRow = #cardList - rows * maxCols + if cardsForRow > maxCols then + cardsForRow = maxCols + end + position.z = startPos.z + ((maxCols - cardsForRow) / 2 * SPREAD_Z_SHIFT) + position.x = position.x + SPREAD_X_SHIFT + cardsInRow = 0 + end + end +end + +-- Spawn a specific list of cards. This method is for internal use and should not be called +-- directly, use spawnCards instead. +---@param cardList: A list of Player Card data structures (data/metadata) +---@param pos table Position where the cards should be spawned (global) +---@param rot table Rotation for the orientation of the spawned cards (global) +---@param callback function callback to be called after the card/deck spawns. +Spawner.spawn = function(cardList, pos, rot, callback) + if (#cardList == 0) then + return + end + -- Spawn a single card directly + if (#cardList == 1) then + spawnObjectData({ + data = cardList[1].data, + position = pos, + rotation = rot, + callback_function = callback, + }) + return + end + -- For multiple cards, construct a deck and spawn that + local deck = Spawner.buildDeckDataTemplate() + -- Decks won't inherently scale to the cards in them. The card list being spawned should be all + -- the same type/size by this point, so use the first card to set the size + deck.Transform = { + scaleX = cardList[1].data.Transform.scaleX, + scaleY = 1, + scaleZ = cardList[1].data.Transform.scaleZ, + } + local sidewaysDeck = true + for _, spawnCard in ipairs(cardList) do + Spawner.addCardToDeck(deck, spawnCard.data) + -- set sidewaysDeck to false if any card is not a sideways card + sidewaysDeck = (sidewaysDeck and spawnCard.data.SidewaysCard) + end + -- set the alt view angle for sideway decks + if sidewaysDeck then + deck.AltLookAngle = { x = 0, y = 180, z = 90 } + end + spawnObjectData({ + data = deck, + position = pos, + rotation = rot, + callback_function = callback, + }) +end + +-- Inserts a card into the given deck. This does three things: +-- 1. Add the card's data to ContainedObjects +-- 2. Add the card's ID (the TTS CardID, not the Arkham ID) to the deck's +-- ID list. Note that the deck's ID list is "DeckIDs" even though it +-- contains a list of card Ids +-- 3. Extract the card's CustomDeck table and add it to the deck. The deck's +-- "CustomDeck" field is a list of all CustomDecks used by cards within the +-- deck, keyed by the DeckID and referencing the custom deck table +---@param deck: TTS deck data structure to add to +---@param card: Data for the card to be inserted +Spawner.addCardToDeck = function(deck, cardData) + for customDeckId, customDeckData in pairs(cardData.CustomDeck) do + if (deck.CustomDeck[customDeckId] == nil) then + -- CustomDeck not added to deck yet, add it + deck.CustomDeck[customDeckId] = customDeckData + elseif (deck.CustomDeck[customDeckId].FaceURL == customDeckData.FaceURL) then + -- CustomDeck for this card matches the current one for the deck, do nothing + else + -- CustomDeck data conflict + local newDeckId = nil + for deckId, customDeck in pairs(deck.CustomDeck) do + if (customDeckData.FaceURL == customDeck.FaceURL) then + newDeckId = deckId + end + end + if (newDeckId == nil) then + -- No non-conflicting custom deck for this card, add a new one + newDeckId = Spawner.findNextAvailableId(deck.CustomDeck, "1000") + deck.CustomDeck[newDeckId] = customDeckData + end + -- Update the card with the new CustomDeck info + cardData.CardID = newDeckId..string.sub(cardData.CardID, 5) + cardData.CustomDeck[customDeckId] = nil + cardData.CustomDeck[newDeckId] = customDeckData + break + end + end + table.insert(deck.ContainedObjects, cardData) + table.insert(deck.DeckIDs, cardData.CardID) +end + +-- Create an empty deck data table which can have cards added to it. This +-- creates a new table on each call without using metatables or previous +-- definitions because we can't be sure that TTS doesn't modify the structure +---@return: Table containing the minimal TTS deck data structure +Spawner.buildDeckDataTemplate = function() + local deck = {} + deck.Name = "Deck" + + -- Card data. DeckIDs and CustomDeck entries will be built from the cards + deck.ContainedObjects = {} + deck.DeckIDs = {} + deck.CustomDeck = {} + + -- Transform is required, Position and Rotation will be overridden by the spawn call so can be omitted here + deck.Transform = { + scaleX = 1, + scaleY = 1, + scaleZ = 1, + } + + return deck +end + +-- Returns the first ID which does not exist in the given table, starting at startId and increasing +-- @param objectTable Table keyed by strings which are numbers +-- @param startId First possible ID. +-- @return String ID >= startId +Spawner.findNextAvailableId = function(objectTable, startId) + local id = startId + while (objectTable[id] ~= nil) do + id = tostring(tonumber(id) + 1) end - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) - end + return id +end - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) +-- Get the PBCN (Permanent/Bonded/Customizable/Normal) value from the given metadata. +---@return: 1 for Permanent, 2 for Bonded or 4 for Normal. The actual values are +-- irrelevant as they provide only grouping and the order between them doesn't matter. +Spawner.getpbcn = function(metadata) + if metadata.permanent then + return 1 + elseif metadata.bonded_to ~= nil then + return 2 + else -- Normal card + return 3 end +end - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) +-- Comparison function used to sort the cards in a deck. Groups bonded or +-- permanent cards first, then sorts within theose types by name/subname. +-- Normal cards will sort in standard alphabetical order, while +-- permanent/bonded/customizable will be in reverse alphabetical order. +-- +-- Since cards spawn in the order provided by this comparator, with the first +-- cards ending up at the bottom of a pile, this ordering will spawn in reverse +-- alphabetical order. This presents the cards in order for non-face-down +-- areas, and presents them in order when Searching the face-down deck. +Spawner.cardComparator = function(card1, card2) + local pbcn1 = Spawner.getpbcn(card1.metadata) + local pbcn2 = Spawner.getpbcn(card2.metadata) + if pbcn1 ~= pbcn2 then + return pbcn1 > pbcn2 end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") + if pbcn1 == 3 then + if card1.data.Nickname ~= card2.data.Nickname then + return card1.data.Nickname < card2.data.Nickname + end + return card1.data.Description < card2.data.Description + else + if card1.data.Nickname ~= card2.data.Nickname then + return card1.data.Nickname > card2.data.Nickname + end + return card1.data.Description > card2.data.Description end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi end end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Playermat 1 White 8b081b.ttslua b/unpacked/Custom_Tile Playermat 1 White 8b081b.ttslua index 008f8f747..9114a7254 100644 --- a/unpacked/Custom_Tile Playermat 1 White 8b081b.ttslua +++ b/unpacked/Custom_Tile Playermat 1 White 8b081b.ttslua @@ -41,177 +41,1008 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local OptionPanelApi = {} - - -- loads saved options - ---@param options Table New options table - OptionPanelApi.loadSettings = function(options) - return Global.call("loadSettings", options) - end - - -- returns option panel table - OptionPanelApi.getOptions = function() - return Global.getTable("optionPanel") - end - - return OptionPanelApi -end -end) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" - - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") - end - - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) - end - - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) - end - - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) - end - - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) - end - - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) - end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") - end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi -end -end) -__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local TokenSpawnTracker = { } - local SPAWN_TRACKER_GUID = "e3ffc9" - - TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("hasSpawnedTokens", cardGuid) - end - - TokenSpawnTracker.markTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("markTokensSpawned", cardGuid) - end - - TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetTokensSpawned", cardGuid) - end - - TokenSpawnTracker.resetAllAssetAndEvents = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllAssetAndEvents") - end - - TokenSpawnTracker.resetAllLocations = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllLocations") - end - - TokenSpawnTracker.resetAll = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAll") - end - - return TokenSpawnTracker -end -end) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) ---------------------------------------------------------- --- specific setup (different for each playmat) ---------------------------------------------------------- - -TRASHCAN_GUID = "147e80" -STAT_TRACKER_GUID = "e598c2" -RESOURCE_COUNTER_GUID = "4406f0" -CLUE_COUNTER_GUID = "d86b7c" -CLUE_CLICKER_GUID = "db85d6" - require("playermat/Playmat") end) +__bundle_register("playermat/Playmat", function(require, _LOADED, __bundle_register, __bundle_modules) +local chaosBagApi = require("chaosbag/ChaosBagApi") +local guidReferenceApi = require("core/GUIDReferenceApi") +local mythosAreaApi = require("core/MythosAreaApi") +local navigationOverlayApi = require("core/NavigationOverlayApi") +local tokenChecker = require("core/token/TokenChecker") +local tokenManager = require("core/token/TokenManager") + +-- set true to enable debug logging and show Physics.cast() +local DEBUG = false + +-- we use this to turn off collision handling until onLoad() is complete +local collisionEnabled = false + +-- position offsets relative to mat [x, y, z] +local DRAWN_ENCOUNTER_CARD_OFFSET = {1.365, 0.5, -0.625} +local DRAWN_CHAOS_TOKEN_OFFSET = {-1.55, 0.25, -0.58} + +-- x-Values for discard buttons +local DISCARD_BUTTON_OFFSETS = {-1.365, -0.91, -0.455, 0, 0.455, 0.91} + +local SEARCH_AROUND_SELF_X_BUFFER = 8 + +-- defined areas for "inArea()" and "Physics.cast()" +local MAIN_PLAY_AREA = { + upperLeft = { + x = 1.98, + z = 0.736 + }, + lowerRight = { + x = -0.79, + z = -0.39 + } +} +local INVESTIGATOR_AREA = { + upperLeft = { + x = -1.084, + z = 0.06517 + }, + lowerRight = { + x = -1.258, + z = -0.0805 + } +} +local THREAT_AREA = { + upperLeft = { + x = 1.53, + z = -0.34 + }, + lowerRight = { + x = -1.13, + z = -0.92 + } +} +local DECK_DISCARD_AREA = { + upperLeft = { + x = -1.62, + z = 0.855 + }, + lowerRight = { + x = -2.02, + z = -0.245 + }, + center = { + x = -1.82, + y = 0.5, + z = 0.305 + }, + size = { + x = 0.4, + y = 3, + z = 1.1 + } +} + +-- local position of draw and discard pile +local DRAW_DECK_POSITION = { x = -1.82, y = 0.1, z = 0 } +local DISCARD_PILE_POSITION = { x = -1.82, y = 0.1, z = 0.61 } + +-- global position of encounter discard pile +local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38} + +-- global variable so it can be reset by the Clean Up Helper +activeInvestigatorId = "00000" + +-- table of type-object reference pairs of all owned objects +local ownedObjects = {} +local matColor = self.getMemo() + +-- variable to track the status of the "Show Draw Button" option +local isDrawButtonVisible = false + +-- global variable to report "Dream-Enhancing Serum" status +isDES = false + +function onSave() + return JSON.encode({ + playerColor = playerColor, + activeInvestigatorId = activeInvestigatorId, + isDrawButtonVisible = isDrawButtonVisible + }) +end + +function onLoad(saveState) + self.interactable = DEBUG + + -- get object references to owned objects + ownedObjects = guidReferenceApi.getObjectsByOwner(matColor) + + -- button creation + for i = 1, 6 do + makeDiscardButton(DISCARD_BUTTON_OFFSETS[i], i) + end + + self.createButton({ + click_function = "drawEncounterCard", + function_owner = self, + position = {-1.84, 0, -0.65}, + rotation = {0, 80, 0}, + width = 265, + height = 190 + }) + + self.createButton({ + click_function = "drawChaosTokenButton", + function_owner = self, + position = {1.85, 0, -0.74}, + rotation = {0, -45, 0}, + width = 135, + height = 135 + }) + + self.createButton({ + label = "Upkeep", + click_function = "doUpkeep", + function_owner = self, + position = {1.84, 0.1, -0.44}, + scale = {0.12, 0.12, 0.12}, + width = 800, + height = 280, + font_size = 180 + }) + + -- save state loading + local state = JSON.decode(saveState) + if state ~= nil then + playerColor = state.playerColor + activeInvestigatorId = state.activeInvestigatorId + isDrawButtonVisible = state.isDrawButtonVisible + end + + showDrawButton(isDrawButtonVisible) + collisionEnabled = true + math.randomseed(os.time()) +end + +--------------------------------------------------------- +-- utility functions +--------------------------------------------------------- + +-- searches an area and optionally filters the result +function searchArea(origin, size, filter) + local searchResult = Physics.cast({ + origin = origin, + direction = { 0, 1, 0 }, + orientation = self.getRotation(), + type = 3, + size = size, + max_distance = 0 + }) + + local objList = {} + for _, v in ipairs(searchResult) do + if not filter or (filter and filter(v.hit_object)) then + table.insert(objList, v.hit_object) + end + end + return objList +end + +-- filter functions for searchArea() +function isCard(x) return x.type == 'Card' end +function isDeck(x) return x.type == 'Deck' end +function isCardOrDeck(x) return x.type == 'Card' or x.type == 'Deck' end + +-- finds all objects on the playmat and associated set aside zone. +function searchAroundSelf(filter) + local bounds = self.getBoundsNormalized() + -- Increase the width to cover the set aside zone + bounds.size.x = bounds.size.x + SEARCH_AROUND_SELF_X_BUFFER + bounds.size.y = 1 + -- Since the cast is centered on the position, shift left or right to keep the non-set aside edge + -- of the cast at the edge of the playmat + -- setAsideDirection accounts for the set aside zone being on the left or right, depending on the + -- table position of the playmat + local setAsideDirection = bounds.center.z > 0 and 1 or -1 + local localCenter = self.positionToLocal(bounds.center) + localCenter.x = localCenter.x + setAsideDirection * SEARCH_AROUND_SELF_X_BUFFER / 2 / self.getScale().x + return searchArea(self.positionToWorld(localCenter), bounds.size, filter) +end + +-- searches the area around the draw deck and discard pile +function searchDeckAndDiscardArea(filter) + local pos = self.positionToWorld(DECK_DISCARD_AREA.center) + local scale = self.getScale() + local size = { + x = DECK_DISCARD_AREA.size.x * scale.x, + y = DECK_DISCARD_AREA.size.y, + z = DECK_DISCARD_AREA.size.z * scale.z + } + return searchArea(pos, size, filter) +end + +function doNotReady(card) + return card.getVar("do_not_ready") or false +end + +-- rounds a number to the specified amount of decimal places +---@param num Number Initial value +---@param numDecimalPlaces Number Amount of decimal places +function round(num, numDecimalPlaces) + local mult = 10^(numDecimalPlaces or 0) + return math.floor(num * mult + 0.5) / mult +end + +--------------------------------------------------------- +-- Discard buttons +--------------------------------------------------------- + +-- handles discarding for a list of objects +---@param objList Table List of objects to discard +function discardListOfObjects(objList) + for _, obj in ipairs(objList) do + if isCardOrDeck(obj) then + if obj.hasTag("PlayerCard") then + placeOrMergeIntoDeck(obj, returnGlobalDiscardPosition(), self.getRotation()) + else + placeOrMergeIntoDeck(obj, ENCOUNTER_DISCARD_POSITION, {x = 0, y = -90, z = 0}) + end + -- put chaos tokens back into bag (e.g. Unrelenting) + elseif tokenChecker.isChaosToken(obj) then + local chaosBag = chaosBagApi.findChaosBag() + chaosBag.putObject(obj) + -- don't touch locked objects (like the table etc.) + elseif not obj.getLock() then + ownedObjects.Trash.putObject(obj) + end + end +end + +-- places a card/deck at a position or merges into an existing deck +-- rotation is optional +function placeOrMergeIntoDeck(obj, pos, rot) + if not pos then return end + + local offset = 0.5 + + -- search the new position for existing card/deck + local searchResult = searchArea(pos, { 1, 1, 1 }, isCardOrDeck) + + -- get new position + local newPos + if #searchResult == 1 then + local bounds = searchResult[1].getBounds() + newPos = Vector(pos):setAt("y", bounds.center.y + bounds.size.y / 2 + offset) + else + newPos = Vector(pos) + Vector(0, offset, 0) + end + + -- allow moving the objects smoothly out of the hand + obj.use_hands = false + + if rot then + obj.setRotationSmooth(rot, false, true) + end + obj.setPositionSmooth(newPos, false, true) + + -- continue if the card stops smooth moving + Wait.condition( + function() + obj.use_hands = true + -- this avoids a TTS bug that merges unrelated cards that are not resting + if #searchResult == 1 and searchResult[1] ~= obj then + -- call this with avoiding errors (physics is sometimes too fast so the object doesn't exist for the put) + pcall(function() searchResult[1].putObject(obj) end) + end + end, + function() return not obj.isSmoothMoving() end, 3) +end + +-- build a discard button to discard from searchPosition (number must be unique) +function makeDiscardButton(xValue, number) + local position = { xValue, 0.1, -0.94} + local searchPosition = {-position[1], position[2], position[3] + 0.32} + local handlerName = 'handler' .. number + self.setVar(handlerName, function() + local cardSizeSearch = {2, 1, 3.2} + local globalSearchPosition = self.positionToWorld(searchPosition) + local searchResult = searchArea(globalSearchPosition, cardSizeSearch) + return discardListOfObjects(searchResult) + end) + self.createButton({ + label = "Discard", + click_function = handlerName, + function_owner = self, + position = position, + scale = {0.12, 0.12, 0.12}, + width = 900, + height = 350, + font_size = 220 + }) +end + +--------------------------------------------------------- +-- Upkeep button +--------------------------------------------------------- + +-- calls the Upkeep function with correct parameter +function doUpkeepFromHotkey(color) + doUpkeep(_, color) +end + +function doUpkeep(_, clickedByColor, isRightClick) + -- right-click allow color changing + if isRightClick then + changeColor(clickedByColor) + return + end + + -- send messages to player who clicked button if no seated player found + messageColor = Player[playerColor].seated and playerColor or clickedByColor + + -- unexhaust cards in play zone, flip action tokens and find forcedLearning + local forcedLearning = false + local rot = self.getRotation() + for _, obj in ipairs(searchAroundSelf()) do + if obj.getDescription() == "Action Token" and obj.is_face_down then + obj.flip() + elseif obj.type == "Card" and not inArea(self.positionToLocal(obj.getPosition()), INVESTIGATOR_AREA) then + local cardMetadata = JSON.decode(obj.getGMNotes()) or {} + if not doNotReady(obj) then + local cardRotation = round(obj.getRotation().y, 0) - rot.y + local yRotDiff = 0 + + if cardRotation < 0 then + cardRotation = cardRotation + 360 + end + + -- rotate cards to the next multiple of 90° towards 0° + if cardRotation > 90 and cardRotation <= 180 then + yRotDiff = 90 + elseif cardRotation < 270 and cardRotation > 180 then + yRotDiff = 270 + end + + -- set correct rotation for face-down cards + rot.z = obj.is_face_down and 180 or 0 + obj.setRotation({rot.x, rot.y + yRotDiff, rot.z}) + end + if cardMetadata.id == "08031" then + forcedLearning = true + end + if cardMetadata.uses ~= nil then + tokenManager.maybeReplenishCard(obj, cardMetadata.uses, self) + end + end + end + + -- flip investigator mini-card and summoned servitor mini-card + -- (all characters allowed to account for custom IDs - e.g. 'Z0000' for TTS Zoop generated IDs) + if activeInvestigatorId ~= nil then + local miniId = string.match(activeInvestigatorId, ".....") .. "-m" + for _, obj in ipairs(getObjects()) do + if obj.type == "Card" and obj.is_face_down then + local notes = JSON.decode(obj.getGMNotes()) + if notes ~= nil and notes.type == "Minicard" and (notes.id == miniId or notes.id == "09080-m") then + obj.flip() + end + end + end + end + + -- gain a resource (or two if playing Jenny Barnes) + if string.match(activeInvestigatorId, "%d%d%d%d%d") == "02003" then + updateCounter({type = "ResourceCounter", modifier = 2}) + printToColor("Gaining 2 resources (Jenny)", messageColor) + else + updateCounter({type = "ResourceCounter", modifier = 1}) + end + + -- draw a card (with handling for Patrice and Forced Learning) + if activeInvestigatorId == "06005" then + if forcedLearning then + printToColor("Wow, did you really take 'Versatile' to play Patrice with 'Forced Learning'? Choose which draw replacement effect takes priority and draw cards accordingly.", messageColor) + else + local handSize = #Player[playerColor].getHandObjects() + if handSize < 5 then + local cardsToDraw = 5 - handSize + printToColor("Drawing " .. cardsToDraw .. " cards (Patrice)", messageColor) + drawCardsWithReshuffle(cardsToDraw) + end + end + elseif forcedLearning then + printToColor("Drawing 2 cards, discard 1 (Forced Learning)", messageColor) + drawCardsWithReshuffle(2) + elseif activeInvestigatorId == "89001" then + printToColor("Drawing 2 cards (Subject 5U-21)", messageColor) + drawCardsWithReshuffle(2) + else + drawCardsWithReshuffle(1) + end +end + +-- function for "draw 1 button" (that can be added via option panel) +function doDrawOne(_, color) + -- send messages to player who clicked button if no seated player found + messageColor = Player[playerColor].seated and playerColor or color + drawCardsWithReshuffle(1) +end + +-- draw X cards (shuffle discards if necessary) +function drawCardsWithReshuffle(numCards) + local deckAreaObjects = getDeckAreaObjects() + + -- Norman Withers handling + local harbinger = false + if deckAreaObjects.topCard and deckAreaObjects.topCard.getName() == "The Harbinger" then + harbinger = true + elseif deckAreaObjects.draw and not deckAreaObjects.draw.is_face_down then + local cards = deckAreaObjects.draw.getObjects() + if cards[#cards].name == "The Harbinger" then + harbinger = true + end + end + + if harbinger then + printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) + return + end + + local topCardDetected = false + if deckAreaObjects.topCard ~= nil then + deckAreaObjects.topCard.deal(1, playerColor) + topCardDetected = true + numCards = numCards - 1 + if numCards == 0 then + flipTopCardFromDeck() + return + end + end + + local deckSize = 1 + if deckAreaObjects.draw == nil then + deckSize = 0 + elseif deckAreaObjects.draw.type == "Deck" then + deckSize = #deckAreaObjects.draw.getObjects() + end + + if deckSize >= numCards then + drawCards(numCards) + -- flip top card again for Norman + if topCardDetected and string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then + flipTopCardFromDeck() + end + else + drawCards(deckSize) + if deckAreaObjects.discard ~= nil then + shuffleDiscardIntoDeck() + Wait.time(function() + drawCards(numCards - deckSize) + -- flip top card again for Norman + if topCardDetected and string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then + flipTopCardFromDeck() + end + end, 1) + end + printToColor("Take 1 horror (drawing card from empty deck)", messageColor) + end +end + +-- get the draw deck and discard pile objects and returns the references +function getDeckAreaObjects() + local deckAreaObjects = {} + for _, object in ipairs(searchDeckAndDiscardArea(isCardOrDeck)) do + if self.positionToLocal(object.getPosition()).z > 0.5 then + deckAreaObjects.discard = object + -- Norman Withers handling + elseif object.type == "Card" and not object.is_face_down then + deckAreaObjects.topCard = object + else + deckAreaObjects.draw = object + end + end + return deckAreaObjects +end + +function drawCards(numCards) + local deckAreaObjects = getDeckAreaObjects() + if deckAreaObjects.draw then + deckAreaObjects.draw.deal(numCards, playerColor) + end +end + +function shuffleDiscardIntoDeck() + local deckAreaObjects = getDeckAreaObjects() + if not deckAreaObjects.discard.is_face_down then + deckAreaObjects.discard.flip() + end + deckAreaObjects.discard.shuffle() + deckAreaObjects.discard.setPositionSmooth(self.positionToWorld(DRAW_DECK_POSITION), false, false) +end + +-- utility function for Norman Withers to flip the top card to the revealed side +function flipTopCardFromDeck() + Wait.time(function() + local deckAreaObjects = getDeckAreaObjects() + if deckAreaObjects.topCard then + return + elseif deckAreaObjects.draw then + if deckAreaObjects.draw.type == "Card" then + deckAreaObjects.draw.flip() + else + -- get bounds to know the height of the deck + local bounds = deckAreaObjects.draw.getBounds() + local pos = bounds.center + Vector(0, bounds.size.y / 2 + 0.2, 0) + deckAreaObjects.draw.takeObject({ position = pos, flip = true }) + end + end + end, 0.1) +end + +-- discard a random non-hidden card from hand +function doDiscardOne() + local hand = Player[playerColor].getHandObjects() + if #hand == 0 then + broadcastToAll("Cannot discard from empty hand!", "Red") + else + local choices = {} + for i = 1, #hand do + local notes = JSON.decode(hand[i].getGMNotes()) + if notes ~= nil then + if notes.hidden ~= true then + table.insert(choices, i) + end + else + table.insert(choices, i) + end + end + + if #choices == 0 then + broadcastToAll("Hidden cards can't be randomly discarded.", "Orange") + return + end + + -- get a random non-hidden card (from the "choices" table) + local num = math.random(1, #choices) + placeOrMergeIntoDeck(hand[choices[num]], returnGlobalDiscardPosition(), self.getRotation()) + broadcastToAll(playerColor .. " randomly discarded card " .. choices[num] .. "/" .. #hand .. ".", "White") + end +end + +--------------------------------------------------------- +-- color related functions +--------------------------------------------------------- + +-- changes the player color +function changeColor(clickedByColor) + local colorList = { + "White", + "Brown", + "Red", + "Orange", + "Yellow", + "Green", + "Teal", + "Blue", + "Purple", + "Pink" + } + + -- remove existing colors from the list of choices + for _, existingColor in ipairs(Player.getAvailableColors()) do + for i, newColor in ipairs(colorList) do + if existingColor == newColor then + table.remove(colorList, i) + end + end + end + + -- show the option dialog for color selection to the player that triggered this + Player[clickedByColor].showOptionsDialog("Select a new color:", colorList, _, function(color) + -- update the color of the hand zone + local handZone = ownedObjects.HandZone + handZone.setValue(color) + + -- if the seated player clicked this, reseat him to the new color + if clickedByColor == playerColor then + navigationOverlayApi.copyVisibility(playerColor, color) + Player[playerColor].changeColor(color) + end + + -- update the internal variable + playerColor = color + end) +end + +--------------------------------------------------------- +-- playmat token spawning +--------------------------------------------------------- + +-- Finds all customizable cards in this play area and updates their metadata based on the selections +-- on the matching upgrade sheet. +-- This method is theoretically O(n^2), and should be used sparingly. In practice it will only be +-- called when a checkbox is added or removed in-game (which should be rare), and is bounded by the +-- number of customizable cards in play. +function syncAllCustomizableCards() + for _, card in ipairs(searchAroundSelf(isCard)) do + syncCustomizableMetadata(card) + end +end + +function syncCustomizableMetadata(card) + local cardMetadata = JSON.decode(card.getGMNotes()) or { } + if cardMetadata == nil or cardMetadata.customizations == nil then + return + end + for _, upgradeSheet in ipairs(searchAroundSelf(isCard)) do + local upgradeSheetMetadata = JSON.decode(upgradeSheet.getGMNotes()) or { } + if upgradeSheetMetadata.id == (cardMetadata.id .. "-c") then + for i, customization in ipairs(cardMetadata.customizations) do + if customization.replaces ~= nil and customization.replaces.uses ~= nil then + -- Allowed use of call(), no APIs for individual cards + if upgradeSheet.call("isUpgradeActive", i) then + cardMetadata.uses = customization.replaces.uses + card.setGMNotes(JSON.encode(cardMetadata)) + else + -- TODO: Get the original metadata to restore it... maybe. This should only be + -- necessary in the very unlikely case that a user un-checks a previously-full upgrade + -- row while the card is in play. It will be much easier once the AllPlayerCardsApi is + -- in place, so defer until it is + end + end + end + end + end +end + +function spawnTokensFor(object) + local extraUses = { } + if activeInvestigatorId == "03004" then + extraUses["Charge"] = 1 + end + + tokenManager.spawnForCard(object, extraUses) +end + +function onCollisionEnter(collisionInfo) + local object = collisionInfo.collision_object + + -- only continue if loading is completed + if not collisionEnabled then return end + + -- only continue for cards + if not isCard(object) then return end + + -- detect if "Dream-Enhancing Serum" is placed + if object.getName() == "Dream-Enhancing Serum" then isDES = true end + + maybeUpdateActiveInvestigator(object) + syncCustomizableMetadata(object) + + local localCardPos = self.positionToLocal(object.getPosition()) + if inArea(localCardPos, DECK_DISCARD_AREA) then + tokenManager.resetTokensSpawned(object) + removeTokensFromObject(object) + elseif shouldSpawnTokens(object) then + spawnTokensFor(object) + end +end + +-- detect if "Dream-Enhancing Serum" is removed +function onCollisionExit(collisionInfo) + if collisionInfo.collision_object.getName() == "Dream-Enhancing Serum" then isDES = false end +end + +-- checks if tokens should be spawned for the provided card +function shouldSpawnTokens(card) + if card.is_face_down then + return false + end + + local localCardPos = self.positionToLocal(card.getPosition()) + local metadata = JSON.decode(card.getGMNotes()) + + -- If no metadata we don't know the type, so only spawn in the main area + if metadata == nil then + return inArea(localCardPos, MAIN_PLAY_AREA) + end + + -- Spawn tokens for assets and events on the main area + if inArea(localCardPos, MAIN_PLAY_AREA) + and (metadata.type == "Asset" + or metadata.type == "Event") then + return true + end + + -- Spawn tokens for all encounter types in the threat area + if inArea(localCardPos, THREAT_AREA) + and (metadata.type == "Treachery" + or metadata.type == "Enemy" + or metadata.weakness) then + return true + end + + return false +end + +function onObjectEnterContainer(container, object) + if not isCard(object) then return end + + local localCardPos = self.positionToLocal(object.getPosition()) + if inArea(localCardPos, DECK_DISCARD_AREA) then + tokenManager.resetTokensSpawned(object) + removeTokensFromObject(object) + end +end + +-- removes tokens from the provided card/deck +function removeTokensFromObject(object) + for _, obj in ipairs(searchArea(object.getPosition(), { 3, 1, 4 })) do + if obj.getGUID() ~= "4ee1f2" and -- table + obj ~= self and + obj.type ~= "Deck" and + obj.type ~= "Card" and + obj.memo ~= nil and + obj.getLock() == false and + obj.getDescription() ~= "Action Token" and + not tokenChecker.isChaosToken(obj) then + ownedObjects.Trash.putObject(obj) + end + end +end + +--------------------------------------------------------- +-- investigator ID grabbing and skill tracker +--------------------------------------------------------- + +function maybeUpdateActiveInvestigator(card) + if not inArea(self.positionToLocal(card.getPosition()), INVESTIGATOR_AREA) then return end + + local notes = JSON.decode(card.getGMNotes()) + local class + + if notes ~= nil and notes.type == "Investigator" and notes.id ~= nil then + if notes.id == activeInvestigatorId then return end + class = notes.class + activeInvestigatorId = notes.id + ownedObjects.InvestigatorSkillTracker.call("updateStats", { + notes.willpowerIcons, + notes.intellectIcons, + notes.combatIcons, + notes.agilityIcons + }) + elseif activeInvestigatorId ~= "00000" then + class = "Neutral" + activeInvestigatorId = "00000" + ownedObjects.InvestigatorSkillTracker.call("updateStats", {1, 1, 1, 1}) + else + return + end + + -- change state of action tokens + local search = searchArea(self.positionToWorld({-1.1, 0.05, -0.27}), {4, 1, 1}) + local smallToken = nil + local STATE_TABLE = { + ["Guardian"] = 1, + ["Seeker"] = 2, + ["Rogue"] = 3, + ["Mystic"] = 4, + ["Survivor"] = 5, + ["Neutral"] = 6 + } + + for _, obj in ipairs(search) do + if obj.getDescription() == "Action Token" and obj.getStateId() > 0 then + if obj.getScale().x < 0.4 then + smallToken = obj + else + setObjectState(obj, STATE_TABLE[class]) + end + end + end + + -- update the small token with special action for certain investigators + local SPECIAL_ACTIONS = { + ["04002"] = 8, -- Ursula Downs + ["01002"] = 9, -- Daisy Walker + ["01502"] = 9, -- Daisy Walker + ["01002-pb"] = 9, -- Daisy Walker + ["06003"] = 10, -- Tony Morgan + ["04003"] = 11, -- Finn Edwards + ["08016"] = 14 -- Bob Jenkins + } + + if smallToken ~= nil then + setObjectState(smallToken, SPECIAL_ACTIONS[activeInvestigatorId] or STATE_TABLE[class]) + end +end + +function setObjectState(obj, stateId) + if obj.getStateId() ~= stateId then obj.setState(stateId) end +end + +--------------------------------------------------------- +-- manipulation of owned objects +--------------------------------------------------------- + +-- updates the specific owned counter +---@param param Table Contains the information to update: +--- type: String Counter to target +--- newValue: Number Value to set the counter to +--- modifier: Number If newValue is not provided, the existing value will be adjusted by this modifier +function updateCounter(param) + local counter = ownedObjects[param.type] + if counter ~= nil then + counter.call("updateVal", param.newValue or (counter.getVar("val") + param.modifier)) + else + printToAll(param.type .. " for " .. matColor .. " could not be found.", "Yellow") + end +end + +-- returns the resource counter amount +---@param type String Counter to target +function getCounterValue(type) + return ownedObjects[type].getVar("val") +end + +-- set investigator skill tracker to "1, 1, 1, 1" +function resetSkillTracker() + local obj = ownedObjects.InvestigatorSkillTracker + if obj ~= nil then + obj.call("updateStats", { 1, 1, 1, 1 }) + else + printToAll("Skill tracker for " .. matColor .. " playmat could not be found.", "Yellow") + end +end + +--------------------------------------------------------- +-- calls to 'Global' / functions for calls from outside +--------------------------------------------------------- + +function drawChaosTokenButton(_, _, isRightClick) + chaosBagApi.drawChaosToken(self, DRAWN_CHAOS_TOKEN_OFFSET, isRightClick) +end + +function drawEncounterCard(_, _, isRightClick) + local pos = self.positionToWorld(DRAWN_ENCOUNTER_CARD_OFFSET) + local rotY = self.getRotation().y + mythosAreaApi.drawEncounterCard(pos, rotY, isRightClick) +end + +function returnGlobalDiscardPosition() + return self.positionToWorld(DISCARD_PILE_POSITION) +end + +-- Sets this playermat's draw 1 button to visible +---@param visible Boolean. Whether the draw 1 button should be visible +function showDrawButton(visible) + isDrawButtonVisible = visible + + -- create the "Draw 1" button + if isDrawButtonVisible then + self.createButton({ + label = "Draw 1", + click_function = "doDrawOne", + function_owner = self, + position = { 1.84, 0.1, -0.36 }, + scale = { 0.12, 0.12, 0.12 }, + width = 800, + height = 280, + font_size = 180 + }) + + -- remove the "Draw 1" button + else + local buttons = self.getButtons() + for i = 1, #buttons do + if buttons[i].label == "Draw 1" then + self.removeButton(buttons[i].index) + end + end + end +end + +-- shows / hides a clickable clue counter for this playmat and sets the correct amount of clues +---@param showCounter Boolean Whether the clickable clue counter should be visible +function clickableClues(showCounter) + local clickerPos = ownedObjects.ClickableClueCounter.getPosition() + local clueCount = 0 + + -- move clue counters + local modY = showCounter and 0.525 or -0.525 + ownedObjects.ClickableClueCounter.setPosition(clickerPos + Vector(0, modY, 0)) + + if showCounter then + -- current clue count + clueCount = ownedObjects.ClueCounter.getVar("exposedValue") + + -- remove clues + ownedObjects.ClueCounter.call("removeAllClues", ownedObjects.Trash) + + -- set value for clue clickers + ownedObjects.ClickableClueCounter.call("updateVal", clueCount) + else + -- current clue count + clueCount = ownedObjects.ClickableClueCounter.getVar("val") + + -- spawn clues + local pos = self.positionToWorld({x = -1.12, y = 0.05, z = 0.7}) + for i = 1, clueCount do + pos.y = pos.y + 0.045 * i + tokenManager.spawnToken(pos, "clue", self.getRotation()) + end + end +end + +-- removes all clues (moving tokens to the trash and setting counters to 0) +function removeClues() + ownedObjects.ClueCounter.call("removeAllClues", ownedObjects.Trash) + ownedObjects.ClickableClueCounter.call("updateVal", 0) +end + +-- reports the clue count +---@param useClickableCounters Boolean Controls which type of counter is getting checked +function getClueCount(useClickableCounters) + if useClickableCounters then + return ownedObjects.ClickableClueCounter.getVar("val") + else + return ownedObjects.ClueCounter.getVar("exposedValue") + end +end + +-- Sets this playermat's snap points to limit snapping to matching card types or not. If matchTypes +-- is true, the main card slot snap points will only snap assets, while the investigator area point +-- will only snap Investigators. If matchTypes is false, snap points will be reset to snap all +-- cards. +---@param matchTypes Boolean. Whether snap points should only snap for the matching card types. +function setLimitSnapsByType(matchTypes) + local snaps = self.getSnapPoints() + for i, snap in ipairs(snaps) do + local snapPos = snap.position + if inArea(snapPos, MAIN_PLAY_AREA) then + local snapTags = snaps[i].tags + if matchTypes then + if snapTags == nil then + snaps[i].tags = { "Asset" } + else + table.insert(snaps[i].tags, "Asset") + end + else + snaps[i].tags = nil + end + end + if inArea(snapPos, INVESTIGATOR_AREA) then + local snapTags = snaps[i].tags + if matchTypes then + if snapTags == nil then + snaps[i].tags = { "Investigator" } + else + table.insert(snaps[i].tags, "Investigator") + end + else + snaps[i].tags = nil + end + end + end + self.setSnapPoints(snaps) +end + +-- Simple method to check if the given point is in a specified area. Local use only, +---@param point Vector Point to check, only x and z values are relevant +---@param bounds Table Defined area to see if the point is within. See MAIN_PLAY_AREA for sample +-- bounds definition. +---@return Boolean True if the point is in the area defined by bounds +function inArea(point, bounds) + return (point.x < bounds.upperLeft.x + and point.x > bounds.lowerRight.x + and point.z < bounds.upperLeft.z + and point.z > bounds.lowerRight.z) +end + +-- called by custom data helpers to add player card data +---@param args table Contains only one entry, the GUID of the custom data helper +function updatePlayerCards(args) + local customDataHelper = getObjectFromGUID(args[1]) + local playerCardData = customDataHelper.getTable("PLAYER_CARD_DATA") + tokenManager.addPlayerCardData(playerCardData) +end +end) __bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local ChaosBagApi = {} @@ -288,25 +1119,182 @@ do return ChaosBagApi end end) +__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local MythosAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end + + -- returns the chaos token metadata (if provided through scenario reference card) + MythosAreaApi.returnTokenData = function() + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") + end + + -- draw an encounter card to the requested position/rotation + MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) + getMythosArea().call("drawEncounterCard", { + pos = pos, + rotY = rotY, + alwaysFaceUp = alwaysFaceUp + }) + end + + return MythosAreaApi +end +end) +__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local CHAOS_TOKEN_NAMES = { + ["Elder Sign"] = true, + ["+1"] = true, + ["0"] = true, + ["-1"] = true, + ["-2"] = true, + ["-3"] = true, + ["-4"] = true, + ["-5"] = true, + ["-6"] = true, + ["-7"] = true, + ["-8"] = true, + ["Skull"] = true, + ["Cultist"] = true, + ["Tablet"] = true, + ["Elder Thing"] = true, + ["Auto-fail"] = true, + ["Bless"] = true, + ["Curse"] = true, + ["Frost"] = true + } + + local TokenChecker = {} + + -- returns true if the passed object is a chaos token (by name) + TokenChecker.isChaosToken = function(obj) + if CHAOS_TOKEN_NAMES[obj.getName()] then + return true + else + return false + end + end + + return TokenChecker +end +end) +__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local OptionPanelApi = {} + + -- loads saved options + ---@param options Table New options table + OptionPanelApi.loadSettings = function(options) + return Global.call("loadSettings", options) + end + + -- returns option panel table + OptionPanelApi.getOptions = function() + return Global.getTable("optionPanel") + end + + return OptionPanelApi +end +end) +__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local TokenSpawnTracker = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getSpawnTracker() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSpawnTracker") + end + + TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) + return getSpawnTracker().call("hasSpawnedTokens", cardGuid) + end + + TokenSpawnTracker.markTokensSpawned = function(cardGuid) + return getSpawnTracker().call("markTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetTokensSpawned = function(cardGuid) + return getSpawnTracker().call("resetTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetAllAssetAndEvents = function() + return getSpawnTracker().call("resetAllAssetAndEvents") + end + + TokenSpawnTracker.resetAllLocations = function() + return getSpawnTracker().call("resetAllLocations") + end + + TokenSpawnTracker.resetAll = function() + return getSpawnTracker().call("resetAll") + end + + return TokenSpawnTracker +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) __bundle_register("core/NavigationOverlayApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local NavigationOverlayApi = {} - local HANDLER_GUID = "797ede" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getNOHandler() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "NavigationOverlayHandler") + end -- Copies the visibility for the Navigation overlay ---@param startColor String Color of the player to copy from ---@param targetColor String Color of the targeted player NavigationOverlayApi.copyVisibility = function(startColor, targetColor) - getObjectFromGUID(HANDLER_GUID).call("copyVisibility", { + getNOHandler().call("copyVisibility", { startColor = startColor, targetColor = targetColor }) - end + end -- Changes the Navigation Overlay view ("Full View" --> "Play Areas" --> "Closed" etc.) ---@param playerColor String Color of the player to update the visibility for NavigationOverlayApi.cycleVisibility = function(playerColor) - getObjectFromGUID(HANDLER_GUID).call("cycleVisibility", playerColor) + getNOHandler().call("cycleVisibility", playerColor) end return NavigationOverlayApi @@ -314,6 +1302,7 @@ end end) __bundle_register("core/token/TokenManager", function(require, _LOADED, __bundle_register, __bundle_modules) do + local guidReferenceApi = require("core/GUIDReferenceApi") local optionPanelApi = require("core/OptionPanelApi") local playAreaApi = require("core/PlayAreaApi") local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") @@ -434,15 +1423,10 @@ do ["supply"] = 7 } - -- Source for tokens - local TOKEN_SOURCE_GUID = "124381" - -- Table of data extracted from the token source bag, keyed by the Memo on each token which -- should match the token type keys ("resource", "clue", etc) local tokenTemplates - local DATA_HELPER_GUID = "708279" - local playerCardData local locationData @@ -540,9 +1524,11 @@ do -- Copy the offsets to make sure we don't change the static values local baseOffsets = offsets offsets = { } + + -- get a vector for the shifting (downwards local to the card) + local shiftDownVector = Vector(0, 0, shiftDown):rotateOver("y", card.getRotation().y) for i, baseOffset in ipairs(baseOffsets) do - offsets[i] = baseOffset - offsets[i][3] = offsets[i][3] + shiftDown + offsets[i] = baseOffset + shiftDownVector end end @@ -655,8 +1641,8 @@ do if tokenTemplates ~= nil then return end - tokenTemplates = { } - local tokenSource = getObjectFromGUID(TOKEN_SOURCE_GUID) + tokenTemplates = {} + local tokenSource = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSource") for _, tokenTemplate in ipairs(tokenSource.getData().ContainedObjects) do local tokenName = tokenTemplate.Memo tokenTemplates[tokenName] = tokenTemplate @@ -668,7 +1654,7 @@ do if playerCardData ~= nil then return end - local dataHelper = getObjectFromGUID(DATA_HELPER_GUID) + local dataHelper = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") playerCardData = dataHelper.getTable('PLAYER_CARD_DATA') locationData = dataHelper.getTable('LOCATIONS_DATA') end @@ -683,18 +1669,16 @@ do if uses == nil then return end -- go through tokens to spawn - local type, token, tokenCount + local tokenCount for i, useInfo in ipairs(uses) do - type = useInfo.type - token = useInfo.token - tokenCount = (useInfo.count or 0) - + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() - if extraUses ~= nil and extraUses[type] ~= nil then - tokenCount = tokenCount + extraUses[type] + tokenCount = (useInfo.count or 0) + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() + if extraUses ~= nil and extraUses[useInfo.type] ~= nil then + tokenCount = tokenCount + extraUses[useInfo.type] end -- Shift each spawned group after the first down so they don't pile on each other - TokenManager.spawnTokenGroup(card, token, tokenCount, (i - 1) * 0.8, type) + TokenManager.spawnTokenGroup(card, useInfo.token, tokenCount, (i - 1) * 0.8, useInfo.type) end + tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -718,9 +1702,8 @@ do ---@param playerData Table Player card data structure retrieved from the DataHelper. Should be -- the right data for this card. internal.spawnPlayerCardTokensFromDataHelper = function(card, playerData) - token = playerData.tokenType - tokenCount = playerData.tokenCount - --log("Spawning data helper tokens for "..card.getName()..'['..card.getDescription()..']: '..tokenCount.."x "..token) + local token = playerData.tokenType + local tokenCount = playerData.tokenCount TokenManager.spawnTokenGroup(card, token, tokenCount) tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -753,7 +1736,6 @@ do return 0 end - --log(card.getName() .. ' : ' .. locationData.type .. ' : ' .. locationData.value .. ' : ' .. locationData.clueSide) if ((card.is_face_down and locationData.clueSide == 'back') or (not card.is_face_down and locationData.clueSide == 'front')) then if locationData.type == 'fixed' then @@ -863,1038 +1845,116 @@ do return TokenManager end end) -__bundle_register("playermat/Playmat", function(require, _LOADED, __bundle_register, __bundle_modules) -local chaosBagApi = require("chaosbag/ChaosBagApi") -local mythosAreaApi = require("core/MythosAreaApi") -local navigationOverlayApi = require("core/NavigationOverlayApi") -local tokenChecker = require("core/token/TokenChecker") -local tokenManager = require("core/token/TokenManager") - --- set true to enable debug logging and show Physics.cast() -local DEBUG = false - --- we use this to turn off collision handling until onLoad() is complete -local collisionEnabled = false - --- position offsets relative to mat [x, y, z] -local DRAWN_ENCOUNTER_CARD_OFFSET = {1.365, 0.5, -0.625} -local DRAWN_CHAOS_TOKEN_OFFSET = {-1.55, 0.25, -0.58} - --- x-Values for discard buttons -local DISCARD_BUTTON_OFFSETS = {-1.365, -0.91, -0.455, 0, 0.455, 0.91} - -local SEARCH_AROUND_SELF_X_BUFFER = 8 - --- defined areas for "inArea()" and "Physics.cast()" -local MAIN_PLAY_AREA = { - upperLeft = { - x = 1.98, - z = 0.736 - }, - lowerRight = { - x = -0.79, - z = -0.39 - } -} -local INVESTIGATOR_AREA = { - upperLeft = { - x = -1.084, - z = 0.06517 - }, - lowerRight = { - x = -1.258, - z = -0.0805 - } -} -local THREAT_AREA = { - upperLeft = { - x = 1.53, - z = -0.34 - }, - lowerRight = { - x = -1.13, - z = -0.92 - } -} -local DECK_DISCARD_AREA = { - upperLeft = { - x = -1.62, - z = 0.855 - }, - lowerRight = { - x = -2.02, - z = -0.245 - }, - center = { - x = -1.82, - y = 0.1, - z = 0.305 - }, - size = { - x = 0.4, - y = 0.1, - z = 1.1 - } -} - --- local position of draw and discard pile -local DRAW_DECK_POSITION = { x = -1.82, y = 0, z = 0 } -local DISCARD_PILE_POSITION = { x = -1.82, y = 0, z = 0.61 } - --- global position of encounter discard pile -local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38} - --- global variable so it can be reset by the Clean Up Helper -activeInvestigatorId = "00000" - -local TRASHCAN, STAT_TRACKER, RESOURCE_COUNTER -local isDrawButtonVisible = false - --- global variable to report "Dream-Enhancing Serum" status -isDES = false - -function onSave() - return JSON.encode({ - playerColor = playerColor, - activeInvestigatorId = activeInvestigatorId, - isDrawButtonVisible = isDrawButtonVisible - }) -end - -function onLoad(saveState) - self.interactable = DEBUG - - TRASHCAN = getObjectFromGUID(TRASHCAN_GUID) - STAT_TRACKER = getObjectFromGUID(STAT_TRACKER_GUID) - RESOURCE_COUNTER = getObjectFromGUID(RESOURCE_COUNTER_GUID) - - -- button creation - for i = 1, 6 do - makeDiscardButton(DISCARD_BUTTON_OFFSETS[i], i) - end - - self.createButton({ - click_function = "drawEncounterCard", - function_owner = self, - position = {-1.84, 0, -0.65}, - rotation = {0, 80, 0}, - width = 265, - height = 190 - }) - - self.createButton({ - click_function = "drawChaosTokenButton", - function_owner = self, - position = {1.85, 0, -0.74}, - rotation = {0, -45, 0}, - width = 135, - height = 135 - }) - - self.createButton({ - label = "Upkeep", - click_function = "doUpkeep", - function_owner = self, - position = {1.84, 0.1, -0.44}, - scale = {0.12, 0.12, 0.12}, - width = 800, - height = 280, - font_size = 180 - }) - - -- save state loading - local state = JSON.decode(saveState) - if state ~= nil then - playerColor = state.playerColor - activeInvestigatorId = state.activeInvestigatorId - isDrawButtonVisible = state.isDrawButtonVisible - end - - showDrawButton(isDrawButtonVisible) - - collisionEnabled = true - - math.randomseed(os.time()) -end - ---------------------------------------------------------- --- utility functions ---------------------------------------------------------- - --- searches an area and optionally filters the result -function searchArea(origin, size, filter) - local searchResult = Physics.cast({ - origin = origin, - direction = { 0, 1, 0 }, - orientation = self.getRotation(), - type = 3, - size = size, - max_distance = 1 - }) - - local objList = {} - for _, v in ipairs(searchResult) do - if not filter or (filter and filter(v.hit_object)) then - table.insert(objList, v.hit_object) - end - end - return objList -end - --- filter functions for searchArea() -function isCard(x) return x.type == 'Card' end -function isDeck(x) return x.type == 'Deck' end -function isCardOrDeck(x) return x.type == 'Card' or x.type == 'Deck' end - --- Finds all objects on the playmat and associated set aside zone. -function searchAroundSelf(filter) - local bounds = self.getBoundsNormalized() - -- Increase the width to cover the set aside zone - bounds.size.x = bounds.size.x + SEARCH_AROUND_SELF_X_BUFFER - -- Since the cast is centered on the position, shift left or right to keep the non-set aside edge - -- of the cast at the edge of the playmat - -- setAsideDirection accounts for the set aside zone being on the left or right, depending on the - -- table position of the playmat - local setAsideDirection = bounds.center.z > 0 and 1 or -1 - local localCenter = self.positionToLocal(bounds.center) - localCenter.x = localCenter.x + setAsideDirection * SEARCH_AROUND_SELF_X_BUFFER / 2 / self.getScale().x - return searchArea(self.positionToWorld(localCenter), bounds.size, filter) -end - --- searches the area around the draw deck and discard pile -function searchDeckAndDiscardArea(filter) - local pos = self.positionToWorld(DECK_DISCARD_AREA.center) - local scale = self.getScale() - local size = { - x = DECK_DISCARD_AREA.size.x * scale.x, - y = DECK_DISCARD_AREA.size.y, - z = DECK_DISCARD_AREA.size.z * scale.z - } - return searchArea(pos, size, filter) -end - -function doNotReady(card) - return card.getVar("do_not_ready") or false -end - ---------------------------------------------------------- --- Discard buttons ---------------------------------------------------------- - --- builds a function that discards things in searchPosition --- stuff on the card/deck will be put into the local trashcan -function makeDiscardHandlerFor(searchPosition) - return function () - local origin = self.positionToWorld(searchPosition) - for _, obj in ipairs(searchArea(origin, {2, 1, 3.2})) do - if isCardOrDeck(obj) then - if obj.hasTag("PlayerCard") then - placeOrMergeIntoDeck(obj, returnGlobalDiscardPosition(), self.getRotation()) - else - placeOrMergeIntoDeck(obj, ENCOUNTER_DISCARD_POSITION, {x = 0, y = -90, z = 0}) - end - -- put chaos tokens back into bag (e.g. Unrelenting) - elseif tokenChecker.isChaosToken(obj) then - local chaosBag = chaosBagApi.findChaosBag() - chaosBag.putObject(obj) - -- don't touch the table or this playmat itself - elseif obj.guid ~= "4ee1f2" and obj ~= self then - TRASHCAN.putObject(obj) - end - end - end -end - --- places a card/deck at a position or merges into an existing deck --- rotation is optional -function placeOrMergeIntoDeck(obj, pos, rot) - if not pos then return end - - local offset = 0.5 - local deck, card, newPos - - -- search the new position for existing card/deck - local searchResult = searchArea(pos, { 1, 1, 1 }, isCardOrDeck) - if #searchResult == 1 then - local match = searchResult[1] - if match.type == 'Card' then - card = match - elseif match.type == 'Deck' then - deck = match - end - end - - -- update vertical component of new position - if card or deck then - local bounds = searchResult[1].getBounds() - newPos = Vector(pos):setAt("y", bounds.center.y + bounds.size.y / 2 + offset) - else - newPos = Vector(pos) + Vector(0, offset, 0) - end - - -- actual movement of the object - if rot then - obj.setRotationSmooth(rot, false, true) - end - obj.setPositionSmooth(newPos, false, true) - - -- this avoids a TTS bug that merges unrelated cards that are not resting - if deck then - Wait.time(function() deck.putObject(obj) end, 0.3) - elseif card then - Wait.time(function() obj.setPosition(newPos) end, 0.3) - end -end - --- build a discard button to discard from searchPosition (number must be unique) -function makeDiscardButton(xValue, number) - local position = { xValue, 0.1, -0.94} - local searchPosition = {-position[1], position[2], position[3] + 0.32} - local handler = makeDiscardHandlerFor(searchPosition) - local handlerName = 'handler' .. number - self.setVar(handlerName, handler) - self.createButton({ - label = "Discard", - click_function = handlerName, - function_owner = self, - position = position, - scale = {0.12, 0.12, 0.12}, - width = 900, - height = 350, - font_size = 220 - }) -end - ---------------------------------------------------------- --- Upkeep button ---------------------------------------------------------- - --- calls the Upkeep function with correct parameter -function doUpkeepFromHotkey(color) - doUpkeep(_, color) -end - -function doUpkeep(_, clickedByColor, isRightClick) - -- right-click allow color changing - if isRightClick then - changeColor(clickedByColor) - return - end - - -- send messages to player who clicked button if no seated player found - messageColor = Player[playerColor].seated and playerColor or clickedByColor - - -- unexhaust cards in play zone, flip action tokens and find forcedLearning - local forcedLearning = false - local rot = self.getRotation() - for _, obj in ipairs(searchAroundSelf()) do - if obj.getDescription() == "Action Token" and obj.is_face_down then - obj.flip() - elseif obj.type == "Card" and not inArea(self.positionToLocal(obj.getPosition()), INVESTIGATOR_AREA) then - local cardMetadata = JSON.decode(obj.getGMNotes()) or {} - if not doNotReady(obj) then - local cardRotation = round(obj.getRotation().y, 0) - rot.y - local yRotDiff = 0 - - if cardRotation < 0 then - cardRotation = cardRotation + 360 - end - - -- rotate cards to the next multiple of 90° towards 0° - if cardRotation > 90 and cardRotation <= 180 then - yRotDiff = 90 - elseif cardRotation < 270 and cardRotation > 180 then - yRotDiff = 270 - end - - -- set correct rotation for face-down cards - rot.z = obj.is_face_down and 180 or 0 - obj.setRotation({rot.x, rot.y + yRotDiff, rot.z}) - end - if cardMetadata.id == "08031" then - forcedLearning = true - end - if cardMetadata.uses ~= nil then - tokenManager.maybeReplenishCard(obj, cardMetadata.uses, self) - end - end - end - - -- flip investigator mini-card and summoned servitor mini-card - -- (all characters allowed to account for custom IDs - e.g. 'Z0000' for TTS Zoop generated IDs) - if activeInvestigatorId ~= nil then - local miniId = string.match(activeInvestigatorId, ".....") .. "-m" - for _, obj in ipairs(getObjects()) do - if obj.type == "Card" and obj.is_face_down then - local notes = JSON.decode(obj.getGMNotes()) - if notes ~= nil and notes.type == "Minicard" and (notes.id == miniId or notes.id == "09080-m") then - obj.flip() - end - end - end - end - - -- gain a resource (or two if playing Jenny Barnes) - if string.match(activeInvestigatorId, "%d%d%d%d%d") == "02003" then - gainResources(2) - printToColor("Gaining 2 resources (Jenny)", messageColor) - else - gainResources(1) - end - - -- draw a card (with handling for Patrice and Forced Learning) - if activeInvestigatorId == "06005" then - if forcedLearning then - printToColor("Wow, did you really take 'Versatile' to play Patrice with 'Forced Learning'? Choose which draw replacement effect takes priority and draw cards accordingly.", messageColor) - else - local handSize = #Player[playerColor].getHandObjects() - if handSize < 5 then - local cardsToDraw = 5 - handSize - printToColor("Drawing " .. cardsToDraw .. " cards (Patrice)", messageColor) - drawCardsWithReshuffle(cardsToDraw) - end - end - elseif forcedLearning then - printToColor("Drawing 2 cards, discard 1 (Forced Learning)", messageColor) - drawCardsWithReshuffle(2) - elseif activeInvestigatorId == "89001" then - printToColor("Drawing 2 cards (Subject 5U-21)", messageColor) - drawCardsWithReshuffle(2) - else - drawCardsWithReshuffle(1) - end -end - --- adds the specified amount of resources to the resource counter -function gainResources(amount) - local count = RESOURCE_COUNTER.getVar("val") - local add = tonumber(amount) or 0 - RESOURCE_COUNTER.call("updateVal", count + add) -end - --- returns the resource counter amount -function getResourceCount() - return RESOURCE_COUNTER.getVar("val") -end - --- function for "draw 1 button" (that can be added via option panel) -function doDrawOne(_, color) - -- send messages to player who clicked button if no seated player found - messageColor = Player[playerColor].seated and playerColor or color - drawCardsWithReshuffle(1) -end - --- draw X cards (shuffle discards if necessary) -function drawCardsWithReshuffle(numCards) - getDrawDiscardDecks() - - -- Norman Withers handling - if string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then - local harbinger = false - if topCard ~= nil and topCard.getName() == "The Harbinger" then harbinger = true - elseif drawDeck ~= nil and not drawDeck.is_face_down then - local cards = drawDeck.getObjects() - if cards[#cards].name == "The Harbinger" then harbinger = true end - end - - if harbinger then - printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) - return - end - - if topCard ~= nil then - topCard.deal(numCards, playerColor) - numCards = numCards - 1 - if numCards == 0 then return end - end - end - - local deckSize = 1 - if drawDeck == nil then - deckSize = 0 - elseif drawDeck.tag == "Deck" then - deckSize = #drawDeck.getObjects() - end - - if deckSize >= numCards then - drawCards(numCards) - return - end - - drawCards(deckSize) - if discardPile ~= nil then - shuffleDiscardIntoDeck() - Wait.time(|| drawCards(numCards - deckSize), 1) - end - printToColor("Take 1 horror (drawing card from empty deck)", messageColor) -end - --- get the draw deck and discard pile objects -function getDrawDiscardDecks() - drawDeck = nil - discardPile = nil - topCard = nil - - for _, object in ipairs(searchDeckAndDiscardArea(isCardOrDeck)) do - if self.positionToLocal(object.getPosition()).z > 0.5 then - discardPile = object - -- Norman Withers handling - elseif string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" and not object.is_face_down then - topCard = object - else - drawDeck = object - end - end -end - -function drawCards(numCards) - if drawDeck == nil then return end - drawDeck.deal(numCards, playerColor) -end - -function shuffleDiscardIntoDeck() - if not discardPile.is_face_down then discardPile.flip() end - discardPile.shuffle() - discardPile.setPositionSmooth(self.positionToWorld(DRAW_DECK_POSITION), false, false) - drawDeck = discardPile - discardPile = nil -end - --- discard a random non-hidden card from hand -function doDiscardOne() - local hand = Player[playerColor].getHandObjects() - if #hand == 0 then - broadcastToAll("Cannot discard from empty hand!", "Red") - else - local choices = {} - for i = 1, #hand do - local notes = JSON.decode(hand[i].getGMNotes()) - if notes ~= nil then - if notes.hidden ~= true then - table.insert(choices, i) - end - else - table.insert(choices, i) - end - end - - if #choices == 0 then - broadcastToAll("Hidden cards can't be randomly discarded.", "Orange") - return - end - - -- get a random non-hidden card (from the "choices" table) - local num = math.random(1, #choices) - placeOrMergeIntoDeck(hand[choices[num]], returnGlobalDiscardPosition(), self.getRotation()) - broadcastToAll(playerColor .. " randomly discarded card " .. choices[num] .. "/" .. #hand .. ".", "White") - end -end - ---------------------------------------------------------- --- color related functions ---------------------------------------------------------- - --- changes the player color -function changeColor(clickedByColor) - local colorList = { - "White", - "Brown", - "Red", - "Orange", - "Yellow", - "Green", - "Teal", - "Blue", - "Purple", - "Pink" - } - - -- remove existing colors from the list of choices - for _, existingColor in ipairs(Player.getAvailableColors()) do - for i, newColor in ipairs(colorList) do - if existingColor == newColor then - table.remove(colorList, i) - end - end - end - - -- show the option dialog for color selection to the player that triggered this - Player[clickedByColor].showOptionsDialog("Select a new color:", colorList, _, function(color) - local HAND_ZONE_GUIDS = { - "a70eee", -- White - "5fe087", -- Orange - "0285cc", -- Green - "be2f17" -- Red - } - local index - local startPos = self.getPosition() - - -- get respective hand zone by position - if startPos.x < -42 then - if startPos.z > 0 then - index = 1 - else - index = 2 - end - else - if startPos.z > 0 then - index = 3 - else - index = 4 - end - end - - -- update the color of the hand zone - local handZone = getObjectFromGUID(HAND_ZONE_GUIDS[index]) - handZone.setValue(color) - - -- if the seated player clicked this, reseat him to the new color - if clickedByColor == playerColor then - navigationOverlayApi.copyVisibility(playerColor, color) - Player[playerColor].changeColor(color) - end - - -- update the internal variable - playerColor = color - end) -end - ---------------------------------------------------------- --- playmat token spawning ---------------------------------------------------------- - --- Finds all customizable cards in this play area and updates their metadata based on the selections --- on the matching upgrade sheet. --- This method is theoretically O(n^2), and should be used sparingly. In practice it will only be --- called when a checkbox is added or removed in-game (which should be rare), and is bounded by the --- number of customizable cards in play. -function syncAllCustomizableCards() - for _, card in ipairs(searchAroundSelf(isCard)) do - syncCustomizableMetadata(card) - end -end - -function syncCustomizableMetadata(card) - local cardMetadata = JSON.decode(card.getGMNotes()) or { } - if cardMetadata == nil or cardMetadata.customizations == nil then - return - end - for _, upgradeSheet in ipairs(searchAroundSelf(isCard)) do - local upgradeSheetMetadata = JSON.decode(upgradeSheet.getGMNotes()) or { } - if upgradeSheetMetadata.id == (cardMetadata.id .. "-c") then - for i, customization in ipairs(cardMetadata.customizations) do - if customization.replaces ~= nil and customization.replaces.uses ~= nil then - -- Allowed use of call(), no APIs for individual cards - if upgradeSheet.call("isUpgradeActive", i) then - cardMetadata.uses = customization.replaces.uses - card.setGMNotes(JSON.encode(cardMetadata)) - else - -- TODO: Get the original metadata to restore it... maybe. This should only be - -- necessary in the very unlikely case that a user un-checks a previously-full upgrade - -- row while the card is in play. It will be much easier once the AllPlayerCardsApi is - -- in place, so defer until it is - end - end - end - end - end -end - -function spawnTokensFor(object) - local extraUses = { } - if activeInvestigatorId == "03004" then - extraUses["Charge"] = 1 - end - - tokenManager.spawnForCard(object, extraUses) -end - -function onCollisionEnter(collision_info) - local object = collision_info.collision_object - - -- detect if "Dream-Enhancing Serum" is placed - if object.getName() == "Dream-Enhancing Serum" then isDES = true end - - -- only continue if loading is completed - if not collisionEnabled then return end - - -- only continue for cards - if object.type ~= "Card" then return end - - maybeUpdateActiveInvestigator(object) - syncCustomizableMetadata(object) - - local localCardPos = self.positionToLocal(object.getPosition()) - if inArea(localCardPos, DECK_DISCARD_AREA) then - tokenManager.resetTokensSpawned(object) - removeTokensFromObject(object) - elseif shouldSpawnTokens(object) then - spawnTokensFor(object) - end -end - --- detect if "Dream-Enhancing Serum" is removed -function onCollisionExit(collision_info) - if collision_info.collision_object.getName() == "Dream-Enhancing Serum" then isDES = false end -end - --- checks if tokens should be spawned for the provided card -function shouldSpawnTokens(card) - if card.is_face_down then - return false - end - - local localCardPos = self.positionToLocal(card.getPosition()) - local metadata = JSON.decode(card.getGMNotes()) - - -- If no metadata we don't know the type, so only spawn in the main area - if metadata == nil then - return inArea(localCardPos, MAIN_PLAY_AREA) - end - - -- Spawn tokens for assets and events on the main area - if inArea(localCardPos, MAIN_PLAY_AREA) - and (metadata.type == "Asset" - or metadata.type == "Event") then - return true - end - - -- Spawn tokens for all encounter types in the threat area - if inArea(localCardPos, THREAT_AREA) - and (metadata.type == "Treachery" - or metadata.type == "Enemy" - or metadata.weakness) then - return true - end - - return false -end - -function onObjectEnterContainer(container, object) - Wait.frames(function() resetTokensIfInDeckZone(container, object) end, 1) -end - -function resetTokensIfInDeckZone(container, object) - local pos = self.positionToLocal(container.getPosition()) - if inArea(pos, DECK_DISCARD_AREA) then - tokenManager.resetTokensSpawned(object) - removeTokensFromObject(container) - end -end - --- removes tokens from the provided card/deck -function removeTokensFromObject(object) - for _, obj in ipairs(searchArea(object.getPosition(), { 3, 1, 4 })) do - if obj.getGUID() ~= "4ee1f2" and -- table - obj ~= self and - obj.type ~= "Deck" and - obj.type ~= "Card" and - obj.memo ~= nil and - obj.getLock() == false and - obj.getDescription() ~= "Action Token" and - not tokenChecker.isChaosToken(obj) then - TRASHCAN.putObject(obj) - end - end -end - ---------------------------------------------------------- --- investigator ID grabbing and skill tracker ---------------------------------------------------------- - -function maybeUpdateActiveInvestigator(card) - if not inArea(self.positionToLocal(card.getPosition()), INVESTIGATOR_AREA) then return end - - local notes = JSON.decode(card.getGMNotes()) - local class - - if notes ~= nil and notes.type == "Investigator" and notes.id ~= nil then - if notes.id == activeInvestigatorId then return end - class = notes.class - activeInvestigatorId = notes.id - STAT_TRACKER.call("updateStats", {notes.willpowerIcons, notes.intellectIcons, notes.combatIcons, notes.agilityIcons}) - elseif activeInvestigatorId ~= "00000" then - class = "Neutral" - activeInvestigatorId = "00000" - STAT_TRACKER.call("updateStats", {1, 1, 1, 1}) - else - return - end - - -- change state of action tokens - local search = searchArea(self.positionToWorld({-1.1, 0.05, -0.27}), {4, 1, 1}) - local smallToken = nil - local STATE_TABLE = { - ["Guardian"] = 1, - ["Seeker"] = 2, - ["Rogue"] = 3, - ["Mystic"] = 4, - ["Survivor"] = 5, - ["Neutral"] = 6 - } - - for _, obj in ipairs(search) do - if obj.getDescription() == "Action Token" and obj.getStateId() > 0 then - if obj.getScale().x < 0.4 then - smallToken = obj - else - setObjectState(obj, STATE_TABLE[class]) - end - end - end - - -- update the small token with special action for certain investigators - local SPECIAL_ACTIONS = { - ["04002"] = 8, -- Ursula Downs - ["01002"] = 9, -- Daisy Walker - ["01502"] = 9, -- Daisy Walker - ["01002-pb"] = 9, -- Daisy Walker - ["06003"] = 10, -- Tony Morgan - ["04003"] = 11, -- Finn Edwards - ["08016"] = 14 -- Bob Jenkins - } - - if smallToken ~= nil then - setObjectState(smallToken, SPECIAL_ACTIONS[activeInvestigatorId] or STATE_TABLE[class]) - end -end - -function setObjectState(obj, stateId) - if obj.getStateId() ~= stateId then obj.setState(stateId) end -end - ---------------------------------------------------------- --- calls to 'Global' / functions for calls from outside ---------------------------------------------------------- - -function drawChaosTokenButton(_, _, isRightClick) - chaosBagApi.drawChaosToken(self, DRAWN_CHAOS_TOKEN_OFFSET, isRightClick) -end - -function drawEncounterCard(_, _, isRightClick) - local pos = self.positionToWorld(DRAWN_ENCOUNTER_CARD_OFFSET) - local rotY = self.getRotation().y - mythosAreaApi.drawEncounterCard(pos, rotY, isRightClick) -end - -function returnGlobalDiscardPosition() - return self.positionToWorld(DISCARD_PILE_POSITION) -end - --- Sets this playermat's draw 1 button to visible ----@param visible Boolean. Whether the draw 1 button should be visible -function showDrawButton(visible) - isDrawButtonVisible = visible - - -- create the "Draw 1" button - if isDrawButtonVisible then - self.createButton({ - label = "Draw 1", - click_function = "doDrawOne", - function_owner = self, - position = { 1.84, 0.1, -0.36 }, - scale = { 0.12, 0.12, 0.12 }, - width = 800, - height = 280, - font_size = 180 - }) - - -- remove the "Draw 1" button - else - local buttons = self.getButtons() - for i = 1, #buttons do - if buttons[i].label == "Draw 1" then - self.removeButton(buttons[i].index) - end - end - end -end - --- Spawns / destroys a clickable clue counter for this playmat with the correct amount of clues ----@param showCounter Boolean Whether the clickable clue counter should be present -function clickableClues(showCounter) - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - local clickerPos = CLUE_CLICKER.getPosition() - local clueCount = 0 - - if showCounter then - -- current clue count - clueCount = CLUE_COUNTER.getVar("exposedValue") - - -- remove clues - CLUE_COUNTER.call("removeAllClues") - - -- set value for clue clickers - CLUE_CLICKER.call("updateVal", clueCount) - - -- move clue counters up - clickerPos.y = 1.52 - CLUE_CLICKER.setPosition(clickerPos) - else - -- current clue count - clueCount = CLUE_CLICKER.getVar("val") - - -- move clue counters down - clickerPos.y = 1.3 - CLUE_CLICKER.setPosition(clickerPos) - - -- spawn clues - local pos = self.positionToWorld({x = -1.12, y = 0.05, z = 0.7}) - for i = 1, clueCount do - pos.y = pos.y + 0.045 * i - tokenManager.spawnToken(pos, "clue", self.getRotation()) - end - end -end - --- removes all clues (moving tokens to the trash and setting counters to 0) -function removeClues() - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - - CLUE_COUNTER.call("removeAllClues") - CLUE_CLICKER.call("updateVal", 0) -end - --- reports the clue count ----@param useClickableCounters Boolean Controls which type of counter is getting checked -function getClueCount(useClickableCounters) - local count = 0 - - if useClickableCounters then - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - count = tonumber(CLUE_CLICKER.getVar("val")) - else - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - count = tonumber(CLUE_COUNTER.getVar("exposedValue")) - end - return count -end - --- Sets this playermat's snap points to limit snapping to matching card types or not. If matchTypes --- is true, the main card slot snap points will only snap assets, while the investigator area point --- will only snap Investigators. If matchTypes is false, snap points will be reset to snap all --- cards. ----@param matchTypes Boolean. Whether snap points should only snap for the matching card types. -function setLimitSnapsByType(matchTypes) - local snaps = self.getSnapPoints() - for i, snap in ipairs(snaps) do - local snapPos = snap.position - if inArea(snapPos, MAIN_PLAY_AREA) then - local snapTags = snaps[i].tags - if matchTypes then - if snapTags == nil then - snaps[i].tags = { "Asset" } - else - table.insert(snaps[i].tags, "Asset") - end - else - snaps[i].tags = nil - end - end - if inArea(snapPos, INVESTIGATOR_AREA) then - local snapTags = snaps[i].tags - if matchTypes then - if snapTags == nil then - snaps[i].tags = { "Investigator" } - else - table.insert(snaps[i].tags, "Investigator") - end - else - snaps[i].tags = nil - end - end - end - self.setSnapPoints(snaps) -end - --- Simple method to check if the given point is in a specified area. Local use only, ----@param point Vector Point to check, only x and z values are relevant ----@param bounds Table Defined area to see if the point is within. See MAIN_PLAY_AREA for sample --- bounds definition. ----@return Boolean True if the point is in the area defined by bounds -function inArea(point, bounds) - return (point.x < bounds.upperLeft.x - and point.x > bounds.lowerRight.x - and point.z < bounds.upperLeft.z - and point.z > bounds.lowerRight.z) -end - --- called by custom data helpers to add player card data ----@param args table Contains only one entry, the GUID of the custom data helper -function updatePlayerCards(args) - local customDataHelper = getObjectFromGUID(args[1]) - local playerCardData = customDataHelper.getTable("PLAYER_CARD_DATA") - tokenManager.addPlayerCardData(playerCardData) -end - --- utility function for rounding ----@param num Number Initial value ----@param numDecimalPlaces Number Amount of decimal places -function round(num, numDecimalPlaces) - local mult = 10^(numDecimalPlaces or 0) - return math.floor(num * mult + 0.5) / mult -end -end) -__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local MythosAreaApi = {} - local MYTHOS_AREA_GUID = "9f334f" + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - -- returns the chaos token metadata (if provided through scenario reference card) - MythosAreaApi.returnTokenData = function() - return getObjectFromGUID(MYTHOS_AREA_GUID).call("returnTokenData") + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") end - -- draw an encounter card to the requested position/rotation - MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) - getObjectFromGUID(MYTHOS_AREA_GUID).call("drawEncounterCard", { - pos = pos, - rotY = rotY, - alwaysFaceUp = alwaysFaceUp - }) + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") end - return MythosAreaApi -end -end) -__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local CHAOS_TOKEN_NAMES = { - ["Elder Sign"] = true, - ["+1"] = true, - ["0"] = true, - ["-1"] = true, - ["-2"] = true, - ["-3"] = true, - ["-4"] = true, - ["-5"] = true, - ["-6"] = true, - ["-7"] = true, - ["-8"] = true, - ["Skull"] = true, - ["Cultist"] = true, - ["Tablet"] = true, - ["Elder Thing"] = true, - ["Auto-fail"] = true, - ["Bless"] = true, - ["Curse"] = true, - ["Frost"] = true - } - - local TokenChecker = {} - - -- returns true if the passed object is a chaos token (by name) - TokenChecker.isChaosToken = function(obj) - if CHAOS_TOKEN_NAMES[obj.getName()] then - return true - else - return false - end + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") end - return TokenChecker + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) + end + + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) + end + + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) + end + + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi end end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Playermat 1 White 8b081b.yaml b/unpacked/Custom_Tile Playermat 1 White 8b081b.yaml index c24f616ae..64fa7b2cc 100644 --- a/unpacked/Custom_Tile Playermat 1 White 8b081b.yaml +++ b/unpacked/Custom_Tile Playermat 1 White 8b081b.yaml @@ -224,6 +224,7 @@ Locked: true LuaScript: !include 'Custom_Tile Playermat 1 White 8b081b.ttslua' LuaScriptState: '{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"White"}' MeasureMovement: false +Memo: White Name: Custom_Tile Nickname: 'Playermat 1: White' Snap: true diff --git a/unpacked/Custom_Tile Playermat 2 Orange bd0ff4.ttslua b/unpacked/Custom_Tile Playermat 2 Orange bd0ff4.ttslua index 07aac7332..5e8826225 100644 --- a/unpacked/Custom_Tile Playermat 2 Orange bd0ff4.ttslua +++ b/unpacked/Custom_Tile Playermat 2 Orange bd0ff4.ttslua @@ -41,8 +41,47 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local CHAOS_TOKEN_NAMES = { + ["Elder Sign"] = true, + ["+1"] = true, + ["0"] = true, + ["-1"] = true, + ["-2"] = true, + ["-3"] = true, + ["-4"] = true, + ["-5"] = true, + ["-6"] = true, + ["-7"] = true, + ["-8"] = true, + ["Skull"] = true, + ["Cultist"] = true, + ["Tablet"] = true, + ["Elder Thing"] = true, + ["Auto-fail"] = true, + ["Bless"] = true, + ["Curse"] = true, + ["Frost"] = true + } + + local TokenChecker = {} + + -- returns true if the passed object is a chaos token (by name) + TokenChecker.isChaosToken = function(obj) + if CHAOS_TOKEN_NAMES[obj.getName()] then + return true + else + return false + end + end + + return TokenChecker +end +end) __bundle_register("core/token/TokenManager", function(require, _LOADED, __bundle_register, __bundle_modules) do + local guidReferenceApi = require("core/GUIDReferenceApi") local optionPanelApi = require("core/OptionPanelApi") local playAreaApi = require("core/PlayAreaApi") local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") @@ -163,15 +202,10 @@ do ["supply"] = 7 } - -- Source for tokens - local TOKEN_SOURCE_GUID = "124381" - -- Table of data extracted from the token source bag, keyed by the Memo on each token which -- should match the token type keys ("resource", "clue", etc) local tokenTemplates - local DATA_HELPER_GUID = "708279" - local playerCardData local locationData @@ -269,9 +303,11 @@ do -- Copy the offsets to make sure we don't change the static values local baseOffsets = offsets offsets = { } + + -- get a vector for the shifting (downwards local to the card) + local shiftDownVector = Vector(0, 0, shiftDown):rotateOver("y", card.getRotation().y) for i, baseOffset in ipairs(baseOffsets) do - offsets[i] = baseOffset - offsets[i][3] = offsets[i][3] + shiftDown + offsets[i] = baseOffset + shiftDownVector end end @@ -384,8 +420,8 @@ do if tokenTemplates ~= nil then return end - tokenTemplates = { } - local tokenSource = getObjectFromGUID(TOKEN_SOURCE_GUID) + tokenTemplates = {} + local tokenSource = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSource") for _, tokenTemplate in ipairs(tokenSource.getData().ContainedObjects) do local tokenName = tokenTemplate.Memo tokenTemplates[tokenName] = tokenTemplate @@ -397,7 +433,7 @@ do if playerCardData ~= nil then return end - local dataHelper = getObjectFromGUID(DATA_HELPER_GUID) + local dataHelper = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") playerCardData = dataHelper.getTable('PLAYER_CARD_DATA') locationData = dataHelper.getTable('LOCATIONS_DATA') end @@ -412,18 +448,16 @@ do if uses == nil then return end -- go through tokens to spawn - local type, token, tokenCount + local tokenCount for i, useInfo in ipairs(uses) do - type = useInfo.type - token = useInfo.token - tokenCount = (useInfo.count or 0) - + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() - if extraUses ~= nil and extraUses[type] ~= nil then - tokenCount = tokenCount + extraUses[type] + tokenCount = (useInfo.count or 0) + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() + if extraUses ~= nil and extraUses[useInfo.type] ~= nil then + tokenCount = tokenCount + extraUses[useInfo.type] end -- Shift each spawned group after the first down so they don't pile on each other - TokenManager.spawnTokenGroup(card, token, tokenCount, (i - 1) * 0.8, type) + TokenManager.spawnTokenGroup(card, useInfo.token, tokenCount, (i - 1) * 0.8, useInfo.type) end + tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -447,9 +481,8 @@ do ---@param playerData Table Player card data structure retrieved from the DataHelper. Should be -- the right data for this card. internal.spawnPlayerCardTokensFromDataHelper = function(card, playerData) - token = playerData.tokenType - tokenCount = playerData.tokenCount - --log("Spawning data helper tokens for "..card.getName()..'['..card.getDescription()..']: '..tokenCount.."x "..token) + local token = playerData.tokenType + local tokenCount = playerData.tokenCount TokenManager.spawnTokenGroup(card, token, tokenCount) tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -482,7 +515,6 @@ do return 0 end - --log(card.getName() .. ' : ' .. locationData.type .. ' : ' .. locationData.value .. ' : ' .. locationData.clueSide) if ((card.is_face_down and locationData.clueSide == 'back') or (not card.is_face_down and locationData.clueSide == 'front')) then if locationData.type == 'fixed' then @@ -592,21 +624,315 @@ do return TokenManager end end) +__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local TokenSpawnTracker = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getSpawnTracker() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSpawnTracker") + end + + TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) + return getSpawnTracker().call("hasSpawnedTokens", cardGuid) + end + + TokenSpawnTracker.markTokensSpawned = function(cardGuid) + return getSpawnTracker().call("markTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetTokensSpawned = function(cardGuid) + return getSpawnTracker().call("resetTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetAllAssetAndEvents = function() + return getSpawnTracker().call("resetAllAssetAndEvents") + end + + TokenSpawnTracker.resetAllLocations = function() + return getSpawnTracker().call("resetAllLocations") + end + + TokenSpawnTracker.resetAll = function() + return getSpawnTracker().call("resetAll") + end + + return TokenSpawnTracker +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.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) +__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local MythosAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end + + -- returns the chaos token metadata (if provided through scenario reference card) + MythosAreaApi.returnTokenData = function() + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") + end + + -- draw an encounter card to the requested position/rotation + MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) + getMythosArea().call("drawEncounterCard", { + pos = pos, + rotY = rotY, + alwaysFaceUp = alwaysFaceUp + }) + end + + return MythosAreaApi +end +end) +__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local OptionPanelApi = {} + + -- loads saved options + ---@param options Table New options table + OptionPanelApi.loadSettings = function(options) + return Global.call("loadSettings", options) + end + + -- returns option panel table + OptionPanelApi.getOptions = function() + return Global.getTable("optionPanel") + end + + return OptionPanelApi +end +end) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end + + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") + end + + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) + end + + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) + end + + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) + end + + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi +end +end) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) ---------------------------------------------------------- --- specific setup (different for each playmat) ---------------------------------------------------------- - -TRASHCAN_GUID = "f7b6c8" -STAT_TRACKER_GUID = "b4a5f7" -RESOURCE_COUNTER_GUID = "816d84" -CLUE_COUNTER_GUID = "1769ed" -CLUE_CLICKER_GUID = "3f22e5" - require("playermat/Playmat") end) __bundle_register("playermat/Playmat", function(require, _LOADED, __bundle_register, __bundle_modules) local chaosBagApi = require("chaosbag/ChaosBagApi") +local guidReferenceApi = require("core/GUIDReferenceApi") local mythosAreaApi = require("core/MythosAreaApi") local navigationOverlayApi = require("core/NavigationOverlayApi") local tokenChecker = require("core/token/TokenChecker") @@ -669,19 +995,19 @@ local DECK_DISCARD_AREA = { }, center = { x = -1.82, - y = 0.1, + y = 0.5, z = 0.305 }, size = { x = 0.4, - y = 0.1, + y = 3, z = 1.1 } } -- local position of draw and discard pile -local DRAW_DECK_POSITION = { x = -1.82, y = 0, z = 0 } -local DISCARD_PILE_POSITION = { x = -1.82, y = 0, z = 0.61 } +local DRAW_DECK_POSITION = { x = -1.82, y = 0.1, z = 0 } +local DISCARD_PILE_POSITION = { x = -1.82, y = 0.1, z = 0.61 } -- global position of encounter discard pile local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38} @@ -689,7 +1015,11 @@ local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38} -- global variable so it can be reset by the Clean Up Helper activeInvestigatorId = "00000" -local TRASHCAN, STAT_TRACKER, RESOURCE_COUNTER +-- table of type-object reference pairs of all owned objects +local ownedObjects = {} +local matColor = self.getMemo() + +-- variable to track the status of the "Show Draw Button" option local isDrawButtonVisible = false -- global variable to report "Dream-Enhancing Serum" status @@ -706,9 +1036,8 @@ end function onLoad(saveState) self.interactable = DEBUG - TRASHCAN = getObjectFromGUID(TRASHCAN_GUID) - STAT_TRACKER = getObjectFromGUID(STAT_TRACKER_GUID) - RESOURCE_COUNTER = getObjectFromGUID(RESOURCE_COUNTER_GUID) + -- get object references to owned objects + ownedObjects = guidReferenceApi.getObjectsByOwner(matColor) -- button creation for i = 1, 6 do @@ -753,9 +1082,7 @@ function onLoad(saveState) end showDrawButton(isDrawButtonVisible) - collisionEnabled = true - math.randomseed(os.time()) end @@ -771,7 +1098,7 @@ function searchArea(origin, size, filter) orientation = self.getRotation(), type = 3, size = size, - max_distance = 1 + max_distance = 0 }) local objList = {} @@ -788,11 +1115,12 @@ function isCard(x) return x.type == 'Card' end function isDeck(x) return x.type == 'Deck' end function isCardOrDeck(x) return x.type == 'Card' or x.type == 'Deck' end --- Finds all objects on the playmat and associated set aside zone. +-- finds all objects on the playmat and associated set aside zone. function searchAroundSelf(filter) local bounds = self.getBoundsNormalized() -- Increase the width to cover the set aside zone bounds.size.x = bounds.size.x + SEARCH_AROUND_SELF_X_BUFFER + bounds.size.y = 1 -- Since the cast is centered on the position, shift left or right to keep the non-set aside edge -- of the cast at the edge of the playmat -- setAsideDirection accounts for the set aside zone being on the left or right, depending on the @@ -819,30 +1147,35 @@ function doNotReady(card) return card.getVar("do_not_ready") or false end +-- rounds a number to the specified amount of decimal places +---@param num Number Initial value +---@param numDecimalPlaces Number Amount of decimal places +function round(num, numDecimalPlaces) + local mult = 10^(numDecimalPlaces or 0) + return math.floor(num * mult + 0.5) / mult +end + --------------------------------------------------------- -- Discard buttons --------------------------------------------------------- --- builds a function that discards things in searchPosition --- stuff on the card/deck will be put into the local trashcan -function makeDiscardHandlerFor(searchPosition) - return function () - local origin = self.positionToWorld(searchPosition) - for _, obj in ipairs(searchArea(origin, {2, 1, 3.2})) do - if isCardOrDeck(obj) then - if obj.hasTag("PlayerCard") then - placeOrMergeIntoDeck(obj, returnGlobalDiscardPosition(), self.getRotation()) - else - placeOrMergeIntoDeck(obj, ENCOUNTER_DISCARD_POSITION, {x = 0, y = -90, z = 0}) - end - -- put chaos tokens back into bag (e.g. Unrelenting) - elseif tokenChecker.isChaosToken(obj) then - local chaosBag = chaosBagApi.findChaosBag() - chaosBag.putObject(obj) - -- don't touch the table or this playmat itself - elseif obj.guid ~= "4ee1f2" and obj ~= self then - TRASHCAN.putObject(obj) +-- handles discarding for a list of objects +---@param objList Table List of objects to discard +function discardListOfObjects(objList) + for _, obj in ipairs(objList) do + if isCardOrDeck(obj) then + if obj.hasTag("PlayerCard") then + placeOrMergeIntoDeck(obj, returnGlobalDiscardPosition(), self.getRotation()) + else + placeOrMergeIntoDeck(obj, ENCOUNTER_DISCARD_POSITION, {x = 0, y = -90, z = 0}) end + -- put chaos tokens back into bag (e.g. Unrelenting) + elseif tokenChecker.isChaosToken(obj) then + local chaosBag = chaosBagApi.findChaosBag() + chaosBag.putObject(obj) + -- don't touch locked objects (like the table etc.) + elseif not obj.getLock() then + ownedObjects.Trash.putObject(obj) end end end @@ -853,48 +1186,51 @@ function placeOrMergeIntoDeck(obj, pos, rot) if not pos then return end local offset = 0.5 - local deck, card, newPos -- search the new position for existing card/deck local searchResult = searchArea(pos, { 1, 1, 1 }, isCardOrDeck) - if #searchResult == 1 then - local match = searchResult[1] - if match.type == 'Card' then - card = match - elseif match.type == 'Deck' then - deck = match - end - end - -- update vertical component of new position - if card or deck then + -- get new position + local newPos + if #searchResult == 1 then local bounds = searchResult[1].getBounds() newPos = Vector(pos):setAt("y", bounds.center.y + bounds.size.y / 2 + offset) else newPos = Vector(pos) + Vector(0, offset, 0) end - -- actual movement of the object + -- allow moving the objects smoothly out of the hand + obj.use_hands = false + if rot then obj.setRotationSmooth(rot, false, true) end obj.setPositionSmooth(newPos, false, true) - - -- this avoids a TTS bug that merges unrelated cards that are not resting - if deck then - Wait.time(function() deck.putObject(obj) end, 0.3) - elseif card then - Wait.time(function() obj.setPosition(newPos) end, 0.3) - end + + -- continue if the card stops smooth moving + Wait.condition( + function() + obj.use_hands = true + -- this avoids a TTS bug that merges unrelated cards that are not resting + if #searchResult == 1 and searchResult[1] ~= obj then + -- call this with avoiding errors (physics is sometimes too fast so the object doesn't exist for the put) + pcall(function() searchResult[1].putObject(obj) end) + end + end, + function() return not obj.isSmoothMoving() end, 3) end -- build a discard button to discard from searchPosition (number must be unique) function makeDiscardButton(xValue, number) local position = { xValue, 0.1, -0.94} local searchPosition = {-position[1], position[2], position[3] + 0.32} - local handler = makeDiscardHandlerFor(searchPosition) local handlerName = 'handler' .. number - self.setVar(handlerName, handler) + self.setVar(handlerName, function() + local cardSizeSearch = {2, 1, 3.2} + local globalSearchPosition = self.positionToWorld(searchPosition) + local searchResult = searchArea(globalSearchPosition, cardSizeSearch) + return discardListOfObjects(searchResult) + end) self.createButton({ label = "Discard", click_function = handlerName, @@ -978,10 +1314,10 @@ function doUpkeep(_, clickedByColor, isRightClick) -- gain a resource (or two if playing Jenny Barnes) if string.match(activeInvestigatorId, "%d%d%d%d%d") == "02003" then - gainResources(2) + updateCounter({type = "ResourceCounter", modifier = 2}) printToColor("Gaining 2 resources (Jenny)", messageColor) else - gainResources(1) + updateCounter({type = "ResourceCounter", modifier = 1}) end -- draw a card (with handling for Patrice and Forced Learning) @@ -1007,18 +1343,6 @@ function doUpkeep(_, clickedByColor, isRightClick) end end --- adds the specified amount of resources to the resource counter -function gainResources(amount) - local count = RESOURCE_COUNTER.getVar("val") - local add = tonumber(amount) or 0 - RESOURCE_COUNTER.call("updateVal", count + add) -end - --- returns the resource counter amount -function getResourceCount() - return RESOURCE_COUNTER.getVar("val") -end - -- function for "draw 1 button" (that can be added via option panel) function doDrawOne(_, color) -- send messages to player who clicked button if no seated player found @@ -1028,78 +1352,113 @@ end -- draw X cards (shuffle discards if necessary) function drawCardsWithReshuffle(numCards) - getDrawDiscardDecks() + local deckAreaObjects = getDeckAreaObjects() -- Norman Withers handling - if string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then - local harbinger = false - if topCard ~= nil and topCard.getName() == "The Harbinger" then harbinger = true - elseif drawDeck ~= nil and not drawDeck.is_face_down then - local cards = drawDeck.getObjects() - if cards[#cards].name == "The Harbinger" then harbinger = true end + local harbinger = false + if deckAreaObjects.topCard and deckAreaObjects.topCard.getName() == "The Harbinger" then + harbinger = true + elseif deckAreaObjects.draw and not deckAreaObjects.draw.is_face_down then + local cards = deckAreaObjects.draw.getObjects() + if cards[#cards].name == "The Harbinger" then + harbinger = true end + end - if harbinger then - printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) + if harbinger then + printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) + return + end + + local topCardDetected = false + if deckAreaObjects.topCard ~= nil then + deckAreaObjects.topCard.deal(1, playerColor) + topCardDetected = true + numCards = numCards - 1 + if numCards == 0 then + flipTopCardFromDeck() return end - - if topCard ~= nil then - topCard.deal(numCards, playerColor) - numCards = numCards - 1 - if numCards == 0 then return end - end end local deckSize = 1 - if drawDeck == nil then + if deckAreaObjects.draw == nil then deckSize = 0 - elseif drawDeck.tag == "Deck" then - deckSize = #drawDeck.getObjects() + elseif deckAreaObjects.draw.type == "Deck" then + deckSize = #deckAreaObjects.draw.getObjects() end if deckSize >= numCards then drawCards(numCards) - return + -- flip top card again for Norman + if topCardDetected and string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then + flipTopCardFromDeck() + end + else + drawCards(deckSize) + if deckAreaObjects.discard ~= nil then + shuffleDiscardIntoDeck() + Wait.time(function() + drawCards(numCards - deckSize) + -- flip top card again for Norman + if topCardDetected and string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then + flipTopCardFromDeck() + end + end, 1) + end + printToColor("Take 1 horror (drawing card from empty deck)", messageColor) end - - drawCards(deckSize) - if discardPile ~= nil then - shuffleDiscardIntoDeck() - Wait.time(|| drawCards(numCards - deckSize), 1) - end - printToColor("Take 1 horror (drawing card from empty deck)", messageColor) end --- get the draw deck and discard pile objects -function getDrawDiscardDecks() - drawDeck = nil - discardPile = nil - topCard = nil - +-- get the draw deck and discard pile objects and returns the references +function getDeckAreaObjects() + local deckAreaObjects = {} for _, object in ipairs(searchDeckAndDiscardArea(isCardOrDeck)) do if self.positionToLocal(object.getPosition()).z > 0.5 then - discardPile = object + deckAreaObjects.discard = object -- Norman Withers handling - elseif string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" and not object.is_face_down then - topCard = object + elseif object.type == "Card" and not object.is_face_down then + deckAreaObjects.topCard = object else - drawDeck = object + deckAreaObjects.draw = object end end + return deckAreaObjects end function drawCards(numCards) - if drawDeck == nil then return end - drawDeck.deal(numCards, playerColor) + local deckAreaObjects = getDeckAreaObjects() + if deckAreaObjects.draw then + deckAreaObjects.draw.deal(numCards, playerColor) + end end function shuffleDiscardIntoDeck() - if not discardPile.is_face_down then discardPile.flip() end - discardPile.shuffle() - discardPile.setPositionSmooth(self.positionToWorld(DRAW_DECK_POSITION), false, false) - drawDeck = discardPile - discardPile = nil + local deckAreaObjects = getDeckAreaObjects() + if not deckAreaObjects.discard.is_face_down then + deckAreaObjects.discard.flip() + end + deckAreaObjects.discard.shuffle() + deckAreaObjects.discard.setPositionSmooth(self.positionToWorld(DRAW_DECK_POSITION), false, false) +end + +-- utility function for Norman Withers to flip the top card to the revealed side +function flipTopCardFromDeck() + Wait.time(function() + local deckAreaObjects = getDeckAreaObjects() + if deckAreaObjects.topCard then + return + elseif deckAreaObjects.draw then + if deckAreaObjects.draw.type == "Card" then + deckAreaObjects.draw.flip() + else + -- get bounds to know the height of the deck + local bounds = deckAreaObjects.draw.getBounds() + local pos = bounds.center + Vector(0, bounds.size.y / 2 + 0.2, 0) + deckAreaObjects.draw.takeObject({ position = pos, flip = true }) + end + end + end, 0.1) end -- discard a random non-hidden card from hand @@ -1162,32 +1521,8 @@ function changeColor(clickedByColor) -- show the option dialog for color selection to the player that triggered this Player[clickedByColor].showOptionsDialog("Select a new color:", colorList, _, function(color) - local HAND_ZONE_GUIDS = { - "a70eee", -- White - "5fe087", -- Orange - "0285cc", -- Green - "be2f17" -- Red - } - local index - local startPos = self.getPosition() - - -- get respective hand zone by position - if startPos.x < -42 then - if startPos.z > 0 then - index = 1 - else - index = 2 - end - else - if startPos.z > 0 then - index = 3 - else - index = 4 - end - end - -- update the color of the hand zone - local handZone = getObjectFromGUID(HAND_ZONE_GUIDS[index]) + local handZone = ownedObjects.HandZone handZone.setValue(color) -- if the seated player clicked this, reseat him to the new color @@ -1251,17 +1586,17 @@ function spawnTokensFor(object) tokenManager.spawnForCard(object, extraUses) end -function onCollisionEnter(collision_info) - local object = collision_info.collision_object - - -- detect if "Dream-Enhancing Serum" is placed - if object.getName() == "Dream-Enhancing Serum" then isDES = true end +function onCollisionEnter(collisionInfo) + local object = collisionInfo.collision_object -- only continue if loading is completed if not collisionEnabled then return end -- only continue for cards - if object.type ~= "Card" then return end + if not isCard(object) then return end + + -- detect if "Dream-Enhancing Serum" is placed + if object.getName() == "Dream-Enhancing Serum" then isDES = true end maybeUpdateActiveInvestigator(object) syncCustomizableMetadata(object) @@ -1276,8 +1611,8 @@ function onCollisionEnter(collision_info) end -- detect if "Dream-Enhancing Serum" is removed -function onCollisionExit(collision_info) - if collision_info.collision_object.getName() == "Dream-Enhancing Serum" then isDES = false end +function onCollisionExit(collisionInfo) + if collisionInfo.collision_object.getName() == "Dream-Enhancing Serum" then isDES = false end end -- checks if tokens should be spawned for the provided card @@ -1313,14 +1648,12 @@ function shouldSpawnTokens(card) end function onObjectEnterContainer(container, object) - Wait.frames(function() resetTokensIfInDeckZone(container, object) end, 1) -end + if not isCard(object) then return end -function resetTokensIfInDeckZone(container, object) - local pos = self.positionToLocal(container.getPosition()) - if inArea(pos, DECK_DISCARD_AREA) then + local localCardPos = self.positionToLocal(object.getPosition()) + if inArea(localCardPos, DECK_DISCARD_AREA) then tokenManager.resetTokensSpawned(object) - removeTokensFromObject(container) + removeTokensFromObject(object) end end @@ -1335,7 +1668,7 @@ function removeTokensFromObject(object) obj.getLock() == false and obj.getDescription() ~= "Action Token" and not tokenChecker.isChaosToken(obj) then - TRASHCAN.putObject(obj) + ownedObjects.Trash.putObject(obj) end end end @@ -1354,11 +1687,16 @@ function maybeUpdateActiveInvestigator(card) if notes.id == activeInvestigatorId then return end class = notes.class activeInvestigatorId = notes.id - STAT_TRACKER.call("updateStats", {notes.willpowerIcons, notes.intellectIcons, notes.combatIcons, notes.agilityIcons}) + ownedObjects.InvestigatorSkillTracker.call("updateStats", { + notes.willpowerIcons, + notes.intellectIcons, + notes.combatIcons, + notes.agilityIcons + }) elseif activeInvestigatorId ~= "00000" then class = "Neutral" activeInvestigatorId = "00000" - STAT_TRACKER.call("updateStats", {1, 1, 1, 1}) + ownedObjects.InvestigatorSkillTracker.call("updateStats", {1, 1, 1, 1}) else return end @@ -1405,6 +1743,40 @@ function setObjectState(obj, stateId) if obj.getStateId() ~= stateId then obj.setState(stateId) end end +--------------------------------------------------------- +-- manipulation of owned objects +--------------------------------------------------------- + +-- updates the specific owned counter +---@param param Table Contains the information to update: +--- type: String Counter to target +--- newValue: Number Value to set the counter to +--- modifier: Number If newValue is not provided, the existing value will be adjusted by this modifier +function updateCounter(param) + local counter = ownedObjects[param.type] + if counter ~= nil then + counter.call("updateVal", param.newValue or (counter.getVar("val") + param.modifier)) + else + printToAll(param.type .. " for " .. matColor .. " could not be found.", "Yellow") + end +end + +-- returns the resource counter amount +---@param type String Counter to target +function getCounterValue(type) + return ownedObjects[type].getVar("val") +end + +-- set investigator skill tracker to "1, 1, 1, 1" +function resetSkillTracker() + local obj = ownedObjects.InvestigatorSkillTracker + if obj ~= nil then + obj.call("updateStats", { 1, 1, 1, 1 }) + else + printToAll("Skill tracker for " .. matColor .. " playmat could not be found.", "Yellow") + end +end + --------------------------------------------------------- -- calls to 'Global' / functions for calls from outside --------------------------------------------------------- @@ -1452,34 +1824,28 @@ function showDrawButton(visible) end end --- Spawns / destroys a clickable clue counter for this playmat with the correct amount of clues ----@param showCounter Boolean Whether the clickable clue counter should be present +-- shows / hides a clickable clue counter for this playmat and sets the correct amount of clues +---@param showCounter Boolean Whether the clickable clue counter should be visible function clickableClues(showCounter) - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - local clickerPos = CLUE_CLICKER.getPosition() + local clickerPos = ownedObjects.ClickableClueCounter.getPosition() local clueCount = 0 + + -- move clue counters + local modY = showCounter and 0.525 or -0.525 + ownedObjects.ClickableClueCounter.setPosition(clickerPos + Vector(0, modY, 0)) if showCounter then -- current clue count - clueCount = CLUE_COUNTER.getVar("exposedValue") + clueCount = ownedObjects.ClueCounter.getVar("exposedValue") -- remove clues - CLUE_COUNTER.call("removeAllClues") + ownedObjects.ClueCounter.call("removeAllClues", ownedObjects.Trash) -- set value for clue clickers - CLUE_CLICKER.call("updateVal", clueCount) - - -- move clue counters up - clickerPos.y = 1.52 - CLUE_CLICKER.setPosition(clickerPos) + ownedObjects.ClickableClueCounter.call("updateVal", clueCount) else -- current clue count - clueCount = CLUE_CLICKER.getVar("val") - - -- move clue counters down - clickerPos.y = 1.3 - CLUE_CLICKER.setPosition(clickerPos) + clueCount = ownedObjects.ClickableClueCounter.getVar("val") -- spawn clues local pos = self.positionToWorld({x = -1.12, y = 0.05, z = 0.7}) @@ -1492,26 +1858,18 @@ end -- removes all clues (moving tokens to the trash and setting counters to 0) function removeClues() - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - - CLUE_COUNTER.call("removeAllClues") - CLUE_CLICKER.call("updateVal", 0) + ownedObjects.ClueCounter.call("removeAllClues", ownedObjects.Trash) + ownedObjects.ClickableClueCounter.call("updateVal", 0) end -- reports the clue count ---@param useClickableCounters Boolean Controls which type of counter is getting checked function getClueCount(useClickableCounters) - local count = 0 - if useClickableCounters then - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - count = tonumber(CLUE_CLICKER.getVar("val")) + return ownedObjects.ClickableClueCounter.getVar("val") else - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - count = tonumber(CLUE_COUNTER.getVar("exposedValue")) + return ownedObjects.ClueCounter.getVar("exposedValue") end - return count end -- Sets this playermat's snap points to limit snapping to matching card types or not. If matchTypes @@ -1570,331 +1928,33 @@ function updatePlayerCards(args) local playerCardData = customDataHelper.getTable("PLAYER_CARD_DATA") tokenManager.addPlayerCardData(playerCardData) end - --- utility function for rounding ----@param num Number Initial value ----@param numDecimalPlaces Number Amount of decimal places -function round(num, numDecimalPlaces) - local mult = 10^(numDecimalPlaces or 0) - return math.floor(num * mult + 0.5) / mult -end -end) -__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local MythosAreaApi = {} - local MYTHOS_AREA_GUID = "9f334f" - - -- returns the chaos token metadata (if provided through scenario reference card) - MythosAreaApi.returnTokenData = function() - return getObjectFromGUID(MYTHOS_AREA_GUID).call("returnTokenData") - end - - -- draw an encounter card to the requested position/rotation - MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) - getObjectFromGUID(MYTHOS_AREA_GUID).call("drawEncounterCard", { - pos = pos, - rotY = rotY, - alwaysFaceUp = alwaysFaceUp - }) - end - - return MythosAreaApi -end end) __bundle_register("core/NavigationOverlayApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local NavigationOverlayApi = {} - local HANDLER_GUID = "797ede" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getNOHandler() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "NavigationOverlayHandler") + end -- Copies the visibility for the Navigation overlay ---@param startColor String Color of the player to copy from ---@param targetColor String Color of the targeted player NavigationOverlayApi.copyVisibility = function(startColor, targetColor) - getObjectFromGUID(HANDLER_GUID).call("copyVisibility", { + getNOHandler().call("copyVisibility", { startColor = startColor, targetColor = targetColor }) - end + end -- Changes the Navigation Overlay view ("Full View" --> "Play Areas" --> "Closed" etc.) ---@param playerColor String Color of the player to update the visibility for NavigationOverlayApi.cycleVisibility = function(playerColor) - getObjectFromGUID(HANDLER_GUID).call("cycleVisibility", playerColor) + getNOHandler().call("cycleVisibility", playerColor) end return NavigationOverlayApi end end) -__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local CHAOS_TOKEN_NAMES = { - ["Elder Sign"] = true, - ["+1"] = true, - ["0"] = true, - ["-1"] = true, - ["-2"] = true, - ["-3"] = true, - ["-4"] = true, - ["-5"] = true, - ["-6"] = true, - ["-7"] = true, - ["-8"] = true, - ["Skull"] = true, - ["Cultist"] = true, - ["Tablet"] = true, - ["Elder Thing"] = true, - ["Auto-fail"] = true, - ["Bless"] = true, - ["Curse"] = true, - ["Frost"] = true - } - - local TokenChecker = {} - - -- returns true if the passed object is a chaos token (by name) - TokenChecker.isChaosToken = function(obj) - if CHAOS_TOKEN_NAMES[obj.getName()] then - return true - else - return false - end - end - - return TokenChecker -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.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/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local OptionPanelApi = {} - - -- loads saved options - ---@param options Table New options table - OptionPanelApi.loadSettings = function(options) - return Global.call("loadSettings", options) - end - - -- returns option panel table - OptionPanelApi.getOptions = function() - return Global.getTable("optionPanel") - end - - return OptionPanelApi -end -end) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" - - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") - end - - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) - end - - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) - end - - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) - end - - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) - end - - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) - end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") - end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi -end -end) -__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local TokenSpawnTracker = { } - local SPAWN_TRACKER_GUID = "e3ffc9" - - TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("hasSpawnedTokens", cardGuid) - end - - TokenSpawnTracker.markTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("markTokensSpawned", cardGuid) - end - - TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetTokensSpawned", cardGuid) - end - - TokenSpawnTracker.resetAllAssetAndEvents = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllAssetAndEvents") - end - - TokenSpawnTracker.resetAllLocations = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllLocations") - end - - TokenSpawnTracker.resetAll = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAll") - end - - return TokenSpawnTracker -end -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Playermat 2 Orange bd0ff4.yaml b/unpacked/Custom_Tile Playermat 2 Orange bd0ff4.yaml index 943fb3c95..fd7d1ff50 100644 --- a/unpacked/Custom_Tile Playermat 2 Orange bd0ff4.yaml +++ b/unpacked/Custom_Tile Playermat 2 Orange bd0ff4.yaml @@ -224,13 +224,14 @@ Locked: true LuaScript: !include 'Custom_Tile Playermat 2 Orange bd0ff4.ttslua' LuaScriptState: '{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Orange"}' MeasureMovement: false +Memo: Orange Name: Custom_Tile Nickname: 'Playermat 2: Orange' Snap: true Sticky: true Tooltip: false Transform: - posX: -55.0 + posX: -55 posY: 1.45 posZ: -16.1 rotX: 0 diff --git a/unpacked/Custom_Tile Playermat 3 Green 383d8b.ttslua b/unpacked/Custom_Tile Playermat 3 Green 383d8b.ttslua index 0922c7343..739e7d66c 100644 --- a/unpacked/Custom_Tile Playermat 3 Green 383d8b.ttslua +++ b/unpacked/Custom_Tile Playermat 3 Green 383d8b.ttslua @@ -41,151 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) ---------------------------------------------------------- --- specific setup (different for each playmat) ---------------------------------------------------------- - -TRASHCAN_GUID = "5f896a" -STAT_TRACKER_GUID = "af7ed7" -RESOURCE_COUNTER_GUID = "cd15ac" -CLUE_COUNTER_GUID = "032300" -CLUE_CLICKER_GUID = "891403" - -require("playermat/Playmat") -end) -__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local MythosAreaApi = {} - local MYTHOS_AREA_GUID = "9f334f" - - -- returns the chaos token metadata (if provided through scenario reference card) - MythosAreaApi.returnTokenData = function() - return getObjectFromGUID(MYTHOS_AREA_GUID).call("returnTokenData") - end - - -- draw an encounter card to the requested position/rotation - MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) - getObjectFromGUID(MYTHOS_AREA_GUID).call("drawEncounterCard", { - pos = pos, - rotY = rotY, - alwaysFaceUp = alwaysFaceUp - }) - end - - return MythosAreaApi -end -end) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" - - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") - end - - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) - end - - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) - end - - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) - end - - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) - end - - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) - end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") - end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi -end -end) __bundle_register("playermat/Playmat", function(require, _LOADED, __bundle_register, __bundle_modules) local chaosBagApi = require("chaosbag/ChaosBagApi") +local guidReferenceApi = require("core/GUIDReferenceApi") local mythosAreaApi = require("core/MythosAreaApi") local navigationOverlayApi = require("core/NavigationOverlayApi") local tokenChecker = require("core/token/TokenChecker") @@ -248,19 +106,19 @@ local DECK_DISCARD_AREA = { }, center = { x = -1.82, - y = 0.1, + y = 0.5, z = 0.305 }, size = { x = 0.4, - y = 0.1, + y = 3, z = 1.1 } } -- local position of draw and discard pile -local DRAW_DECK_POSITION = { x = -1.82, y = 0, z = 0 } -local DISCARD_PILE_POSITION = { x = -1.82, y = 0, z = 0.61 } +local DRAW_DECK_POSITION = { x = -1.82, y = 0.1, z = 0 } +local DISCARD_PILE_POSITION = { x = -1.82, y = 0.1, z = 0.61 } -- global position of encounter discard pile local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38} @@ -268,7 +126,11 @@ local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38} -- global variable so it can be reset by the Clean Up Helper activeInvestigatorId = "00000" -local TRASHCAN, STAT_TRACKER, RESOURCE_COUNTER +-- table of type-object reference pairs of all owned objects +local ownedObjects = {} +local matColor = self.getMemo() + +-- variable to track the status of the "Show Draw Button" option local isDrawButtonVisible = false -- global variable to report "Dream-Enhancing Serum" status @@ -285,9 +147,8 @@ end function onLoad(saveState) self.interactable = DEBUG - TRASHCAN = getObjectFromGUID(TRASHCAN_GUID) - STAT_TRACKER = getObjectFromGUID(STAT_TRACKER_GUID) - RESOURCE_COUNTER = getObjectFromGUID(RESOURCE_COUNTER_GUID) + -- get object references to owned objects + ownedObjects = guidReferenceApi.getObjectsByOwner(matColor) -- button creation for i = 1, 6 do @@ -332,9 +193,7 @@ function onLoad(saveState) end showDrawButton(isDrawButtonVisible) - collisionEnabled = true - math.randomseed(os.time()) end @@ -350,7 +209,7 @@ function searchArea(origin, size, filter) orientation = self.getRotation(), type = 3, size = size, - max_distance = 1 + max_distance = 0 }) local objList = {} @@ -367,11 +226,12 @@ function isCard(x) return x.type == 'Card' end function isDeck(x) return x.type == 'Deck' end function isCardOrDeck(x) return x.type == 'Card' or x.type == 'Deck' end --- Finds all objects on the playmat and associated set aside zone. +-- finds all objects on the playmat and associated set aside zone. function searchAroundSelf(filter) local bounds = self.getBoundsNormalized() -- Increase the width to cover the set aside zone bounds.size.x = bounds.size.x + SEARCH_AROUND_SELF_X_BUFFER + bounds.size.y = 1 -- Since the cast is centered on the position, shift left or right to keep the non-set aside edge -- of the cast at the edge of the playmat -- setAsideDirection accounts for the set aside zone being on the left or right, depending on the @@ -398,30 +258,35 @@ function doNotReady(card) return card.getVar("do_not_ready") or false end +-- rounds a number to the specified amount of decimal places +---@param num Number Initial value +---@param numDecimalPlaces Number Amount of decimal places +function round(num, numDecimalPlaces) + local mult = 10^(numDecimalPlaces or 0) + return math.floor(num * mult + 0.5) / mult +end + --------------------------------------------------------- -- Discard buttons --------------------------------------------------------- --- builds a function that discards things in searchPosition --- stuff on the card/deck will be put into the local trashcan -function makeDiscardHandlerFor(searchPosition) - return function () - local origin = self.positionToWorld(searchPosition) - for _, obj in ipairs(searchArea(origin, {2, 1, 3.2})) do - if isCardOrDeck(obj) then - if obj.hasTag("PlayerCard") then - placeOrMergeIntoDeck(obj, returnGlobalDiscardPosition(), self.getRotation()) - else - placeOrMergeIntoDeck(obj, ENCOUNTER_DISCARD_POSITION, {x = 0, y = -90, z = 0}) - end - -- put chaos tokens back into bag (e.g. Unrelenting) - elseif tokenChecker.isChaosToken(obj) then - local chaosBag = chaosBagApi.findChaosBag() - chaosBag.putObject(obj) - -- don't touch the table or this playmat itself - elseif obj.guid ~= "4ee1f2" and obj ~= self then - TRASHCAN.putObject(obj) +-- handles discarding for a list of objects +---@param objList Table List of objects to discard +function discardListOfObjects(objList) + for _, obj in ipairs(objList) do + if isCardOrDeck(obj) then + if obj.hasTag("PlayerCard") then + placeOrMergeIntoDeck(obj, returnGlobalDiscardPosition(), self.getRotation()) + else + placeOrMergeIntoDeck(obj, ENCOUNTER_DISCARD_POSITION, {x = 0, y = -90, z = 0}) end + -- put chaos tokens back into bag (e.g. Unrelenting) + elseif tokenChecker.isChaosToken(obj) then + local chaosBag = chaosBagApi.findChaosBag() + chaosBag.putObject(obj) + -- don't touch locked objects (like the table etc.) + elseif not obj.getLock() then + ownedObjects.Trash.putObject(obj) end end end @@ -432,48 +297,51 @@ function placeOrMergeIntoDeck(obj, pos, rot) if not pos then return end local offset = 0.5 - local deck, card, newPos -- search the new position for existing card/deck local searchResult = searchArea(pos, { 1, 1, 1 }, isCardOrDeck) - if #searchResult == 1 then - local match = searchResult[1] - if match.type == 'Card' then - card = match - elseif match.type == 'Deck' then - deck = match - end - end - -- update vertical component of new position - if card or deck then + -- get new position + local newPos + if #searchResult == 1 then local bounds = searchResult[1].getBounds() newPos = Vector(pos):setAt("y", bounds.center.y + bounds.size.y / 2 + offset) else newPos = Vector(pos) + Vector(0, offset, 0) end - -- actual movement of the object + -- allow moving the objects smoothly out of the hand + obj.use_hands = false + if rot then obj.setRotationSmooth(rot, false, true) end obj.setPositionSmooth(newPos, false, true) - - -- this avoids a TTS bug that merges unrelated cards that are not resting - if deck then - Wait.time(function() deck.putObject(obj) end, 0.3) - elseif card then - Wait.time(function() obj.setPosition(newPos) end, 0.3) - end + + -- continue if the card stops smooth moving + Wait.condition( + function() + obj.use_hands = true + -- this avoids a TTS bug that merges unrelated cards that are not resting + if #searchResult == 1 and searchResult[1] ~= obj then + -- call this with avoiding errors (physics is sometimes too fast so the object doesn't exist for the put) + pcall(function() searchResult[1].putObject(obj) end) + end + end, + function() return not obj.isSmoothMoving() end, 3) end -- build a discard button to discard from searchPosition (number must be unique) function makeDiscardButton(xValue, number) local position = { xValue, 0.1, -0.94} local searchPosition = {-position[1], position[2], position[3] + 0.32} - local handler = makeDiscardHandlerFor(searchPosition) local handlerName = 'handler' .. number - self.setVar(handlerName, handler) + self.setVar(handlerName, function() + local cardSizeSearch = {2, 1, 3.2} + local globalSearchPosition = self.positionToWorld(searchPosition) + local searchResult = searchArea(globalSearchPosition, cardSizeSearch) + return discardListOfObjects(searchResult) + end) self.createButton({ label = "Discard", click_function = handlerName, @@ -557,10 +425,10 @@ function doUpkeep(_, clickedByColor, isRightClick) -- gain a resource (or two if playing Jenny Barnes) if string.match(activeInvestigatorId, "%d%d%d%d%d") == "02003" then - gainResources(2) + updateCounter({type = "ResourceCounter", modifier = 2}) printToColor("Gaining 2 resources (Jenny)", messageColor) else - gainResources(1) + updateCounter({type = "ResourceCounter", modifier = 1}) end -- draw a card (with handling for Patrice and Forced Learning) @@ -586,18 +454,6 @@ function doUpkeep(_, clickedByColor, isRightClick) end end --- adds the specified amount of resources to the resource counter -function gainResources(amount) - local count = RESOURCE_COUNTER.getVar("val") - local add = tonumber(amount) or 0 - RESOURCE_COUNTER.call("updateVal", count + add) -end - --- returns the resource counter amount -function getResourceCount() - return RESOURCE_COUNTER.getVar("val") -end - -- function for "draw 1 button" (that can be added via option panel) function doDrawOne(_, color) -- send messages to player who clicked button if no seated player found @@ -607,78 +463,113 @@ end -- draw X cards (shuffle discards if necessary) function drawCardsWithReshuffle(numCards) - getDrawDiscardDecks() + local deckAreaObjects = getDeckAreaObjects() -- Norman Withers handling - if string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then - local harbinger = false - if topCard ~= nil and topCard.getName() == "The Harbinger" then harbinger = true - elseif drawDeck ~= nil and not drawDeck.is_face_down then - local cards = drawDeck.getObjects() - if cards[#cards].name == "The Harbinger" then harbinger = true end + local harbinger = false + if deckAreaObjects.topCard and deckAreaObjects.topCard.getName() == "The Harbinger" then + harbinger = true + elseif deckAreaObjects.draw and not deckAreaObjects.draw.is_face_down then + local cards = deckAreaObjects.draw.getObjects() + if cards[#cards].name == "The Harbinger" then + harbinger = true end + end - if harbinger then - printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) + if harbinger then + printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) + return + end + + local topCardDetected = false + if deckAreaObjects.topCard ~= nil then + deckAreaObjects.topCard.deal(1, playerColor) + topCardDetected = true + numCards = numCards - 1 + if numCards == 0 then + flipTopCardFromDeck() return end - - if topCard ~= nil then - topCard.deal(numCards, playerColor) - numCards = numCards - 1 - if numCards == 0 then return end - end end local deckSize = 1 - if drawDeck == nil then + if deckAreaObjects.draw == nil then deckSize = 0 - elseif drawDeck.tag == "Deck" then - deckSize = #drawDeck.getObjects() + elseif deckAreaObjects.draw.type == "Deck" then + deckSize = #deckAreaObjects.draw.getObjects() end if deckSize >= numCards then drawCards(numCards) - return + -- flip top card again for Norman + if topCardDetected and string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then + flipTopCardFromDeck() + end + else + drawCards(deckSize) + if deckAreaObjects.discard ~= nil then + shuffleDiscardIntoDeck() + Wait.time(function() + drawCards(numCards - deckSize) + -- flip top card again for Norman + if topCardDetected and string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then + flipTopCardFromDeck() + end + end, 1) + end + printToColor("Take 1 horror (drawing card from empty deck)", messageColor) end - - drawCards(deckSize) - if discardPile ~= nil then - shuffleDiscardIntoDeck() - Wait.time(|| drawCards(numCards - deckSize), 1) - end - printToColor("Take 1 horror (drawing card from empty deck)", messageColor) end --- get the draw deck and discard pile objects -function getDrawDiscardDecks() - drawDeck = nil - discardPile = nil - topCard = nil - +-- get the draw deck and discard pile objects and returns the references +function getDeckAreaObjects() + local deckAreaObjects = {} for _, object in ipairs(searchDeckAndDiscardArea(isCardOrDeck)) do if self.positionToLocal(object.getPosition()).z > 0.5 then - discardPile = object + deckAreaObjects.discard = object -- Norman Withers handling - elseif string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" and not object.is_face_down then - topCard = object + elseif object.type == "Card" and not object.is_face_down then + deckAreaObjects.topCard = object else - drawDeck = object + deckAreaObjects.draw = object end end + return deckAreaObjects end function drawCards(numCards) - if drawDeck == nil then return end - drawDeck.deal(numCards, playerColor) + local deckAreaObjects = getDeckAreaObjects() + if deckAreaObjects.draw then + deckAreaObjects.draw.deal(numCards, playerColor) + end end function shuffleDiscardIntoDeck() - if not discardPile.is_face_down then discardPile.flip() end - discardPile.shuffle() - discardPile.setPositionSmooth(self.positionToWorld(DRAW_DECK_POSITION), false, false) - drawDeck = discardPile - discardPile = nil + local deckAreaObjects = getDeckAreaObjects() + if not deckAreaObjects.discard.is_face_down then + deckAreaObjects.discard.flip() + end + deckAreaObjects.discard.shuffle() + deckAreaObjects.discard.setPositionSmooth(self.positionToWorld(DRAW_DECK_POSITION), false, false) +end + +-- utility function for Norman Withers to flip the top card to the revealed side +function flipTopCardFromDeck() + Wait.time(function() + local deckAreaObjects = getDeckAreaObjects() + if deckAreaObjects.topCard then + return + elseif deckAreaObjects.draw then + if deckAreaObjects.draw.type == "Card" then + deckAreaObjects.draw.flip() + else + -- get bounds to know the height of the deck + local bounds = deckAreaObjects.draw.getBounds() + local pos = bounds.center + Vector(0, bounds.size.y / 2 + 0.2, 0) + deckAreaObjects.draw.takeObject({ position = pos, flip = true }) + end + end + end, 0.1) end -- discard a random non-hidden card from hand @@ -741,32 +632,8 @@ function changeColor(clickedByColor) -- show the option dialog for color selection to the player that triggered this Player[clickedByColor].showOptionsDialog("Select a new color:", colorList, _, function(color) - local HAND_ZONE_GUIDS = { - "a70eee", -- White - "5fe087", -- Orange - "0285cc", -- Green - "be2f17" -- Red - } - local index - local startPos = self.getPosition() - - -- get respective hand zone by position - if startPos.x < -42 then - if startPos.z > 0 then - index = 1 - else - index = 2 - end - else - if startPos.z > 0 then - index = 3 - else - index = 4 - end - end - -- update the color of the hand zone - local handZone = getObjectFromGUID(HAND_ZONE_GUIDS[index]) + local handZone = ownedObjects.HandZone handZone.setValue(color) -- if the seated player clicked this, reseat him to the new color @@ -830,17 +697,17 @@ function spawnTokensFor(object) tokenManager.spawnForCard(object, extraUses) end -function onCollisionEnter(collision_info) - local object = collision_info.collision_object - - -- detect if "Dream-Enhancing Serum" is placed - if object.getName() == "Dream-Enhancing Serum" then isDES = true end +function onCollisionEnter(collisionInfo) + local object = collisionInfo.collision_object -- only continue if loading is completed if not collisionEnabled then return end -- only continue for cards - if object.type ~= "Card" then return end + if not isCard(object) then return end + + -- detect if "Dream-Enhancing Serum" is placed + if object.getName() == "Dream-Enhancing Serum" then isDES = true end maybeUpdateActiveInvestigator(object) syncCustomizableMetadata(object) @@ -855,8 +722,8 @@ function onCollisionEnter(collision_info) end -- detect if "Dream-Enhancing Serum" is removed -function onCollisionExit(collision_info) - if collision_info.collision_object.getName() == "Dream-Enhancing Serum" then isDES = false end +function onCollisionExit(collisionInfo) + if collisionInfo.collision_object.getName() == "Dream-Enhancing Serum" then isDES = false end end -- checks if tokens should be spawned for the provided card @@ -892,14 +759,12 @@ function shouldSpawnTokens(card) end function onObjectEnterContainer(container, object) - Wait.frames(function() resetTokensIfInDeckZone(container, object) end, 1) -end + if not isCard(object) then return end -function resetTokensIfInDeckZone(container, object) - local pos = self.positionToLocal(container.getPosition()) - if inArea(pos, DECK_DISCARD_AREA) then + local localCardPos = self.positionToLocal(object.getPosition()) + if inArea(localCardPos, DECK_DISCARD_AREA) then tokenManager.resetTokensSpawned(object) - removeTokensFromObject(container) + removeTokensFromObject(object) end end @@ -914,7 +779,7 @@ function removeTokensFromObject(object) obj.getLock() == false and obj.getDescription() ~= "Action Token" and not tokenChecker.isChaosToken(obj) then - TRASHCAN.putObject(obj) + ownedObjects.Trash.putObject(obj) end end end @@ -933,11 +798,16 @@ function maybeUpdateActiveInvestigator(card) if notes.id == activeInvestigatorId then return end class = notes.class activeInvestigatorId = notes.id - STAT_TRACKER.call("updateStats", {notes.willpowerIcons, notes.intellectIcons, notes.combatIcons, notes.agilityIcons}) + ownedObjects.InvestigatorSkillTracker.call("updateStats", { + notes.willpowerIcons, + notes.intellectIcons, + notes.combatIcons, + notes.agilityIcons + }) elseif activeInvestigatorId ~= "00000" then class = "Neutral" activeInvestigatorId = "00000" - STAT_TRACKER.call("updateStats", {1, 1, 1, 1}) + ownedObjects.InvestigatorSkillTracker.call("updateStats", {1, 1, 1, 1}) else return end @@ -984,6 +854,40 @@ function setObjectState(obj, stateId) if obj.getStateId() ~= stateId then obj.setState(stateId) end end +--------------------------------------------------------- +-- manipulation of owned objects +--------------------------------------------------------- + +-- updates the specific owned counter +---@param param Table Contains the information to update: +--- type: String Counter to target +--- newValue: Number Value to set the counter to +--- modifier: Number If newValue is not provided, the existing value will be adjusted by this modifier +function updateCounter(param) + local counter = ownedObjects[param.type] + if counter ~= nil then + counter.call("updateVal", param.newValue or (counter.getVar("val") + param.modifier)) + else + printToAll(param.type .. " for " .. matColor .. " could not be found.", "Yellow") + end +end + +-- returns the resource counter amount +---@param type String Counter to target +function getCounterValue(type) + return ownedObjects[type].getVar("val") +end + +-- set investigator skill tracker to "1, 1, 1, 1" +function resetSkillTracker() + local obj = ownedObjects.InvestigatorSkillTracker + if obj ~= nil then + obj.call("updateStats", { 1, 1, 1, 1 }) + else + printToAll("Skill tracker for " .. matColor .. " playmat could not be found.", "Yellow") + end +end + --------------------------------------------------------- -- calls to 'Global' / functions for calls from outside --------------------------------------------------------- @@ -1031,34 +935,28 @@ function showDrawButton(visible) end end --- Spawns / destroys a clickable clue counter for this playmat with the correct amount of clues ----@param showCounter Boolean Whether the clickable clue counter should be present +-- shows / hides a clickable clue counter for this playmat and sets the correct amount of clues +---@param showCounter Boolean Whether the clickable clue counter should be visible function clickableClues(showCounter) - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - local clickerPos = CLUE_CLICKER.getPosition() + local clickerPos = ownedObjects.ClickableClueCounter.getPosition() local clueCount = 0 + + -- move clue counters + local modY = showCounter and 0.525 or -0.525 + ownedObjects.ClickableClueCounter.setPosition(clickerPos + Vector(0, modY, 0)) if showCounter then -- current clue count - clueCount = CLUE_COUNTER.getVar("exposedValue") + clueCount = ownedObjects.ClueCounter.getVar("exposedValue") -- remove clues - CLUE_COUNTER.call("removeAllClues") + ownedObjects.ClueCounter.call("removeAllClues", ownedObjects.Trash) -- set value for clue clickers - CLUE_CLICKER.call("updateVal", clueCount) - - -- move clue counters up - clickerPos.y = 1.52 - CLUE_CLICKER.setPosition(clickerPos) + ownedObjects.ClickableClueCounter.call("updateVal", clueCount) else -- current clue count - clueCount = CLUE_CLICKER.getVar("val") - - -- move clue counters down - clickerPos.y = 1.3 - CLUE_CLICKER.setPosition(clickerPos) + clueCount = ownedObjects.ClickableClueCounter.getVar("val") -- spawn clues local pos = self.positionToWorld({x = -1.12, y = 0.05, z = 0.7}) @@ -1071,26 +969,18 @@ end -- removes all clues (moving tokens to the trash and setting counters to 0) function removeClues() - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - - CLUE_COUNTER.call("removeAllClues") - CLUE_CLICKER.call("updateVal", 0) + ownedObjects.ClueCounter.call("removeAllClues", ownedObjects.Trash) + ownedObjects.ClickableClueCounter.call("updateVal", 0) end -- reports the clue count ---@param useClickableCounters Boolean Controls which type of counter is getting checked function getClueCount(useClickableCounters) - local count = 0 - if useClickableCounters then - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - count = tonumber(CLUE_CLICKER.getVar("val")) + return ownedObjects.ClickableClueCounter.getVar("val") else - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - count = tonumber(CLUE_COUNTER.getVar("exposedValue")) + return ownedObjects.ClueCounter.getVar("exposedValue") end - return count end -- Sets this playermat's snap points to limit snapping to matching card types or not. If matchTypes @@ -1149,113 +1039,35 @@ function updatePlayerCards(args) local playerCardData = customDataHelper.getTable("PLAYER_CARD_DATA") tokenManager.addPlayerCardData(playerCardData) end - --- utility function for rounding ----@param num Number Initial value ----@param numDecimalPlaces Number Amount of decimal places -function round(num, numDecimalPlaces) - local mult = 10^(numDecimalPlaces or 0) - return math.floor(num * mult + 0.5) / mult -end end) -__bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local ChaosBagApi = {} + local GUIDReferenceApi = {} - -- 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) + local function getGuidHandler() + return getObjectFromGUID("123456") 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 + -- 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 - -- checks scripting zone for chaos bag (also called by a lot of objects!) - ChaosBagApi.findChaosBag = function() - return Global.call("findChaosBag") + -- 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 a table of object references to the tokens in play (does not include sealed tokens!) - ChaosBagApi.getTokensInPlay = function() - return Global.getTable("chaosTokens") + -- 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 - -- 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/NavigationOverlayApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local NavigationOverlayApi = {} - local HANDLER_GUID = "797ede" - - -- Copies the visibility for the Navigation overlay - ---@param startColor String Color of the player to copy from - ---@param targetColor String Color of the targeted player - NavigationOverlayApi.copyVisibility = function(startColor, targetColor) - getObjectFromGUID(HANDLER_GUID).call("copyVisibility", { - startColor = startColor, - targetColor = targetColor - }) - end - - -- Changes the Navigation Overlay view ("Full View" --> "Play Areas" --> "Closed" etc.) - ---@param playerColor String Color of the player to update the visibility for - NavigationOverlayApi.cycleVisibility = function(playerColor) - getObjectFromGUID(HANDLER_GUID).call("cycleVisibility", playerColor) - end - - return NavigationOverlayApi + return GUIDReferenceApi end end) __bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) @@ -1298,6 +1110,7 @@ end end) __bundle_register("core/token/TokenManager", function(require, _LOADED, __bundle_register, __bundle_modules) do + local guidReferenceApi = require("core/GUIDReferenceApi") local optionPanelApi = require("core/OptionPanelApi") local playAreaApi = require("core/PlayAreaApi") local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") @@ -1418,15 +1231,10 @@ do ["supply"] = 7 } - -- Source for tokens - local TOKEN_SOURCE_GUID = "124381" - -- Table of data extracted from the token source bag, keyed by the Memo on each token which -- should match the token type keys ("resource", "clue", etc) local tokenTemplates - local DATA_HELPER_GUID = "708279" - local playerCardData local locationData @@ -1524,9 +1332,11 @@ do -- Copy the offsets to make sure we don't change the static values local baseOffsets = offsets offsets = { } + + -- get a vector for the shifting (downwards local to the card) + local shiftDownVector = Vector(0, 0, shiftDown):rotateOver("y", card.getRotation().y) for i, baseOffset in ipairs(baseOffsets) do - offsets[i] = baseOffset - offsets[i][3] = offsets[i][3] + shiftDown + offsets[i] = baseOffset + shiftDownVector end end @@ -1639,8 +1449,8 @@ do if tokenTemplates ~= nil then return end - tokenTemplates = { } - local tokenSource = getObjectFromGUID(TOKEN_SOURCE_GUID) + tokenTemplates = {} + local tokenSource = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSource") for _, tokenTemplate in ipairs(tokenSource.getData().ContainedObjects) do local tokenName = tokenTemplate.Memo tokenTemplates[tokenName] = tokenTemplate @@ -1652,7 +1462,7 @@ do if playerCardData ~= nil then return end - local dataHelper = getObjectFromGUID(DATA_HELPER_GUID) + local dataHelper = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") playerCardData = dataHelper.getTable('PLAYER_CARD_DATA') locationData = dataHelper.getTable('LOCATIONS_DATA') end @@ -1667,18 +1477,16 @@ do if uses == nil then return end -- go through tokens to spawn - local type, token, tokenCount + local tokenCount for i, useInfo in ipairs(uses) do - type = useInfo.type - token = useInfo.token - tokenCount = (useInfo.count or 0) - + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() - if extraUses ~= nil and extraUses[type] ~= nil then - tokenCount = tokenCount + extraUses[type] + tokenCount = (useInfo.count or 0) + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() + if extraUses ~= nil and extraUses[useInfo.type] ~= nil then + tokenCount = tokenCount + extraUses[useInfo.type] end -- Shift each spawned group after the first down so they don't pile on each other - TokenManager.spawnTokenGroup(card, token, tokenCount, (i - 1) * 0.8, type) + TokenManager.spawnTokenGroup(card, useInfo.token, tokenCount, (i - 1) * 0.8, useInfo.type) end + tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -1702,9 +1510,8 @@ do ---@param playerData Table Player card data structure retrieved from the DataHelper. Should be -- the right data for this card. internal.spawnPlayerCardTokensFromDataHelper = function(card, playerData) - token = playerData.tokenType - tokenCount = playerData.tokenCount - --log("Spawning data helper tokens for "..card.getName()..'['..card.getDescription()..']: '..tokenCount.."x "..token) + local token = playerData.tokenType + local tokenCount = playerData.tokenCount TokenManager.spawnTokenGroup(card, token, tokenCount) tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -1737,7 +1544,6 @@ do return 0 end - --log(card.getName() .. ' : ' .. locationData.type .. ' : ' .. locationData.value .. ' : ' .. locationData.clueSide) if ((card.is_face_down and locationData.clueSide == 'back') or (not card.is_face_down and locationData.clueSide == 'front')) then if locationData.type == 'fixed' then @@ -1847,6 +1653,104 @@ do return TokenManager end end) +__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local TokenSpawnTracker = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getSpawnTracker() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSpawnTracker") + end + + TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) + return getSpawnTracker().call("hasSpawnedTokens", cardGuid) + end + + TokenSpawnTracker.markTokensSpawned = function(cardGuid) + return getSpawnTracker().call("markTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetTokensSpawned = function(cardGuid) + return getSpawnTracker().call("resetTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetAllAssetAndEvents = function() + return getSpawnTracker().call("resetAllAssetAndEvents") + end + + TokenSpawnTracker.resetAllLocations = function() + return getSpawnTracker().call("resetAllLocations") + end + + TokenSpawnTracker.resetAll = function() + return getSpawnTracker().call("resetAll") + end + + return TokenSpawnTracker +end +end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playermat/Playmat") +end) +__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local MythosAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end + + -- returns the chaos token metadata (if provided through scenario reference card) + MythosAreaApi.returnTokenData = function() + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") + end + + -- draw an encounter card to the requested position/rotation + MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) + getMythosArea().call("drawEncounterCard", { + pos = pos, + rotY = rotY, + alwaysFaceUp = alwaysFaceUp + }) + end + + return MythosAreaApi +end +end) +__bundle_register("core/NavigationOverlayApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local NavigationOverlayApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getNOHandler() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "NavigationOverlayHandler") + end + + -- Copies the visibility for the Navigation overlay + ---@param startColor String Color of the player to copy from + ---@param targetColor String Color of the targeted player + NavigationOverlayApi.copyVisibility = function(startColor, targetColor) + getNOHandler().call("copyVisibility", { + startColor = startColor, + targetColor = targetColor + }) + end + + -- Changes the Navigation Overlay view ("Full View" --> "Play Areas" --> "Closed" etc.) + ---@param playerColor String Color of the player to update the visibility for + NavigationOverlayApi.cycleVisibility = function(playerColor) + getNOHandler().call("cycleVisibility", playerColor) + end + + return NavigationOverlayApi +end +end) __bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local OptionPanelApi = {} @@ -1865,36 +1769,192 @@ do return OptionPanelApi end end) -__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local TokenSpawnTracker = { } - local SPAWN_TRACKER_GUID = "e3ffc9" + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("hasSpawnedTokens", cardGuid) + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") end - TokenSpawnTracker.markTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("markTokensSpawned", cardGuid) + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") end - TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetTokensSpawned", cardGuid) + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") end - TokenSpawnTracker.resetAllAssetAndEvents = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllAssetAndEvents") + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) end - TokenSpawnTracker.resetAllLocations = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllLocations") + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) end - TokenSpawnTracker.resetAll = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAll") + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) end - return TokenSpawnTracker + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi +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.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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Playermat 3 Green 383d8b.yaml b/unpacked/Custom_Tile Playermat 3 Green 383d8b.yaml index d85d86fa8..eed21e7e1 100644 --- a/unpacked/Custom_Tile Playermat 3 Green 383d8b.yaml +++ b/unpacked/Custom_Tile Playermat 3 Green 383d8b.yaml @@ -224,6 +224,7 @@ Locked: true LuaScript: !include 'Custom_Tile Playermat 3 Green 383d8b.ttslua' LuaScriptState: '{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Green"}' MeasureMovement: false +Memo: Green Name: Custom_Tile Nickname: 'Playermat 3: Green' Snap: true diff --git a/unpacked/Custom_Tile Playermat 4 Red 0840d5.ttslua b/unpacked/Custom_Tile Playermat 4 Red 0840d5.ttslua index a88e2d250..7141e5b27 100644 --- a/unpacked/Custom_Tile Playermat 4 Red 0840d5.ttslua +++ b/unpacked/Custom_Tile Playermat 4 Red 0840d5.ttslua @@ -41,28 +41,74 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("core/NavigationOverlayApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local NavigationOverlayApi = {} - local HANDLER_GUID = "797ede" + local TokenSpawnTracker = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - -- Copies the visibility for the Navigation overlay - ---@param startColor String Color of the player to copy from - ---@param targetColor String Color of the targeted player - NavigationOverlayApi.copyVisibility = function(startColor, targetColor) - getObjectFromGUID(HANDLER_GUID).call("copyVisibility", { - startColor = startColor, - targetColor = targetColor + local function getSpawnTracker() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSpawnTracker") + end + + TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) + return getSpawnTracker().call("hasSpawnedTokens", cardGuid) + end + + TokenSpawnTracker.markTokensSpawned = function(cardGuid) + return getSpawnTracker().call("markTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetTokensSpawned = function(cardGuid) + return getSpawnTracker().call("resetTokensSpawned", cardGuid) + end + + TokenSpawnTracker.resetAllAssetAndEvents = function() + return getSpawnTracker().call("resetAllAssetAndEvents") + end + + TokenSpawnTracker.resetAllLocations = function() + return getSpawnTracker().call("resetAllLocations") + end + + TokenSpawnTracker.resetAll = function() + return getSpawnTracker().call("resetAll") + end + + return TokenSpawnTracker +end +end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playermat/Playmat") +end) +__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local MythosAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end + + -- returns the chaos token metadata (if provided through scenario reference card) + MythosAreaApi.returnTokenData = function() + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") + end + + -- draw an encounter card to the requested position/rotation + MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) + getMythosArea().call("drawEncounterCard", { + pos = pos, + rotY = rotY, + alwaysFaceUp = alwaysFaceUp }) end - -- Changes the Navigation Overlay view ("Full View" --> "Play Areas" --> "Closed" etc.) - ---@param playerColor String Color of the player to update the visibility for - NavigationOverlayApi.cycleVisibility = function(playerColor) - getObjectFromGUID(HANDLER_GUID).call("cycleVisibility", playerColor) - end - - return NavigationOverlayApi + return MythosAreaApi end end) __bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) @@ -103,8 +149,37 @@ do return TokenChecker end end) +__bundle_register("core/NavigationOverlayApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local NavigationOverlayApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getNOHandler() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "NavigationOverlayHandler") + end + + -- Copies the visibility for the Navigation overlay + ---@param startColor String Color of the player to copy from + ---@param targetColor String Color of the targeted player + NavigationOverlayApi.copyVisibility = function(startColor, targetColor) + getNOHandler().call("copyVisibility", { + startColor = startColor, + targetColor = targetColor + }) + end + + -- Changes the Navigation Overlay view ("Full View" --> "Play Areas" --> "Closed" etc.) + ---@param playerColor String Color of the player to update the visibility for + NavigationOverlayApi.cycleVisibility = function(playerColor) + getNOHandler().call("cycleVisibility", playerColor) + end + + return NavigationOverlayApi +end +end) __bundle_register("core/token/TokenManager", function(require, _LOADED, __bundle_register, __bundle_modules) do + local guidReferenceApi = require("core/GUIDReferenceApi") local optionPanelApi = require("core/OptionPanelApi") local playAreaApi = require("core/PlayAreaApi") local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") @@ -225,15 +300,10 @@ do ["supply"] = 7 } - -- Source for tokens - local TOKEN_SOURCE_GUID = "124381" - -- Table of data extracted from the token source bag, keyed by the Memo on each token which -- should match the token type keys ("resource", "clue", etc) local tokenTemplates - local DATA_HELPER_GUID = "708279" - local playerCardData local locationData @@ -331,9 +401,11 @@ do -- Copy the offsets to make sure we don't change the static values local baseOffsets = offsets offsets = { } + + -- get a vector for the shifting (downwards local to the card) + local shiftDownVector = Vector(0, 0, shiftDown):rotateOver("y", card.getRotation().y) for i, baseOffset in ipairs(baseOffsets) do - offsets[i] = baseOffset - offsets[i][3] = offsets[i][3] + shiftDown + offsets[i] = baseOffset + shiftDownVector end end @@ -446,8 +518,8 @@ do if tokenTemplates ~= nil then return end - tokenTemplates = { } - local tokenSource = getObjectFromGUID(TOKEN_SOURCE_GUID) + tokenTemplates = {} + local tokenSource = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSource") for _, tokenTemplate in ipairs(tokenSource.getData().ContainedObjects) do local tokenName = tokenTemplate.Memo tokenTemplates[tokenName] = tokenTemplate @@ -459,7 +531,7 @@ do if playerCardData ~= nil then return end - local dataHelper = getObjectFromGUID(DATA_HELPER_GUID) + local dataHelper = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") playerCardData = dataHelper.getTable('PLAYER_CARD_DATA') locationData = dataHelper.getTable('LOCATIONS_DATA') end @@ -474,18 +546,16 @@ do if uses == nil then return end -- go through tokens to spawn - local type, token, tokenCount + local tokenCount for i, useInfo in ipairs(uses) do - type = useInfo.type - token = useInfo.token - tokenCount = (useInfo.count or 0) - + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() - if extraUses ~= nil and extraUses[type] ~= nil then - tokenCount = tokenCount + extraUses[type] + tokenCount = (useInfo.count or 0) + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() + if extraUses ~= nil and extraUses[useInfo.type] ~= nil then + tokenCount = tokenCount + extraUses[useInfo.type] end -- Shift each spawned group after the first down so they don't pile on each other - TokenManager.spawnTokenGroup(card, token, tokenCount, (i - 1) * 0.8, type) + TokenManager.spawnTokenGroup(card, useInfo.token, tokenCount, (i - 1) * 0.8, useInfo.type) end + tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -509,9 +579,8 @@ do ---@param playerData Table Player card data structure retrieved from the DataHelper. Should be -- the right data for this card. internal.spawnPlayerCardTokensFromDataHelper = function(card, playerData) - token = playerData.tokenType - tokenCount = playerData.tokenCount - --log("Spawning data helper tokens for "..card.getName()..'['..card.getDescription()..']: '..tokenCount.."x "..token) + local token = playerData.tokenType + local tokenCount = playerData.tokenCount TokenManager.spawnTokenGroup(card, token, tokenCount) tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -544,7 +613,6 @@ do return 0 end - --log(card.getName() .. ' : ' .. locationData.type .. ' : ' .. locationData.value .. ' : ' .. locationData.clueSide) if ((card.is_face_down and locationData.clueSide == 'back') or (not card.is_face_down and locationData.clueSide == 'front')) then if locationData.type == 'fixed' then @@ -672,53 +740,121 @@ do return OptionPanelApi end end) -__bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local TokenSpawnTracker = { } - local SPAWN_TRACKER_GUID = "e3ffc9" + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("hasSpawnedTokens", cardGuid) + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") end - TokenSpawnTracker.markTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("markTokensSpawned", cardGuid) + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") end - TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetTokensSpawned", cardGuid) + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") end - TokenSpawnTracker.resetAllAssetAndEvents = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllAssetAndEvents") + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) end - TokenSpawnTracker.resetAllLocations = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllLocations") + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) end - TokenSpawnTracker.resetAll = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAll") + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) end - return TokenSpawnTracker + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) ---------------------------------------------------------- --- specific setup (different for each playmat) ---------------------------------------------------------- - -TRASHCAN_GUID = "4b8594" -STAT_TRACKER_GUID = "e74881" -RESOURCE_COUNTER_GUID = "a4b60d" -CLUE_COUNTER_GUID = "37be78" -CLUE_CLICKER_GUID = "4111de" - -require("playermat/Playmat") -end) __bundle_register("playermat/Playmat", function(require, _LOADED, __bundle_register, __bundle_modules) local chaosBagApi = require("chaosbag/ChaosBagApi") +local guidReferenceApi = require("core/GUIDReferenceApi") local mythosAreaApi = require("core/MythosAreaApi") local navigationOverlayApi = require("core/NavigationOverlayApi") local tokenChecker = require("core/token/TokenChecker") @@ -781,19 +917,19 @@ local DECK_DISCARD_AREA = { }, center = { x = -1.82, - y = 0.1, + y = 0.5, z = 0.305 }, size = { x = 0.4, - y = 0.1, + y = 3, z = 1.1 } } -- local position of draw and discard pile -local DRAW_DECK_POSITION = { x = -1.82, y = 0, z = 0 } -local DISCARD_PILE_POSITION = { x = -1.82, y = 0, z = 0.61 } +local DRAW_DECK_POSITION = { x = -1.82, y = 0.1, z = 0 } +local DISCARD_PILE_POSITION = { x = -1.82, y = 0.1, z = 0.61 } -- global position of encounter discard pile local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38} @@ -801,7 +937,11 @@ local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38} -- global variable so it can be reset by the Clean Up Helper activeInvestigatorId = "00000" -local TRASHCAN, STAT_TRACKER, RESOURCE_COUNTER +-- table of type-object reference pairs of all owned objects +local ownedObjects = {} +local matColor = self.getMemo() + +-- variable to track the status of the "Show Draw Button" option local isDrawButtonVisible = false -- global variable to report "Dream-Enhancing Serum" status @@ -818,9 +958,8 @@ end function onLoad(saveState) self.interactable = DEBUG - TRASHCAN = getObjectFromGUID(TRASHCAN_GUID) - STAT_TRACKER = getObjectFromGUID(STAT_TRACKER_GUID) - RESOURCE_COUNTER = getObjectFromGUID(RESOURCE_COUNTER_GUID) + -- get object references to owned objects + ownedObjects = guidReferenceApi.getObjectsByOwner(matColor) -- button creation for i = 1, 6 do @@ -865,9 +1004,7 @@ function onLoad(saveState) end showDrawButton(isDrawButtonVisible) - collisionEnabled = true - math.randomseed(os.time()) end @@ -883,7 +1020,7 @@ function searchArea(origin, size, filter) orientation = self.getRotation(), type = 3, size = size, - max_distance = 1 + max_distance = 0 }) local objList = {} @@ -900,11 +1037,12 @@ function isCard(x) return x.type == 'Card' end function isDeck(x) return x.type == 'Deck' end function isCardOrDeck(x) return x.type == 'Card' or x.type == 'Deck' end --- Finds all objects on the playmat and associated set aside zone. +-- finds all objects on the playmat and associated set aside zone. function searchAroundSelf(filter) local bounds = self.getBoundsNormalized() -- Increase the width to cover the set aside zone bounds.size.x = bounds.size.x + SEARCH_AROUND_SELF_X_BUFFER + bounds.size.y = 1 -- Since the cast is centered on the position, shift left or right to keep the non-set aside edge -- of the cast at the edge of the playmat -- setAsideDirection accounts for the set aside zone being on the left or right, depending on the @@ -931,30 +1069,35 @@ function doNotReady(card) return card.getVar("do_not_ready") or false end +-- rounds a number to the specified amount of decimal places +---@param num Number Initial value +---@param numDecimalPlaces Number Amount of decimal places +function round(num, numDecimalPlaces) + local mult = 10^(numDecimalPlaces or 0) + return math.floor(num * mult + 0.5) / mult +end + --------------------------------------------------------- -- Discard buttons --------------------------------------------------------- --- builds a function that discards things in searchPosition --- stuff on the card/deck will be put into the local trashcan -function makeDiscardHandlerFor(searchPosition) - return function () - local origin = self.positionToWorld(searchPosition) - for _, obj in ipairs(searchArea(origin, {2, 1, 3.2})) do - if isCardOrDeck(obj) then - if obj.hasTag("PlayerCard") then - placeOrMergeIntoDeck(obj, returnGlobalDiscardPosition(), self.getRotation()) - else - placeOrMergeIntoDeck(obj, ENCOUNTER_DISCARD_POSITION, {x = 0, y = -90, z = 0}) - end - -- put chaos tokens back into bag (e.g. Unrelenting) - elseif tokenChecker.isChaosToken(obj) then - local chaosBag = chaosBagApi.findChaosBag() - chaosBag.putObject(obj) - -- don't touch the table or this playmat itself - elseif obj.guid ~= "4ee1f2" and obj ~= self then - TRASHCAN.putObject(obj) +-- handles discarding for a list of objects +---@param objList Table List of objects to discard +function discardListOfObjects(objList) + for _, obj in ipairs(objList) do + if isCardOrDeck(obj) then + if obj.hasTag("PlayerCard") then + placeOrMergeIntoDeck(obj, returnGlobalDiscardPosition(), self.getRotation()) + else + placeOrMergeIntoDeck(obj, ENCOUNTER_DISCARD_POSITION, {x = 0, y = -90, z = 0}) end + -- put chaos tokens back into bag (e.g. Unrelenting) + elseif tokenChecker.isChaosToken(obj) then + local chaosBag = chaosBagApi.findChaosBag() + chaosBag.putObject(obj) + -- don't touch locked objects (like the table etc.) + elseif not obj.getLock() then + ownedObjects.Trash.putObject(obj) end end end @@ -965,48 +1108,51 @@ function placeOrMergeIntoDeck(obj, pos, rot) if not pos then return end local offset = 0.5 - local deck, card, newPos -- search the new position for existing card/deck local searchResult = searchArea(pos, { 1, 1, 1 }, isCardOrDeck) - if #searchResult == 1 then - local match = searchResult[1] - if match.type == 'Card' then - card = match - elseif match.type == 'Deck' then - deck = match - end - end - -- update vertical component of new position - if card or deck then + -- get new position + local newPos + if #searchResult == 1 then local bounds = searchResult[1].getBounds() newPos = Vector(pos):setAt("y", bounds.center.y + bounds.size.y / 2 + offset) else newPos = Vector(pos) + Vector(0, offset, 0) end - -- actual movement of the object + -- allow moving the objects smoothly out of the hand + obj.use_hands = false + if rot then obj.setRotationSmooth(rot, false, true) end obj.setPositionSmooth(newPos, false, true) - - -- this avoids a TTS bug that merges unrelated cards that are not resting - if deck then - Wait.time(function() deck.putObject(obj) end, 0.3) - elseif card then - Wait.time(function() obj.setPosition(newPos) end, 0.3) - end + + -- continue if the card stops smooth moving + Wait.condition( + function() + obj.use_hands = true + -- this avoids a TTS bug that merges unrelated cards that are not resting + if #searchResult == 1 and searchResult[1] ~= obj then + -- call this with avoiding errors (physics is sometimes too fast so the object doesn't exist for the put) + pcall(function() searchResult[1].putObject(obj) end) + end + end, + function() return not obj.isSmoothMoving() end, 3) end -- build a discard button to discard from searchPosition (number must be unique) function makeDiscardButton(xValue, number) local position = { xValue, 0.1, -0.94} local searchPosition = {-position[1], position[2], position[3] + 0.32} - local handler = makeDiscardHandlerFor(searchPosition) local handlerName = 'handler' .. number - self.setVar(handlerName, handler) + self.setVar(handlerName, function() + local cardSizeSearch = {2, 1, 3.2} + local globalSearchPosition = self.positionToWorld(searchPosition) + local searchResult = searchArea(globalSearchPosition, cardSizeSearch) + return discardListOfObjects(searchResult) + end) self.createButton({ label = "Discard", click_function = handlerName, @@ -1090,10 +1236,10 @@ function doUpkeep(_, clickedByColor, isRightClick) -- gain a resource (or two if playing Jenny Barnes) if string.match(activeInvestigatorId, "%d%d%d%d%d") == "02003" then - gainResources(2) + updateCounter({type = "ResourceCounter", modifier = 2}) printToColor("Gaining 2 resources (Jenny)", messageColor) else - gainResources(1) + updateCounter({type = "ResourceCounter", modifier = 1}) end -- draw a card (with handling for Patrice and Forced Learning) @@ -1119,18 +1265,6 @@ function doUpkeep(_, clickedByColor, isRightClick) end end --- adds the specified amount of resources to the resource counter -function gainResources(amount) - local count = RESOURCE_COUNTER.getVar("val") - local add = tonumber(amount) or 0 - RESOURCE_COUNTER.call("updateVal", count + add) -end - --- returns the resource counter amount -function getResourceCount() - return RESOURCE_COUNTER.getVar("val") -end - -- function for "draw 1 button" (that can be added via option panel) function doDrawOne(_, color) -- send messages to player who clicked button if no seated player found @@ -1140,78 +1274,113 @@ end -- draw X cards (shuffle discards if necessary) function drawCardsWithReshuffle(numCards) - getDrawDiscardDecks() + local deckAreaObjects = getDeckAreaObjects() -- Norman Withers handling - if string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then - local harbinger = false - if topCard ~= nil and topCard.getName() == "The Harbinger" then harbinger = true - elseif drawDeck ~= nil and not drawDeck.is_face_down then - local cards = drawDeck.getObjects() - if cards[#cards].name == "The Harbinger" then harbinger = true end + local harbinger = false + if deckAreaObjects.topCard and deckAreaObjects.topCard.getName() == "The Harbinger" then + harbinger = true + elseif deckAreaObjects.draw and not deckAreaObjects.draw.is_face_down then + local cards = deckAreaObjects.draw.getObjects() + if cards[#cards].name == "The Harbinger" then + harbinger = true end + end - if harbinger then - printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) + if harbinger then + printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) + return + end + + local topCardDetected = false + if deckAreaObjects.topCard ~= nil then + deckAreaObjects.topCard.deal(1, playerColor) + topCardDetected = true + numCards = numCards - 1 + if numCards == 0 then + flipTopCardFromDeck() return end - - if topCard ~= nil then - topCard.deal(numCards, playerColor) - numCards = numCards - 1 - if numCards == 0 then return end - end end local deckSize = 1 - if drawDeck == nil then + if deckAreaObjects.draw == nil then deckSize = 0 - elseif drawDeck.tag == "Deck" then - deckSize = #drawDeck.getObjects() + elseif deckAreaObjects.draw.type == "Deck" then + deckSize = #deckAreaObjects.draw.getObjects() end if deckSize >= numCards then drawCards(numCards) - return + -- flip top card again for Norman + if topCardDetected and string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then + flipTopCardFromDeck() + end + else + drawCards(deckSize) + if deckAreaObjects.discard ~= nil then + shuffleDiscardIntoDeck() + Wait.time(function() + drawCards(numCards - deckSize) + -- flip top card again for Norman + if topCardDetected and string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then + flipTopCardFromDeck() + end + end, 1) + end + printToColor("Take 1 horror (drawing card from empty deck)", messageColor) end - - drawCards(deckSize) - if discardPile ~= nil then - shuffleDiscardIntoDeck() - Wait.time(|| drawCards(numCards - deckSize), 1) - end - printToColor("Take 1 horror (drawing card from empty deck)", messageColor) end --- get the draw deck and discard pile objects -function getDrawDiscardDecks() - drawDeck = nil - discardPile = nil - topCard = nil - +-- get the draw deck and discard pile objects and returns the references +function getDeckAreaObjects() + local deckAreaObjects = {} for _, object in ipairs(searchDeckAndDiscardArea(isCardOrDeck)) do if self.positionToLocal(object.getPosition()).z > 0.5 then - discardPile = object + deckAreaObjects.discard = object -- Norman Withers handling - elseif string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" and not object.is_face_down then - topCard = object + elseif object.type == "Card" and not object.is_face_down then + deckAreaObjects.topCard = object else - drawDeck = object + deckAreaObjects.draw = object end end + return deckAreaObjects end function drawCards(numCards) - if drawDeck == nil then return end - drawDeck.deal(numCards, playerColor) + local deckAreaObjects = getDeckAreaObjects() + if deckAreaObjects.draw then + deckAreaObjects.draw.deal(numCards, playerColor) + end end function shuffleDiscardIntoDeck() - if not discardPile.is_face_down then discardPile.flip() end - discardPile.shuffle() - discardPile.setPositionSmooth(self.positionToWorld(DRAW_DECK_POSITION), false, false) - drawDeck = discardPile - discardPile = nil + local deckAreaObjects = getDeckAreaObjects() + if not deckAreaObjects.discard.is_face_down then + deckAreaObjects.discard.flip() + end + deckAreaObjects.discard.shuffle() + deckAreaObjects.discard.setPositionSmooth(self.positionToWorld(DRAW_DECK_POSITION), false, false) +end + +-- utility function for Norman Withers to flip the top card to the revealed side +function flipTopCardFromDeck() + Wait.time(function() + local deckAreaObjects = getDeckAreaObjects() + if deckAreaObjects.topCard then + return + elseif deckAreaObjects.draw then + if deckAreaObjects.draw.type == "Card" then + deckAreaObjects.draw.flip() + else + -- get bounds to know the height of the deck + local bounds = deckAreaObjects.draw.getBounds() + local pos = bounds.center + Vector(0, bounds.size.y / 2 + 0.2, 0) + deckAreaObjects.draw.takeObject({ position = pos, flip = true }) + end + end + end, 0.1) end -- discard a random non-hidden card from hand @@ -1274,32 +1443,8 @@ function changeColor(clickedByColor) -- show the option dialog for color selection to the player that triggered this Player[clickedByColor].showOptionsDialog("Select a new color:", colorList, _, function(color) - local HAND_ZONE_GUIDS = { - "a70eee", -- White - "5fe087", -- Orange - "0285cc", -- Green - "be2f17" -- Red - } - local index - local startPos = self.getPosition() - - -- get respective hand zone by position - if startPos.x < -42 then - if startPos.z > 0 then - index = 1 - else - index = 2 - end - else - if startPos.z > 0 then - index = 3 - else - index = 4 - end - end - -- update the color of the hand zone - local handZone = getObjectFromGUID(HAND_ZONE_GUIDS[index]) + local handZone = ownedObjects.HandZone handZone.setValue(color) -- if the seated player clicked this, reseat him to the new color @@ -1363,17 +1508,17 @@ function spawnTokensFor(object) tokenManager.spawnForCard(object, extraUses) end -function onCollisionEnter(collision_info) - local object = collision_info.collision_object - - -- detect if "Dream-Enhancing Serum" is placed - if object.getName() == "Dream-Enhancing Serum" then isDES = true end +function onCollisionEnter(collisionInfo) + local object = collisionInfo.collision_object -- only continue if loading is completed if not collisionEnabled then return end -- only continue for cards - if object.type ~= "Card" then return end + if not isCard(object) then return end + + -- detect if "Dream-Enhancing Serum" is placed + if object.getName() == "Dream-Enhancing Serum" then isDES = true end maybeUpdateActiveInvestigator(object) syncCustomizableMetadata(object) @@ -1388,8 +1533,8 @@ function onCollisionEnter(collision_info) end -- detect if "Dream-Enhancing Serum" is removed -function onCollisionExit(collision_info) - if collision_info.collision_object.getName() == "Dream-Enhancing Serum" then isDES = false end +function onCollisionExit(collisionInfo) + if collisionInfo.collision_object.getName() == "Dream-Enhancing Serum" then isDES = false end end -- checks if tokens should be spawned for the provided card @@ -1425,14 +1570,12 @@ function shouldSpawnTokens(card) end function onObjectEnterContainer(container, object) - Wait.frames(function() resetTokensIfInDeckZone(container, object) end, 1) -end + if not isCard(object) then return end -function resetTokensIfInDeckZone(container, object) - local pos = self.positionToLocal(container.getPosition()) - if inArea(pos, DECK_DISCARD_AREA) then + local localCardPos = self.positionToLocal(object.getPosition()) + if inArea(localCardPos, DECK_DISCARD_AREA) then tokenManager.resetTokensSpawned(object) - removeTokensFromObject(container) + removeTokensFromObject(object) end end @@ -1447,7 +1590,7 @@ function removeTokensFromObject(object) obj.getLock() == false and obj.getDescription() ~= "Action Token" and not tokenChecker.isChaosToken(obj) then - TRASHCAN.putObject(obj) + ownedObjects.Trash.putObject(obj) end end end @@ -1466,11 +1609,16 @@ function maybeUpdateActiveInvestigator(card) if notes.id == activeInvestigatorId then return end class = notes.class activeInvestigatorId = notes.id - STAT_TRACKER.call("updateStats", {notes.willpowerIcons, notes.intellectIcons, notes.combatIcons, notes.agilityIcons}) + ownedObjects.InvestigatorSkillTracker.call("updateStats", { + notes.willpowerIcons, + notes.intellectIcons, + notes.combatIcons, + notes.agilityIcons + }) elseif activeInvestigatorId ~= "00000" then class = "Neutral" activeInvestigatorId = "00000" - STAT_TRACKER.call("updateStats", {1, 1, 1, 1}) + ownedObjects.InvestigatorSkillTracker.call("updateStats", {1, 1, 1, 1}) else return end @@ -1517,6 +1665,40 @@ function setObjectState(obj, stateId) if obj.getStateId() ~= stateId then obj.setState(stateId) end end +--------------------------------------------------------- +-- manipulation of owned objects +--------------------------------------------------------- + +-- updates the specific owned counter +---@param param Table Contains the information to update: +--- type: String Counter to target +--- newValue: Number Value to set the counter to +--- modifier: Number If newValue is not provided, the existing value will be adjusted by this modifier +function updateCounter(param) + local counter = ownedObjects[param.type] + if counter ~= nil then + counter.call("updateVal", param.newValue or (counter.getVar("val") + param.modifier)) + else + printToAll(param.type .. " for " .. matColor .. " could not be found.", "Yellow") + end +end + +-- returns the resource counter amount +---@param type String Counter to target +function getCounterValue(type) + return ownedObjects[type].getVar("val") +end + +-- set investigator skill tracker to "1, 1, 1, 1" +function resetSkillTracker() + local obj = ownedObjects.InvestigatorSkillTracker + if obj ~= nil then + obj.call("updateStats", { 1, 1, 1, 1 }) + else + printToAll("Skill tracker for " .. matColor .. " playmat could not be found.", "Yellow") + end +end + --------------------------------------------------------- -- calls to 'Global' / functions for calls from outside --------------------------------------------------------- @@ -1564,34 +1746,28 @@ function showDrawButton(visible) end end --- Spawns / destroys a clickable clue counter for this playmat with the correct amount of clues ----@param showCounter Boolean Whether the clickable clue counter should be present +-- shows / hides a clickable clue counter for this playmat and sets the correct amount of clues +---@param showCounter Boolean Whether the clickable clue counter should be visible function clickableClues(showCounter) - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - local clickerPos = CLUE_CLICKER.getPosition() + local clickerPos = ownedObjects.ClickableClueCounter.getPosition() local clueCount = 0 + + -- move clue counters + local modY = showCounter and 0.525 or -0.525 + ownedObjects.ClickableClueCounter.setPosition(clickerPos + Vector(0, modY, 0)) if showCounter then -- current clue count - clueCount = CLUE_COUNTER.getVar("exposedValue") + clueCount = ownedObjects.ClueCounter.getVar("exposedValue") -- remove clues - CLUE_COUNTER.call("removeAllClues") + ownedObjects.ClueCounter.call("removeAllClues", ownedObjects.Trash) -- set value for clue clickers - CLUE_CLICKER.call("updateVal", clueCount) - - -- move clue counters up - clickerPos.y = 1.52 - CLUE_CLICKER.setPosition(clickerPos) + ownedObjects.ClickableClueCounter.call("updateVal", clueCount) else -- current clue count - clueCount = CLUE_CLICKER.getVar("val") - - -- move clue counters down - clickerPos.y = 1.3 - CLUE_CLICKER.setPosition(clickerPos) + clueCount = ownedObjects.ClickableClueCounter.getVar("val") -- spawn clues local pos = self.positionToWorld({x = -1.12, y = 0.05, z = 0.7}) @@ -1604,26 +1780,18 @@ end -- removes all clues (moving tokens to the trash and setting counters to 0) function removeClues() - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - - CLUE_COUNTER.call("removeAllClues") - CLUE_CLICKER.call("updateVal", 0) + ownedObjects.ClueCounter.call("removeAllClues", ownedObjects.Trash) + ownedObjects.ClickableClueCounter.call("updateVal", 0) end -- reports the clue count ---@param useClickableCounters Boolean Controls which type of counter is getting checked function getClueCount(useClickableCounters) - local count = 0 - if useClickableCounters then - local CLUE_CLICKER = getObjectFromGUID(CLUE_CLICKER_GUID) - count = tonumber(CLUE_CLICKER.getVar("val")) + return ownedObjects.ClickableClueCounter.getVar("val") else - local CLUE_COUNTER = getObjectFromGUID(CLUE_COUNTER_GUID) - count = tonumber(CLUE_COUNTER.getVar("exposedValue")) + return ownedObjects.ClueCounter.getVar("exposedValue") end - return count end -- Sets this playermat's snap points to limit snapping to matching card types or not. If matchTypes @@ -1682,14 +1850,6 @@ function updatePlayerCards(args) local playerCardData = customDataHelper.getTable("PLAYER_CARD_DATA") tokenManager.addPlayerCardData(playerCardData) end - --- utility function for rounding ----@param num Number Initial value ----@param numDecimalPlaces Number Amount of decimal places -function round(num, numDecimalPlaces) - local mult = 10^(numDecimalPlaces or 0) - return math.floor(num * mult + 0.5) / mult -end end) __bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules) do @@ -1767,134 +1927,34 @@ do return ChaosBagApi end end) -__bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local MythosAreaApi = {} - local MYTHOS_AREA_GUID = "9f334f" + local GUIDReferenceApi = {} - -- returns the chaos token metadata (if provided through scenario reference card) - MythosAreaApi.returnTokenData = function() - return getObjectFromGUID(MYTHOS_AREA_GUID).call("returnTokenData") + local function getGuidHandler() + return getObjectFromGUID("123456") end - -- draw an encounter card to the requested position/rotation - MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) - getObjectFromGUID(MYTHOS_AREA_GUID).call("drawEncounterCard", { - pos = pos, - rotY = rotY, - alwaysFaceUp = alwaysFaceUp - }) + -- 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 - return MythosAreaApi -end -end) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" - - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") + -- 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 - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) + -- 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 - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) - end - - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) - end - - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) - end - - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) - end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") - end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi + return GUIDReferenceApi end end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Playermat 4 Red 0840d5.yaml b/unpacked/Custom_Tile Playermat 4 Red 0840d5.yaml index abf385fb0..1cc8094b2 100644 --- a/unpacked/Custom_Tile Playermat 4 Red 0840d5.yaml +++ b/unpacked/Custom_Tile Playermat 4 Red 0840d5.yaml @@ -224,6 +224,7 @@ Locked: true LuaScript: !include 'Custom_Tile Playermat 4 Red 0840d5.ttslua' LuaScriptState: '{"activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Red"}' MeasureMovement: false +Memo: Red Name: Custom_Tile Nickname: 'Playermat 4: Red' Snap: true diff --git a/unpacked/Custom_Tile Token Remover 0a5a29.ttslua b/unpacked/Custom_Tile Token Remover 0a5a29.ttslua index 8e7004e14..efdf8101c 100644 --- a/unpacked/Custom_Tile Token Remover 0a5a29.ttslua +++ b/unpacked/Custom_Tile Token Remover 0a5a29.ttslua @@ -41,12 +41,8 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("util/TokenRemover") -end) __bundle_register("util/TokenRemover", function(require, _LOADED, __bundle_register, __bundle_modules) local zone = nil -local tokenChecker = require("core/token/TokenChecker") -- general code function onSave() @@ -65,10 +61,11 @@ function enable() local scale = self.getScale() zone = spawnObject({ type = "ScriptingTrigger", - position = self.getPosition() + Vector(0, 2.5 + 0.11, 0), + position = self.getPosition() + Vector(0, 3.5 + 0.11, 0), rotation = self.getRotation(), - scale = { scale.x * 2, 5, scale.z * 2 } + scale = { scale.x * 2, 7, scale.z * 2 } }) + zone.setName("TokenDiscardZone") setMenu(false) end @@ -87,53 +84,11 @@ function setMenu(isEnabled) end end -function onObjectEnterScriptingZone(entering, object) - if zone ~= entering then return end - if object == self or object.type == "Deck" or object.type == "Card" then return end - if tokenChecker.isChaosToken(object) then return end - object.destruct() -end - function onPickUp() disable() end end) -__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local CHAOS_TOKEN_NAMES = { - ["Elder Sign"] = true, - ["+1"] = true, - ["0"] = true, - ["-1"] = true, - ["-2"] = true, - ["-3"] = true, - ["-4"] = true, - ["-5"] = true, - ["-6"] = true, - ["-7"] = true, - ["-8"] = true, - ["Skull"] = true, - ["Cultist"] = true, - ["Tablet"] = true, - ["Elder Thing"] = true, - ["Auto-fail"] = true, - ["Bless"] = true, - ["Curse"] = true, - ["Frost"] = true - } - - local TokenChecker = {} - - -- returns true if the passed object is a chaos token (by name) - TokenChecker.isChaosToken = function(obj) - if CHAOS_TOKEN_NAMES[obj.getName()] then - return true - else - return false - end - end - - return TokenChecker -end +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("util/TokenRemover") end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Token Remover 2ba7a5.ttslua b/unpacked/Custom_Tile Token Remover 2ba7a5.ttslua index 8e7004e14..b670f04eb 100644 --- a/unpacked/Custom_Tile Token Remover 2ba7a5.ttslua +++ b/unpacked/Custom_Tile Token Remover 2ba7a5.ttslua @@ -46,7 +46,6 @@ require("util/TokenRemover") end) __bundle_register("util/TokenRemover", function(require, _LOADED, __bundle_register, __bundle_modules) local zone = nil -local tokenChecker = require("core/token/TokenChecker") -- general code function onSave() @@ -65,10 +64,11 @@ function enable() local scale = self.getScale() zone = spawnObject({ type = "ScriptingTrigger", - position = self.getPosition() + Vector(0, 2.5 + 0.11, 0), + position = self.getPosition() + Vector(0, 3.5 + 0.11, 0), rotation = self.getRotation(), - scale = { scale.x * 2, 5, scale.z * 2 } + scale = { scale.x * 2, 7, scale.z * 2 } }) + zone.setName("TokenDiscardZone") setMenu(false) end @@ -87,53 +87,8 @@ function setMenu(isEnabled) end end -function onObjectEnterScriptingZone(entering, object) - if zone ~= entering then return end - if object == self or object.type == "Deck" or object.type == "Card" then return end - if tokenChecker.isChaosToken(object) then return end - object.destruct() -end - function onPickUp() disable() end end) -__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local CHAOS_TOKEN_NAMES = { - ["Elder Sign"] = true, - ["+1"] = true, - ["0"] = true, - ["-1"] = true, - ["-2"] = true, - ["-3"] = true, - ["-4"] = true, - ["-5"] = true, - ["-6"] = true, - ["-7"] = true, - ["-8"] = true, - ["Skull"] = true, - ["Cultist"] = true, - ["Tablet"] = true, - ["Elder Thing"] = true, - ["Auto-fail"] = true, - ["Bless"] = true, - ["Curse"] = true, - ["Frost"] = true - } - - local TokenChecker = {} - - -- returns true if the passed object is a chaos token (by name) - TokenChecker.isChaosToken = function(obj) - if CHAOS_TOKEN_NAMES[obj.getName()] then - return true - else - return false - end - end - - return TokenChecker -end -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Token Remover 39b175.ttslua b/unpacked/Custom_Tile Token Remover 39b175.ttslua index 8e7004e14..b670f04eb 100644 --- a/unpacked/Custom_Tile Token Remover 39b175.ttslua +++ b/unpacked/Custom_Tile Token Remover 39b175.ttslua @@ -46,7 +46,6 @@ require("util/TokenRemover") end) __bundle_register("util/TokenRemover", function(require, _LOADED, __bundle_register, __bundle_modules) local zone = nil -local tokenChecker = require("core/token/TokenChecker") -- general code function onSave() @@ -65,10 +64,11 @@ function enable() local scale = self.getScale() zone = spawnObject({ type = "ScriptingTrigger", - position = self.getPosition() + Vector(0, 2.5 + 0.11, 0), + position = self.getPosition() + Vector(0, 3.5 + 0.11, 0), rotation = self.getRotation(), - scale = { scale.x * 2, 5, scale.z * 2 } + scale = { scale.x * 2, 7, scale.z * 2 } }) + zone.setName("TokenDiscardZone") setMenu(false) end @@ -87,53 +87,8 @@ function setMenu(isEnabled) end end -function onObjectEnterScriptingZone(entering, object) - if zone ~= entering then return end - if object == self or object.type == "Deck" or object.type == "Card" then return end - if tokenChecker.isChaosToken(object) then return end - object.destruct() -end - function onPickUp() disable() end end) -__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local CHAOS_TOKEN_NAMES = { - ["Elder Sign"] = true, - ["+1"] = true, - ["0"] = true, - ["-1"] = true, - ["-2"] = true, - ["-3"] = true, - ["-4"] = true, - ["-5"] = true, - ["-6"] = true, - ["-7"] = true, - ["-8"] = true, - ["Skull"] = true, - ["Cultist"] = true, - ["Tablet"] = true, - ["Elder Thing"] = true, - ["Auto-fail"] = true, - ["Bless"] = true, - ["Curse"] = true, - ["Frost"] = true - } - - local TokenChecker = {} - - -- returns true if the passed object is a chaos token (by name) - TokenChecker.isChaosToken = function(obj) - if CHAOS_TOKEN_NAMES[obj.getName()] then - return true - else - return false - end - end - - return TokenChecker -end -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Tile Token Spawning Reference f8b3a7.yaml b/unpacked/Custom_Tile Token Spawning Reference f8b3a7.yaml new file mode 100644 index 000000000..5dcc800f6 --- /dev/null +++ b/unpacked/Custom_Tile Token Spawning Reference f8b3a7.yaml @@ -0,0 +1,54 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +ColorDiffuse: + b: 0 + g: 0 + r: 0 +CustomImage: + CustomTile: + Stackable: false + Stretch: true + Thickness: 0.2 + Type: 3 + ImageScalar: 1 + ImageSecondaryURL: '' + ImageURL: http://cloud-3.steamusercontent.com/ugc/2172484009093238162/ACF3BBD93CB517B0BD0952E9BB78A2D35A62F377/ + WidthScale: 0 +Description: Press a numpad key to spawn the indicated token. +DragSelectable: true +GMNotes: '' +GUID: f8b3a7 +Grid: true +GridProjection: false +Hands: false +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: true +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Custom_Tile +Nickname: Token Spawning Reference +Snap: true +Sticky: true +Tags: +- CameraZoom_ignore +- CleanUpHelper_ignore +- displacement_excluded +Tooltip: true +Transform: + posX: -48 + posY: 1.48 + posZ: 55 + rotX: 0 + rotY: 270 + rotZ: 0 + scaleX: 3 + scaleY: 1 + scaleZ: 3 +Value: 0 +XmlUI: '' diff --git a/unpacked/Custom_Token BlessCurse Manager 5933fb.ttslua b/unpacked/Custom_Token BlessCurse Manager 5933fb.ttslua index 69355fb7b..177497d7f 100644 --- a/unpacked/Custom_Token BlessCurse Manager 5933fb.ttslua +++ b/unpacked/Custom_Token BlessCurse Manager 5933fb.ttslua @@ -41,6 +41,112 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("chaosbag/BlessCurseManager") end) @@ -480,12 +586,13 @@ end) __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 Variant Parameter to pass local function callIfExistent(functionName, argument) - local tokenArranger = getObjectsWithTag("TokenArranger")[1] + local tokenArranger = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenArranger") if tokenArranger ~= nil then tokenArranger.call(functionName, argument) end @@ -510,80 +617,4 @@ do 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.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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Chaos Bag Manager 023240.ttslua b/unpacked/Custom_Token Chaos Bag Manager 023240.ttslua index 57b159a7e..74208df61 100644 --- a/unpacked/Custom_Token Chaos Bag Manager 023240.ttslua +++ b/unpacked/Custom_Token Chaos Bag Manager 023240.ttslua @@ -41,6 +41,85 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__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("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("accessories/ChaosBagManager") +end) __bundle_register("accessories/ChaosBagManager", function(require, _LOADED, __bundle_register, __bundle_modules) local chaosBagApi = require("chaosbag/ChaosBagApi") @@ -127,83 +206,4 @@ function buttonClick(index, isRightClick) end 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.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("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("accessories/ChaosBagManager") -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Clues 3f22e5.yaml b/unpacked/Custom_Token Clues 3f22e5.yaml index 3532b64e5..fc341431e 100644 --- a/unpacked/Custom_Token Clues 3f22e5.yaml +++ b/unpacked/Custom_Token Clues 3f22e5.yaml @@ -42,7 +42,7 @@ Tags: Tooltip: false Transform: posX: -59.43 - posY: 1.3 + posY: 1 posZ: -22.72 rotX: 0 rotY: 280 diff --git a/unpacked/Custom_Token Clues 4111de.yaml b/unpacked/Custom_Token Clues 4111de.yaml index edf26350f..16d8dba47 100644 --- a/unpacked/Custom_Token Clues 4111de.yaml +++ b/unpacked/Custom_Token Clues 4111de.yaml @@ -42,7 +42,7 @@ Tags: Tooltip: false Transform: posX: -23.89 - posY: 1.3 + posY: 1 posZ: -30.98 rotX: 0 rotY: 190 diff --git a/unpacked/Custom_Token Clues 891403.yaml b/unpacked/Custom_Token Clues 891403.yaml index e60b2f598..49006b521 100644 --- a/unpacked/Custom_Token Clues 891403.yaml +++ b/unpacked/Custom_Token Clues 891403.yaml @@ -42,7 +42,7 @@ Tags: Tooltip: false Transform: posX: -36.87 - posY: 1.3 + posY: 1 posZ: 30.98 rotX: 0 rotY: 10 diff --git a/unpacked/Custom_Token Clues db85d6.yaml b/unpacked/Custom_Token Clues db85d6.yaml index 44189316b..2fb08467f 100644 --- a/unpacked/Custom_Token Clues db85d6.yaml +++ b/unpacked/Custom_Token Clues db85d6.yaml @@ -42,7 +42,7 @@ Tags: Tooltip: false Transform: posX: -59.43 - posY: 1.3 + posY: 1 posZ: 9.39 rotX: 0 rotY: 280 diff --git a/unpacked/Custom_Token Damage eb08d6.ttslua b/unpacked/Custom_Token Damage eb08d6.ttslua index 3e8cdcc2f..85608f361 100644 --- a/unpacked/Custom_Token Damage eb08d6.ttslua +++ b/unpacked/Custom_Token Damage eb08d6.ttslua @@ -41,9 +41,6 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/GenericCounter") -end) __bundle_register("core/GenericCounter", function(require, _LOADED, __bundle_register, __bundle_modules) MIN_VALUE = 0 MAX_VALUE = 99 @@ -100,4 +97,7 @@ function addOrSubtract(_, _, isRightClick) self.editButton({ index = 0, label = tostring(val) }) end end) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/GenericCounter") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Doom Counter 85c4c6.ttslua b/unpacked/Custom_Token Doom Counter 85c4c6.ttslua index d3356ac78..16e949acf 100644 --- a/unpacked/Custom_Token Doom Counter 85c4c6.ttslua +++ b/unpacked/Custom_Token Doom Counter 85c4c6.ttslua @@ -45,6 +45,8 @@ __bundle_register("__root", function(require, _LOADED, __bundle_register, __bund require("core/DoomCounter") end) __bundle_register("core/DoomCounter", function(require, _LOADED, __bundle_register, __bundle_modules) +local guidReferenceApi = require("core/GUIDReferenceApi") + local optionsVisible = false local options = { Agenda = true, @@ -111,10 +113,9 @@ function startReset() if options.Agenda then updateVal(0) end - -- call the "Doom-in-Play"-counter - local DoomInPlayCounter = getObjectFromGUID("652ff3") - if DoomInPlayCounter then - DoomInPlayCounter.call("removeDoom", options) + local doomInPlayCounter = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DoomInPlayCounter") + if doomInPlayCounter then + doomInPlayCounter.call("removeDoom", options) end end @@ -134,4 +135,34 @@ function toggleOptions() end 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Doom Counter 85c4c6.xml b/unpacked/Custom_Token Doom Counter 85c4c6.xml index e83f7e158..27d07db37 100644 --- a/unpacked/Custom_Token Doom Counter 85c4c6.xml +++ b/unpacked/Custom_Token Doom Counter 85c4c6.xml @@ -1,3 +1,4 @@ + @@ -22,4 +23,5 @@ Doom in Playarea Doom on Playermats - \ No newline at end of file + + \ No newline at end of file diff --git a/unpacked/Custom_Token Doom Counter 85c4c6.yaml b/unpacked/Custom_Token Doom Counter 85c4c6.yaml index 039c7479e..ddc8dd039 100644 --- a/unpacked/Custom_Token Doom Counter 85c4c6.yaml +++ b/unpacked/Custom_Token Doom Counter 85c4c6.yaml @@ -35,6 +35,8 @@ Name: Custom_Token Nickname: Doom Counter Snap: true Sticky: true +Tags: +- CleanUpHelper_ignore Tooltip: true Transform: posX: -5.3 diff --git a/unpacked/Custom_Token Investigator Count f182ee.ttslua b/unpacked/Custom_Token Investigator Count f182ee.ttslua index d5e384648..6f38634e6 100644 --- a/unpacked/Custom_Token Investigator Count f182ee.ttslua +++ b/unpacked/Custom_Token Investigator Count f182ee.ttslua @@ -41,6 +41,14 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/ActiveInvestigatorCounter") +end) +__bundle_register("core/ActiveInvestigatorCounter", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/GenericCounter") +MIN_VALUE = 1 +MAX_VALUE = 4 +end) __bundle_register("core/GenericCounter", function(require, _LOADED, __bundle_register, __bundle_modules) MIN_VALUE = 0 MAX_VALUE = 99 @@ -97,12 +105,4 @@ function addOrSubtract(_, _, isRightClick) self.editButton({ index = 0, label = tostring(val) }) end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/ActiveInvestigatorCounter") -end) -__bundle_register("core/ActiveInvestigatorCounter", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/GenericCounter") -MIN_VALUE = 1 -MAX_VALUE = 4 -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Investigator Skill Tracker e74881.ttslua b/unpacked/Custom_Token Investigator Skill Tracker e74881.ttslua index 4e4f723f4..62c6d6787 100644 --- a/unpacked/Custom_Token Investigator Skill Tracker e74881.ttslua +++ b/unpacked/Custom_Token Investigator Skill Tracker e74881.ttslua @@ -41,6 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("playermat/InvestigatorSkillTracker") +end) __bundle_register("playermat/InvestigatorSkillTracker", function(require, _LOADED, __bundle_register, __bundle_modules) local BUTTON_PARAMETERS = {} BUTTON_PARAMETERS.function_owner = self @@ -105,7 +108,4 @@ function updateStats(newStats) for i = 1, 4 do changeButton(i) end end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("playermat/InvestigatorSkillTracker") -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Master Clue Counter 4a3aa4.ttslua b/unpacked/Custom_Token Master Clue Counter 4a3aa4.ttslua index 96c2e3c3b..f8bcd60eb 100644 --- a/unpacked/Custom_Token Master Clue Counter 4a3aa4.ttslua +++ b/unpacked/Custom_Token Master Clue Counter 4a3aa4.ttslua @@ -41,6 +41,267 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi +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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("core/MasterClueCounter") end) @@ -67,11 +328,10 @@ function onLoad(savedData) width = 900, scale = { 1.5, 1.5, 1.5 }, font_size = 650, - font_color = { 0, 0, 0, 100 }, + font_color = { 1, 1, 1, 100 }, color = { 0, 0, 0, 0 } }) - - loopID = Wait.time(sumClues, 2, -1) + Wait.time(sumClues, 2, -1) end -- removes all player clues by calling the respective function from the counting bowls / clickers @@ -87,231 +347,4 @@ function sumClues() self.editButton({ index = 0, label = tostring(count) }) end end) -__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlaymatApi = { } - local internal = { } - - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end - else - if startPos.z > 0 then - return "Green" - else - return "Red" - end - end - end - - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat - PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") - end - - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") - end - - -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") - end - - -- Transforms a local position into a global position - ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat - PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) - end - - -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() - end - - -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat - ---@param playerColor String Color of the calling player (for messages) - PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) - end - - -- Returns the active investigator id - ---@param matColor String Color of the playermat - PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") - end - - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If - -- matchTypes is true, the main card slot snap points will only snap assets, while the - -- investigator area point will only snap Investigators. If matchTypes is false, snap points will - -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("setLimitSnapsByType", matchCardTypes) - end - end - - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("showDrawButton", isDrawButtonVisible) - end - end - - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("clickableClues", showCounter) - end - end - - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. - PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("removeClues") - end - end - - -- Reports the clue count for the requested playermat - ---@param useClickableCounters Boolean Controls which type of counter is getting checked - PlaymatApi.getClueCount = function(useClickableCounters, matColor) - local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) - end - return count - end - - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) - end - end - - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") - end - - -- Discard a non-hidden card from the corresponding player's hand - PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("doDiscardOne") - end - end - - PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do - mat.call("syncAllCustomizableCards") - end - end - - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - - return PlaymatApi -end -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Master Clue Counter 4a3aa4.yaml b/unpacked/Custom_Token Master Clue Counter 4a3aa4.yaml index 016d18927..66c3aca43 100644 --- a/unpacked/Custom_Token Master Clue Counter 4a3aa4.yaml +++ b/unpacked/Custom_Token Master Clue Counter 4a3aa4.yaml @@ -15,7 +15,7 @@ CustomImage: Thickness: 0.1 ImageScalar: 1 ImageSecondaryURL: '' - ImageURL: http://cloud-3.steamusercontent.com/ugc/1758068501357164917/1D06F1DC4D6888B6F57124BD2AFE20D0B0DA15A8/ + ImageURL: http://cloud-3.steamusercontent.com/ugc/784129913444610342/7903BA89870C1656A003FD69C79BFA99BD1AAC24/ WidthScale: 0 Description: Click to remove all clues from all investigators DragSelectable: true @@ -32,11 +32,11 @@ LuaScript: !include 'Custom_Token Master Clue Counter 4a3aa4.ttslua' LuaScriptState: 'false' MeasureMovement: false Name: Custom_Token -Nickname: 'Master Clue Counter - - ' +Nickname: Master Clue Counter Snap: true Sticky: true +Tags: +- CleanUpHelper_ignore Tooltip: true Transform: posX: -5.3 diff --git a/unpacked/Custom_Token Other Doom in Play 652ff3.ttslua b/unpacked/Custom_Token Other Doom in Play 652ff3.ttslua index 3e17f2f88..e84c9b227 100644 --- a/unpacked/Custom_Token Other Doom in Play 652ff3.ttslua +++ b/unpacked/Custom_Token Other Doom in Play 652ff3.ttslua @@ -45,28 +45,27 @@ __bundle_register("__root", function(require, _LOADED, __bundle_register, __bund require("core/DoomInPlayCounter") end) __bundle_register("core/DoomInPlayCounter", function(require, _LOADED, __bundle_register, __bundle_modules) --- common parameters -local castParameters = {} -castParameters.direction = { 0, 1, 0 } -castParameters.type = 3 -castParameters.max_distance = 0 +local guidReferenceApi = require("core/GUIDReferenceApi") +local playmatApi = require("playermat/PlaymatApi") -local zone +local ZONE, TRASH, loopID local doomURL = "https://i.imgur.com/EoL7yaZ.png" local IGNORE_TAG = "DoomCounter_ignore" - --- playermats 1 to 4 -local originAndSize = { - { origin = { -55, 1.6, 16.5 }, size = { 12, 1, 25 } }, - { origin = { -55, 1.6, -16.5 }, size = { 12, 1, 25 } }, - { origin = { -25, 1.6, 27 }, size = { 25, 1, 12 } }, - { origin = { -25, 1.6, -27 }, size = { 25, 1, 12 } } +local TOTAL_PLAY_AREA = { + upperLeft = { + x = -10, + z = -35 + }, + lowerRight = { + x = -60, + z = 35 + } } -- create button, context menu and start loop function onLoad() self.createButton({ - label = tostring(0), + label = "0", click_function = "none", function_owner = self, position = { 0, 0.06, 0 }, @@ -78,78 +77,328 @@ function onLoad() color = { 0, 0, 0, 0 } }) - zone = getObjectFromGUID("a2f932") + TRASH = guidReferenceApi.getObjectByOwnerAndType("Mythos", "Trash") + ZONE = guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayAreaZone") loopID = Wait.time(countDoom, 2, -1) end -- main function function countDoom() - local doom = 0 - for i = 1, 5 do doom = doom + search(i) end - self.editButton({ index = 0, label = tostring(doom) }) + local count = 0 + + -- get doom in play + for _, obj in ipairs(getObjects()) do + count = count + getDoomAmount(obj) + end + + self.editButton({ index = 0, label = tostring(count) }) end --- searches playermats (num = 1-4) or the scripting zone (num = 5) -function search(num) - local val = 0 - if num == 5 then - for _, obj in ipairs(zone.getObjects()) do - val = val + isDoom(obj) - end +-- gets quantity (for stacks) of doom +function getDoomAmount(obj) + if (obj.is_face_down and obj.getCustomObject().image_bottom == doomURL) + and not obj.hasTag(IGNORE_TAG) + and inArea(obj.getPosition(), TOTAL_PLAY_AREA) then + return math.abs(obj.getQuantity()) else - castParameters.origin = originAndSize[num].origin - castParameters.size = originAndSize[num].size - - for _, obj in ipairs(Physics.cast(castParameters)) do - val = val + isDoom(obj.hit_object) - end + return 0 end - return val -end - --- checks an object for the doom image and gets quantity (for stacks) -function isDoom(obj) - if (obj.is_face_down and obj.getCustomObject().image_bottom == doomURL) or - (obj.name == "Custom_Token" and obj.getCustomObject().image == doomURL) then - if not obj.hasTag(IGNORE_TAG) then - return math.abs(obj.getQuantity()) - end - end - return 0 end -- removes doom from playermats / playarea function removeDoom(options) - local trashCan = getObjectFromGUID("70b9f6") local count = 0 - if options.Playermats then - for i = 1, 4 do - castParameters.origin = originAndSize[i].origin - castParameters.size = originAndSize[i].size - for _, obj in ipairs(Physics.cast(castParameters)) do - local obj = obj.hit_object - local amount = isDoom(obj) - if amount > 0 then - trashCan.putObject(obj) - count = count + amount - end - end - end + if options.Playermats then + count = removeDoomFromList(playmatApi.searchAroundPlaymat("All")) broadcastToAll(count .. " doom removed from Playermats.", "White") end - local count = 0 if options.Playarea then - for _, obj in ipairs(zone.getObjects()) do - local amount = isDoom(obj) - if amount > 0 then - trashCan.putObject(obj) - count = count + amount + count = removeDoomFromList(ZONE.getObjects()) + broadcastToAll(count .. " doom removed from Playerarea.", "White") + end +end + +-- removes doom from provided object list and returns the removed amount +function removeDoomFromList(objList) + local count = 0 + for _, obj in ipairs(objList) do + local amount = getDoomAmount(obj) + if amount > 0 then + TRASH.putObject(obj) + count = count + amount + end + end + return count +end + +function inArea(point, bounds) + return (point.x < bounds.upperLeft.x + and point.x > bounds.lowerRight.x + and point.z > bounds.upperLeft.z + and point.z < bounds.lowerRight.z) +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) +__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") + else + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor end end - broadcastToAll(count .. " doom removed from Playarea.", "White") + return result end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor + end + end + end + + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.isDES = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end + end + + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end + end + + -- Returns the position of the discard pile of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDiscardPosition = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end + end + + -- Transforms a local position into a global position + ---@param localPos Table Local position to be transformed + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.transformLocalPosition = function(localPos, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end + end + + -- Returns the rotation of the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnRotation = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end + end + + -- Triggers the Upkeep for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param playerColor String Color of the calling player (for messages) + PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end + end + + -- Returns the active investigator id + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.returnInvestigatorId = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end + end + + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If + -- matchTypes is true, the main card slot snap points will only snap assets, while the + -- investigator area point will only snap Investigators. If matchTypes is false, snap points will + -- be reset to snap all cards. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("setLimitSnapsByType", matchCardTypes) + end + end + + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("showDrawButton", isDrawButtonVisible) + end + end + + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.clickableClues = function(showCounter, matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("clickableClues", showCounter) + end + end + + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.removeClues = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("removeClues") + end + end + + -- Reports the clue count for the requested playmat + ---@param useClickableCounters Boolean Controls which type of counter is getting checked + PlaymatApi.getClueCount = function(useClickableCounters, matColor) + local count = 0 + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) + end + return count + end + + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) + end + end + + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList + end + + -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.doDiscardOne = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doDiscardOne") + end + end + + -- Triggers the metadata sync for all playmats + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in pairs(getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + + return PlaymatApi end end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Playarea 721ba2.ttslua b/unpacked/Custom_Token Play Area 721ba2.ttslua similarity index 85% rename from unpacked/Custom_Token Playarea 721ba2.ttslua rename to unpacked/Custom_Token Play Area 721ba2.ttslua index 5c0c7660c..1e2bdd88b 100644 --- a/unpacked/Custom_Token Playarea 721ba2.ttslua +++ b/unpacked/Custom_Token Play Area 721ba2.ttslua @@ -41,33 +41,149 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end + + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") + end + + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) + end + + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) + end + + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) + end + + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi +end +end) __bundle_register("core/token/TokenSpawnTrackerApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local TokenSpawnTracker = { } - local SPAWN_TRACKER_GUID = "e3ffc9" + local TokenSpawnTracker = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getSpawnTracker() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSpawnTracker") + end TokenSpawnTracker.hasSpawnedTokens = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("hasSpawnedTokens", cardGuid) + return getSpawnTracker().call("hasSpawnedTokens", cardGuid) end TokenSpawnTracker.markTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("markTokensSpawned", cardGuid) + return getSpawnTracker().call("markTokensSpawned", cardGuid) end TokenSpawnTracker.resetTokensSpawned = function(cardGuid) - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetTokensSpawned", cardGuid) + return getSpawnTracker().call("resetTokensSpawned", cardGuid) end TokenSpawnTracker.resetAllAssetAndEvents = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllAssetAndEvents") + return getSpawnTracker().call("resetAllAssetAndEvents") end TokenSpawnTracker.resetAllLocations = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAllLocations") + return getSpawnTracker().call("resetAllLocations") end TokenSpawnTracker.resetAll = function() - return getObjectFromGUID(SPAWN_TRACKER_GUID).call("resetAll") + return getSpawnTracker().call("resetAll") end return TokenSpawnTracker @@ -82,60 +198,56 @@ __bundle_register("core/PlayArea", function(require, _LOADED, __bundle_register, --------------------------------------------------------- -- Location connection directional options -local BIDIRECTIONAL = 0 -local ONE_WAY = 1 -local INCOMING_ONE_WAY = 2 +local BIDIRECTIONAL = 0 +local ONE_WAY = 1 +local INCOMING_ONE_WAY = 2 -- Connector draw parameters -local CONNECTION_THICKNESS = 0.015 +local CONNECTION_THICKNESS = 0.015 local DRAGGING_CONNECTION_THICKNESS = 0.15 -local DRAGGING_CONNECTION_COLOR = { 0.8, 0.8, 0.8, 1 } -local CONNECTION_COLOR = { 0.4, 0.4, 0.4, 1 } -local DIRECTIONAL_ARROW_DISTANCE = 3.5 -local ARROW_ARM_LENGTH = 0.9 -local ARROW_ANGLE = 25 +local DRAGGING_CONNECTION_COLOR = { 0.8, 0.8, 0.8, 1 } +local CONNECTION_COLOR = { 0.4, 0.4, 0.4, 1 } +local DIRECTIONAL_ARROW_DISTANCE = 3.5 +local ARROW_ARM_LENGTH = 0.9 +local ARROW_ANGLE = 25 -- Height to draw the connector lines, places them just above the table and always below cards -local CONNECTION_LINE_Y = 1.529 +local CONNECTION_LINE_Y = 1.529 -- we use this to turn off collision handling until onLoad() is complete -local collisionEnabled = false +local collisionEnabled = false -- used for recreating the link to a custom data helper after image change -customDataHelper = nil +customDataHelper = nil -local DEFAULT_URL = "http://cloud-3.steamusercontent.com/ugc/998015670465071049/FFAE162920D67CF38045EFBD3B85AD0F916147B2/" +local DEFAULT_URL = +"http://cloud-3.steamusercontent.com/ugc/998015670465071049/FFAE162920D67CF38045EFBD3B85AD0F916147B2/" -local SHIFT_OFFSETS = { +local SHIFT_OFFSETS = { left = { x = 0.00, y = 0, z = 7.67 }, right = { x = 0.00, y = 0, z = -7.67 }, up = { x = 6.54, y = 0, z = 0.00 }, down = { x = -6.54, y = 0, z = 0.00 } } -local SHIFT_EXCLUSION = { +local SHIFT_EXCLUSION = { ["b7b45b"] = true, ["f182ee"] = true, ["721ba2"] = true } -local LOC_LINK_EXCLUDE_SCENARIOS = { +local LOC_LINK_EXCLUDE_SCENARIOS = { ["The Witching Hour"] = true, ["The Heart of Madness"] = true } -local tokenManager = require("core/token/TokenManager") -local INVESTIGATOR_COUNTER_GUID = "f182ee" -local PLAY_AREA_ZONE_GUID = "a2f932" - -local clueData = {} -local spawnedLocationGUIDs = {} -local locations = {} -local locationConnections = {} -local draggingGuids = {} -local locationData -local currentScenario - -local missingData = {} -local countedVP = {} +local guidReferenceApi = require("core/GUIDReferenceApi") +local tokenManager = require("core/token/TokenManager") +local clueData = {} +local spawnedLocationGUIDs = {} +local locations = {} +local locationConnections = {} +local draggingGuids = {} +local missingData = {} +local locationData, currentScenario --------------------------------------------------------- -- general code @@ -150,8 +262,8 @@ end function onLoad(saveState) -- records locations we have spawned clues for - local save = JSON.decode(saveState) or { } - locations = save.trackedLocations or { } + local save = JSON.decode(saveState) or {} + locations = save.trackedLocations or {} currentScenario = save.currentScenario self.interactable = false @@ -172,13 +284,13 @@ function updateSurface(newURL) local customInfo = self.getCustomObject() if newURL ~= "" and newURL ~= nil and newURL ~= DEFAULT_URL then - customInfo.image = newURL - broadcastToAll("New Playmat Image Applied", { 0.2, 0.9, 0.2 }) + customInfo.image = newURL + broadcastToAll("New Playmat Image Applied", { 0.2, 0.9, 0.2 }) else - customInfo.image = DEFAULT_URL - broadcastToAll("Default Playmat Image Applied", { 0.2, 0.9, 0.2 }) + customInfo.image = DEFAULT_URL + broadcastToAll("Default Playmat Image Applied", { 0.2, 0.9, 0.2 }) end - + self.setCustomObject(customInfo) local guid = nil @@ -187,7 +299,7 @@ function updateSurface(newURL) self.reload() if guid ~= nil then - Wait.time(function() updateLocations({ guid }) end, 1) + Wait.time(function() updateLocations({ guid }) end, 1) end end @@ -208,12 +320,14 @@ function onCollisionEnter(collisionInfo) if shouldSpawnTokens(card) then tokenManager.spawnForCard(card) end + -- If this card was being dragged, clear the dragging connections. A multi-drag/drop may send -- the dropped card immediately into a deck, so this has to be done here if draggingGuids[card.getGUID()] ~= nil then card.setVectorLines(nil) draggingGuids[card.getGUID()] = nil end + maybeTrackLocation(card) end @@ -226,6 +340,11 @@ function shouldSpawnTokens(card) or metadata.type == "Enemy" or metadata.type == "Treachery" or metadata.weakness + -- hardcoded IDs for "Makeshift Trap" and "Shrine of the Moirai" + -- these cards are events with uses, that attach to encounter cards and thus will enter play in the playarea + -- TODO: probably turn this into a metadata field if we get more cards like that + or metadata.id == "07310" + or metadata.id == "09100" end function onCollisionExit(collisionInfo) @@ -246,20 +365,20 @@ function onObjectPickUp(player, object) -- should be tracking if showLocationLinks() and isInPlayArea(object) and object.getGMNotes() ~= nil and object.getGMNotes() ~= "" then local pickedUpGuid = object.getGUID() - local metadata = JSON.decode(object.getGMNotes()) or { } + local metadata = JSON.decode(object.getGMNotes()) or {} if metadata.type == "Location" then -- onCollisionExit sometimes comes 1 frame after onObjectPickUp (rather than before it or in -- the same frame). This causes a mismatch in the data between dragging the on-table, and -- that one frame draws connectors on the card which then show up as shadows for snap points. -- Waiting ensures we always do thing in the expected Exit->PickUp order Wait.frames(function() - if object.is_face_down then - draggingGuids[pickedUpGuid] = metadata.locationBack - else - draggingGuids[pickedUpGuid] = metadata.locationFront - end - rebuildConnectionList() - end, 2) + if object.is_face_down then + draggingGuids[pickedUpGuid] = metadata.locationBack + else + draggingGuids[pickedUpGuid] = metadata.locationFront + end + rebuildConnectionList() + end, 2) end end end @@ -352,11 +471,11 @@ end -- drawBaseConnections() function rebuildConnectionList() if not showLocationLinks() then - locationConnections = { } + locationConnections = {} return end - local iconCardList = { } + local iconCardList = {} -- Build a list of cards with each icon as their location ID for cardId, metadata in pairs(draggingGuids) do @@ -367,7 +486,7 @@ function rebuildConnectionList() end -- Pair up all the icons - locationConnections = { } + locationConnections = {} for cardId, metadata in pairs(draggingGuids) do buildConnection(cardId, iconCardList, metadata) end @@ -386,7 +505,7 @@ function buildLocListByIcon(cardId, iconCardList, locData) if locData ~= nil and locData.icons ~= nil then for icon in string.gmatch(locData.icons, "%a+") do if iconCardList[icon] == nil then - iconCardList[icon] = { } + iconCardList[icon] = {} end table.insert(iconCardList[icon], cardId) end @@ -400,19 +519,19 @@ end ---@param locData Table A table containing the metadata for the card (for the correct side) function buildConnection(cardId, iconCardList, locData) if locData ~= nil and locData.connections ~= nil then - locationConnections[cardId] = { } + locationConnections[cardId] = {} for icon in string.gmatch(locData.connections, "%a+") do if iconCardList[icon] ~= nil then for _, connectedGuid in ipairs(iconCardList[icon]) do -- If the reciprocal exists, convert it to BiDi, otherwise add as a one-way if locationConnections[connectedGuid] ~= nil and (locationConnections[connectedGuid][cardId] == ONE_WAY - or locationConnections[connectedGuid][cardId] == BIDIRECTIONAL) then + or locationConnections[connectedGuid][cardId] == BIDIRECTIONAL) then locationConnections[connectedGuid][cardId] = BIDIRECTIONAL locationConnections[cardId][connectedGuid] = nil else if locationConnections[connectedGuid] == nil then - locationConnections[connectedGuid] = { } + locationConnections[connectedGuid] = {} end locationConnections[cardId][connectedGuid] = ONE_WAY locationConnections[connectedGuid][cardId] = INCOMING_ONE_WAY @@ -427,10 +546,10 @@ end -- Constructed vectors will be set to the playmat function drawBaseConnections() if not showLocationLinks() then - locationConnections = { } + locationConnections = {} return end - local cardConnectionLines = { } + local cardConnectionLines = {} for originGuid, targetGuids in pairs(locationConnections) do -- Objects should reliably exist at this point, but since this can be called during onUpdate the @@ -459,8 +578,8 @@ function drawDraggingConnections() if not showLocationLinks() then return end - local cardConnectionLines = { } - local ownedVectors = { } + local cardConnectionLines = {} + local ownedVectors = {} for originGuid, _ in pairs(draggingGuids) do targetGuids = locationConnections[originGuid] @@ -468,7 +587,7 @@ function drawDraggingConnections() -- object checks are conservative just to make sure. local origin = getObjectFromGUID(originGuid) if draggingGuids[originGuid] and origin ~= nil and targetGuids ~= nil then - ownedVectors[originGuid] = { } + ownedVectors[originGuid] = {} for targetGuid, direction in pairs(targetGuids) do local target = getObjectFromGUID(targetGuid) if target != nil then @@ -506,9 +625,9 @@ function addBidirectionalVector(card1, card2, vectorOwner, lines) local pos2 = vectorOwner.positionToLocal(cardPos2) table.insert(lines, { - points = { pos1, pos2 }, - color = vectorOwner == self and CONNECTION_COLOR or DRAGGING_CONNECTION_COLOR, - thickness = vectorOwner == self and CONNECTION_THICKNESS or DRAGGING_CONNECTION_THICKNESS, + points = { pos1, pos2 }, + color = vectorOwner == self and CONNECTION_COLOR or DRAGGING_CONNECTION_COLOR, + thickness = vectorOwner == self and CONNECTION_THICKNESS or DRAGGING_CONNECTION_THICKNESS, }) end @@ -530,11 +649,13 @@ function addOneWayVector(origin, target, vectorOwner, lines) -- Calculate card distance to be closer for horizontal positions than vertical, since cards are -- taller than they are wide local heading = Vector(originPos):sub(targetPos):heading("y") - local distanceFromCard = DIRECTIONAL_ARROW_DISTANCE * 0.7 + DIRECTIONAL_ARROW_DISTANCE * 0.3 * math.abs(math.sin(math.rad(heading))) + local distanceFromCard = DIRECTIONAL_ARROW_DISTANCE * 0.7 + + DIRECTIONAL_ARROW_DISTANCE * 0.3 * math.abs(math.sin(math.rad(heading))) -- Calculate the three possible arrow positions. These are offset by half the arrow length to -- make them visually balanced by keeping the arrows centered, not tracking the point - local midpoint = Vector(originPos):add(targetPos):scale(Vector(0.5, 0.5, 0.5)):moveTowards(targetPos, ARROW_ARM_LENGTH / 2) + local midpoint = Vector(originPos):add(targetPos):scale(Vector(0.5, 0.5, 0.5)):moveTowards(targetPos, + ARROW_ARM_LENGTH / 2) local closeToOrigin = Vector(originPos):moveTowards(targetPos, distanceFromCard + ARROW_ARM_LENGTH / 2) local closeToTarget = Vector(targetPos):moveTowards(originPos, distanceFromCard - ARROW_ARM_LENGTH / 2) @@ -553,14 +674,16 @@ end --- positioning and scaling, as well as highlighting connections during a drag operation ---@param lines Table List of vector line elements. Mutable, will be updated to add this arrow function addArrowLines(arrowheadPos, originPos, vectorOwner, lines) - local arrowArm1 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", -1 * ARROW_ANGLE):add(arrowheadPos) - local arrowArm2 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", ARROW_ANGLE):add(arrowheadPos) + local arrowArm1 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", + -1 * ARROW_ANGLE):add(arrowheadPos) + local arrowArm2 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", + ARROW_ANGLE):add(arrowheadPos) local head = vectorOwner.positionToLocal(arrowheadPos) local arm1 = vectorOwner.positionToLocal(arrowArm1) local arm2 = vectorOwner.positionToLocal(arrowArm2) table.insert(lines, { - points = { arm1, head, arm2}, + points = { arm1, head, arm2 }, color = vectorOwner == self and CONNECTION_COLOR or DRAGGING_CONNECTION_COLOR, thickness = vectorOwner == self and CONNECTION_THICKNESS or DRAGGING_CONNECTION_THICKNESS, }) @@ -587,7 +710,7 @@ function shiftContentsRight(playerColor) end function shiftContents(playerColor, direction) - local zone = getObjectFromGUID(PLAY_AREA_ZONE_GUID) + local zone = guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayAreaZone") if not zone then broadcastToColor("Scripting zone couldn't be found.", playerColor, "Red") return @@ -609,8 +732,8 @@ function isInPlayArea(object) local bounds = self.getBounds() local position = object.getPosition() -- Corners are arbitrary since it's all global - c1 goes down both axes, c2 goes up - local c1 = { x = bounds.center.x - bounds.size.x / 2, z = bounds.center.z - bounds.size.z / 2} - local c2 = { x = bounds.center.x + bounds.size.x / 2, z = bounds.center.z + bounds.size.z / 2} + local c1 = { x = bounds.center.x - bounds.size.x / 2, z = bounds.center.z - bounds.size.z / 2 } + local c2 = { x = bounds.center.x + bounds.size.x / 2, z = bounds.center.z + bounds.size.z / 2 } return position.x > c1.x and position.x < c2.x and position.z > c1.z and position.z < c2.z end @@ -652,17 +775,23 @@ function setLimitSnapsByType(matchTypes) end -- count victory points on locations in play area +---@param highlightOff Boolean True if highlighting should be enabled ---@return. Returns the total amount of VP found in the play area -function countVP() +function countVP(highlightOff) local totalVP = 0 for cardId, metadata in pairs(locations) do - if metadata ~= nil then + local card = getObjectFromGUID(cardId) + if metadata ~= nil and card ~= nil then + if highlightOff == true then + card.highlightOff("Green") + end + local cardVP = tonumber(metadata.victory) or 0 - if cardVP ~= 0 and not cardHasClues(cardId) then + if cardVP ~= 0 and not cardHasClues(card) then totalVP = totalVP + cardVP - if cardVP >0 then - table.insert(countedVP, getObjectFromGUID(cardId)) + if highlightOff == false then + card.highlightOn("Green") end end end @@ -672,9 +801,8 @@ function countVP() end -- checks if a card has clues on it, returns true if clues are on it ----@param cardId String GUID of the card to check for clues -function cardHasClues(cardId) - local card = getObjectFromGUID(cardId) +---@param card TTSObject Card to check for clues +function cardHasClues(card) for _, v in ipairs(searchOnObj(card)) do local obj = v.hit_object if obj.memo == "clueDoom" and obj.is_face_down == false then @@ -712,26 +840,10 @@ function highlightMissingData(state) end end --- highlights all locations in the play area with VP ----@param state Boolean True if highlighting should be enabled -function highlightCountedVP(state) - for i, obj in pairs(countedVP) do - if obj ~= nil then - if state then - obj.highlightOff("Green") - else - obj.highlightOn("Green") - end - else - countedVP[i] = nil - end - end -end - -- rebuilds local snap points (could be useful in the future again) function buildSnaps() - local upperleft = { x = 1.53, z = -1.09} - local lowerright = {x = -1.53, z = 1.55} + local upperleft = { x = 1.53, z = -1.09 } + local lowerright = { x = -1.53, z = 1.55 } local snaps = {} -- creates 81 snap points, for uneven rows + columns it makes a rotation snap point @@ -745,7 +857,7 @@ function buildSnaps() -- enable rotation snaps for uneven rows / columns if (i % 2 ~= 0) and (j % 2 ~= 0) then - snap.rotation = {0, 0, 0} + snap.rotation = { 0, 0, 0 } snap.rotation_snap = true end @@ -757,12 +869,43 @@ end -- utility function function round(num, numDecimalPlaces) - local mult = 10^(numDecimalPlaces or 0) + local mult = 10 ^ (numDecimalPlaces or 0) return math.floor(num * mult + 0.5) / mult 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) __bundle_register("core/token/TokenManager", function(require, _LOADED, __bundle_register, __bundle_modules) do + local guidReferenceApi = require("core/GUIDReferenceApi") local optionPanelApi = require("core/OptionPanelApi") local playAreaApi = require("core/PlayAreaApi") local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") @@ -883,15 +1026,10 @@ do ["supply"] = 7 } - -- Source for tokens - local TOKEN_SOURCE_GUID = "124381" - -- Table of data extracted from the token source bag, keyed by the Memo on each token which -- should match the token type keys ("resource", "clue", etc) local tokenTemplates - local DATA_HELPER_GUID = "708279" - local playerCardData local locationData @@ -989,9 +1127,11 @@ do -- Copy the offsets to make sure we don't change the static values local baseOffsets = offsets offsets = { } + + -- get a vector for the shifting (downwards local to the card) + local shiftDownVector = Vector(0, 0, shiftDown):rotateOver("y", card.getRotation().y) for i, baseOffset in ipairs(baseOffsets) do - offsets[i] = baseOffset - offsets[i][3] = offsets[i][3] + shiftDown + offsets[i] = baseOffset + shiftDownVector end end @@ -1104,8 +1244,8 @@ do if tokenTemplates ~= nil then return end - tokenTemplates = { } - local tokenSource = getObjectFromGUID(TOKEN_SOURCE_GUID) + tokenTemplates = {} + local tokenSource = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TokenSource") for _, tokenTemplate in ipairs(tokenSource.getData().ContainedObjects) do local tokenName = tokenTemplate.Memo tokenTemplates[tokenName] = tokenTemplate @@ -1117,7 +1257,7 @@ do if playerCardData ~= nil then return end - local dataHelper = getObjectFromGUID(DATA_HELPER_GUID) + local dataHelper = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") playerCardData = dataHelper.getTable('PLAYER_CARD_DATA') locationData = dataHelper.getTable('LOCATIONS_DATA') end @@ -1132,18 +1272,16 @@ do if uses == nil then return end -- go through tokens to spawn - local type, token, tokenCount + local tokenCount for i, useInfo in ipairs(uses) do - type = useInfo.type - token = useInfo.token - tokenCount = (useInfo.count or 0) - + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() - if extraUses ~= nil and extraUses[type] ~= nil then - tokenCount = tokenCount + extraUses[type] + tokenCount = (useInfo.count or 0) + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount() + if extraUses ~= nil and extraUses[useInfo.type] ~= nil then + tokenCount = tokenCount + extraUses[useInfo.type] end -- Shift each spawned group after the first down so they don't pile on each other - TokenManager.spawnTokenGroup(card, token, tokenCount, (i - 1) * 0.8, type) + TokenManager.spawnTokenGroup(card, useInfo.token, tokenCount, (i - 1) * 0.8, useInfo.type) end + tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -1167,9 +1305,8 @@ do ---@param playerData Table Player card data structure retrieved from the DataHelper. Should be -- the right data for this card. internal.spawnPlayerCardTokensFromDataHelper = function(card, playerData) - token = playerData.tokenType - tokenCount = playerData.tokenCount - --log("Spawning data helper tokens for "..card.getName()..'['..card.getDescription()..']: '..tokenCount.."x "..token) + local token = playerData.tokenType + local tokenCount = playerData.tokenCount TokenManager.spawnTokenGroup(card, token, tokenCount) tokenSpawnTrackerApi.markTokensSpawned(card.getGUID()) end @@ -1202,7 +1339,6 @@ do return 0 end - --log(card.getName() .. ' : ' .. locationData.type .. ' : ' .. locationData.value .. ' : ' .. locationData.clueSide) if ((card.is_face_down and locationData.clueSide == 'back') or (not card.is_face_down and locationData.clueSide == 'front')) then if locationData.type == 'fixed' then @@ -1330,112 +1466,4 @@ do return OptionPanelApi end end) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" - - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") - end - - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) - end - - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) - end - - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) - end - - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) - end - - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) - end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") - end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi -end -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Playarea 721ba2.yaml b/unpacked/Custom_Token Play Area 721ba2.yaml similarity index 98% rename from unpacked/Custom_Token Playarea 721ba2.yaml rename to unpacked/Custom_Token Play Area 721ba2.yaml index 58fc95f87..4f59dfabf 100644 --- a/unpacked/Custom_Token Playarea 721ba2.yaml +++ b/unpacked/Custom_Token Play Area 721ba2.yaml @@ -615,11 +615,11 @@ HideWhenFaceDown: false IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: true -LuaScript: !include 'Custom_Token Playarea 721ba2.ttslua' +LuaScript: !include 'Custom_Token Play Area 721ba2.ttslua' LuaScriptState: '{"trackedLocations":[]}' MeasureMovement: false Name: Custom_Token -Nickname: Playarea +Nickname: Play Area Snap: true Sticky: true Tags: diff --git a/unpacked/Custom_Token Playmat Image Swapper b7b45b.ttslua b/unpacked/Custom_Token Playmat Image Swapper b7b45b.ttslua index 8d432a42e..2697e32e8 100644 --- a/unpacked/Custom_Token Playmat Image Swapper b7b45b.ttslua +++ b/unpacked/Custom_Token Playmat Image Swapper b7b45b.ttslua @@ -41,197 +41,1291 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/PlayAreaSelector") -end) __bundle_register("core/PlayAreaSelector", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/PlayAreaImageData") -- this fills the variable "PLAYAREA_IMAGE_DATA" local playAreaApi = require("core/PlayAreaApi") +local typeIndex, selectionIndex -local controlActive = false +function onSave() return JSON.encode({typeIndex = typeIndex, selectionIndex = selectionIndex}) end --- parameters for open/close button for reusing -local buttonParameters = {} -buttonParameters.function_owner = self -buttonParameters.click_function = "click_toggleControl" -buttonParameters.height = 1500 -buttonParameters.width = 1500 -buttonParameters.color = { 1, 1, 1, 0 } +function onLoad(savedData) + self.createButton({ + function_owner = self, + click_function = "onClick_toggleGallery", + tooltip = "Show Image Gallery", + height = 1500, + width = 1500, + color = { 1, 1, 1, 0 } + }) -function onLoad() - createOpenCloseButton() + local loadedData = JSON.decode(savedData) or {} + typeIndex = loadedData.typeIndex or 1 + selectionIndex = loadedData.selectionIndex or 1 + Wait.time(updatePlayareaGallery, 0.5) end -- click function for main button -function click_toggleControl() - self.clearButtons() - self.clearInputs() - - controlActive = not controlActive - createOpenCloseButton() - - if not controlActive then return end - - -- creates the label, input box and apply button - self.createButton({ - function_owner = self, - label = "Playmat Image Swapper", - tooltip = "", - click_function = "none", - position = { 0, 0.15, 2.2 }, - height = 0, - width = 0, - font_size = 300, - font_color = { 1, 1, 1 } - }) - - self.createInput({ - function_owner = self, - label = "URL", - tooltip = "Enter URL for playmat image", - input_function = "none", - alignment = 3, - position = { 0, 0.15, 3 }, - height = 323, - width = 4000, - font_size = 300 - }) - - self.createButton({ - function_owner = self, - label = "Apply Image\nTo Playmat", - tooltip = "Left-Click: Apply URL\nRight-Click: Reset to default image", - click_function = "click_applySurface", - position = { 0, 0.15, 4.1 }, - height = 460, - width = 1400, - font_size = 200 - }) +function onClick_toggleGallery() + Global.call("togglePlayareaGallery") end --- click function for apply button -function click_applySurface(_, _, isRightClick) - playAreaApi.updateSurface(isRightClick and "" or self.getInputs()[1].value) +function onClick_defaultImage() + playAreaApi.updateSurface() + Global.call("togglePlayareaGallery") end -function updateSurface(newURL) - playAreaApi.updateSurface(newURL) +function getDataSubTableByIndex(dataTable, index) + local loopId = 1 + for i, v in pairs(dataTable) do + if index == loopId then return v end + loopId = loopId + 1 + end + return {} end --- input function for the input box -function none() end +function updatePlayareaGallery() + -- get subtables + local dataForType = getDataSubTableByIndex(PLAYAREA_IMAGE_DATA, typeIndex) + local dataForSelection = getDataSubTableByIndex(dataForType, selectionIndex) --- creates the main button -function createOpenCloseButton() - buttonParameters.tooltip = (controlActive and "Close" or "Open") .. " Playmat Panel" - self.createButton(buttonParameters) + -- get global xml to insert elements + local globalXml = UI.getXmlTable() + + -- selectable items + local itemSelection = getXmlTableElementById(globalXml, 'itemSelection') + itemSelection.children = {} + + local i = 0 + for itemName, _ in pairs(dataForType) do + i = i + 1 + table.insert(itemSelection.children, + { + tag = "Panel", + attributes = { class = "itemPanel", id = "typePanel" .. i }, + children = { + tag = "Text", + value = itemName, + attributes = { class = "itemText", id = "typeListText" .. i } + } + }) + end + + -- selectable images for that item + local playareaList = getXmlTableElementById(globalXml, 'playareaList') + playareaList.children = {} + + for i, v in ipairs(dataForSelection) do + table.insert(playareaList.children, + { + tag = "VerticalLayout", + attributes = { class = "imageBox", id = "image" .. i }, + children = { + { + tag = 'Image', + attributes = { class = "playareaImage", image = v.URL } + }, + { + tag = 'Text', + value = v.Name, + attributes = { class = "imageName" } + } + } + }) + end + + playareaList.attributes.height = round(#playareaList.children / 2, 0) * 380 + UI.setXmlTable(globalXml) + Wait.time(highlightTabAndItem, 0.1) +end + +function onClick_imageTab(_, _, tabId) + typeIndex = tonumber(tabId:sub(9)) + selectionIndex = 1 + updatePlayareaGallery() +end + +function onClick_listItem(_, _, listId) + selectionIndex = tonumber(listId:sub(10)) + updatePlayareaGallery() +end + +function onClick_image(_, _, id) + local imageIndex = tonumber(id:sub(6)) + local dataForType = getDataSubTableByIndex(PLAYAREA_IMAGE_DATA, typeIndex) + local dataForSelection = getDataSubTableByIndex(dataForType, selectionIndex) + local newURL = dataForSelection[imageIndex].URL + playAreaApi.updateSurface(newURL) + Global.call("togglePlayareaGallery") +end + +function highlightTabAndItem() + -- highlight active tab + for i = 1, 5 do + local color = "#888888" + if i == typeIndex then color = "#ffffff" end + UI.setAttribute("imageTab" .. i, "color", color) + end + + -- highlight item + UI.setAttribute("typePanel" .. selectionIndex, "color", "grey") + UI.setAttribute("typeListText" .. selectionIndex, "color", "black") +end + +-- loops through an XML table and returns the specified object +---@param ui Table XmlTable (get this via getXmlTable) +---@param id String Id of the object to return +function getXmlTableElementById(ui, id) + for _, obj in ipairs(ui) do + if obj.attributes and obj.attributes.id and obj.attributes.id == id then return obj end + if obj.children then + local result = getXmlTableElementById(obj.children, id) + if result then return result end + end + end + return nil +end + +-- utility function +function round(num, numDecimalPlaces) + local mult = 10 ^ (numDecimalPlaces or 0) + return math.floor(num * mult + 0.5) / mult end end) __bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end -- Returns the current value of the investigator counter from the playmat ---@return Integer. Number of investigators currently set on the counter PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") + return getInvestigatorCounter().getVar("val") end -- Updates the current value of the investigator counter from the playmat ---@param count Number of investigators to set on the counter PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) + getInvestigatorCounter().call("updateVal", count) end -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) end PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) end PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) end PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) end -- Reset the play area's tracking of which cards have had tokens spawned. PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") + return getPlayArea().call("resetSpawnedCards") end -- Event to be called when the current scenario has changed. ---@param scenarioName Name of the new scenario PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) end -- Sets this playmat's snap points to limit snapping to locations or not. -- If matchTypes is false, snap points will be reset to snap all cards. ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) end -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged -- cards before they're destroyed by entering the container PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) end -- counts the VP on locations in the play area PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") + return getPlayArea().call("countVP") end -- highlights all locations in the play area without metadata ---@param state Boolean True if highlighting should be enabled PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) + return getPlayArea().call("highlightMissingData", state) end -- highlights all locations in the play area with VP ---@param state Boolean True if highlighting should be enabled PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) + return getPlayArea().call("countVP", state) end -- Checks if an object is in the play area (returns true or false) PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) + return getPlayArea().call("isInPlayArea", object) end PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image + return getPlayArea().getCustomObject().image end PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) + return getPlayArea().call("updateSurface", url) end -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the -- data to the local token manager instance. ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) + getPlayArea().call("updateLocations", args) end PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") + return getPlayArea().getVar("customDataHelper") end return PlayAreaApi end end) +__bundle_register("core/PlayAreaImageData", function(require, _LOADED, __bundle_register, __bundle_modules) +PLAYAREA_IMAGE_DATA = { + ["Official Campaigns"] = { + ["Night of the Zealot"] = { + { + Name = "I - The Gathering 1", + URL = "https://i.ibb.co/6NWqg1K/Zealot-Gathering.jpg" + }, + { + Name = "III - Devourer Below 1", + URL = "https://i.ibb.co/x5QFzrx/Zealot-3-Devourer-Below-Helen-Castelow.png" + }, + { + Name = "III - Devourer Below 2", + URL = "https://i.ibb.co/6r6LFGz/Zealot-3-Devourer-Below-Sarah-Miller.png" + } + }, + ["The Dunwich Legacy"] = { + { + Name = "I-A - Extracurricular Activity 1", + URL = "https://i.ibb.co/tDxX8KS/Dunwich-1-Extracurricular-Activity-Igor-Kirdeika.jpg" + }, + { + Name = "I-A - Extracurricular Activity 2", + URL = "https://i.ibb.co/RQ6z0pj/Dunwich-1-Extracurricular-Activity-Joseph-Diaz.jpg" + }, + { + Name = "I-A - Extracurricular Activity 3", + URL = "https://i.ibb.co/nnJdwL2/Dunwich-1-Extracurricular-Activity-Tomasz-Jedruszek.jpg" + }, + { + Name = "I-B - House Always Wins 1", + URL = "https://i.ibb.co/8XPLdr9/Dunwich-2-House-Always-Wins-Jonny-Klein.jpg" + }, + { + Name = "I-B - House Always Wins 2", + URL = "https://i.ibb.co/HtX95GK/Dunwich-2-House-Always-Wins-Robert-Laskey.jpg" + }, + { + Name = "I-B - House Always Wins 3", + URL = "https://i.ibb.co/MCLP3Sz/Dunwich-2-House-Always-Wins-XX-l.jpg" + }, + { + Name = "I-B - House Always Wins 4", + URL = "https://i.ibb.co/w7Pf5sd/Dunwich-2-House-Always-Wins-XX-l-2.jpg" + }, + { + Name = "II - Miskatonic Museum 1", + URL = "https://i.ibb.co/x1Kf7qG/Dunwich-3-Miskatonic-Museum-Emre-Aktuna.jpg" + }, + { + Name = "II - Miskatonic Museum 2", + URL = "https://i.ibb.co/yWXVPcN/Dunwich-3-Miskatonic-Museum-Richard-Wright.jpg" + }, + { + Name = "III - Essex County Express", + URL = "https://i.ibb.co/602CMZb/Dunwich-4-Essex-County-Express-David-Alvarez.jpg" + }, + { + Name = "IV - Blood on the Altar 1", + URL = "https://i.ibb.co/3CYHDhf/Dunwich-5-Blood-on-the-Altar.jpg" + }, + { + Name = "IV - Blood on the Altar 2", + URL = "https://i.ibb.co/FbxcCY2/Dunwich-5-Blood-on-the-Altar-Chris-Ostrowski.jpg" + }, + { + Name = "IV - Blood on the Altar 3", + URL = "https://i.ibb.co/sJf6YsZ/Dunwich-5-Blood-on-the-Altar-Lucas-Staniec.jpg" + }, + { + Name = "IV - Blood on the Altar 4", + URL = "https://i.ibb.co/kBPNGBd/Dunwich-5-Blood-on-the-Altar-Mark-Molnar.jpg" + }, + { + Name = "V - Undimensioned and Unseen 1", + URL = "https://i.ibb.co/QvfhjDv/Dunwich-6-Undimensioned-and-Unseen-Frej-Agelii.jpg" + }, + { + Name = "V - Undimensioned and Unseen 2", + URL = "https://i.ibb.co/4VL9gSK/Dunwich-6-Undimensioned-and-Unseen-Lucas-Staniec.jpg" + }, + { + Name = "V - Undimensioned and Unseen 3", + URL = "https://i.ibb.co/wBFsS8P/Dunwich-6-Undimensioned-and-Unseen-Michal-Teliga-jpg.jpg" + }, + { + Name = "V - Undimensioned and Unseen 4", + URL = "https://i.ibb.co/wwGDcq6/Dunwich-6-Undimensioned-and-Unseen-Tomasz-Jedruszek.jpg" + }, + { + Name = "VI - Where Doom Awaits 1", + URL = "https://i.ibb.co/TvMwqj4/Dunwich-7-Where-Doom-Awaits.jpg" + }, + { + Name = "VI - Where Doom Awaits 2", + URL = "https://i.ibb.co/S6cSLH9/Dunwich-7-Where-Doom-Awaits-3.jpg" + }, + { + Name = "VI - Where Doom Awaits 3", + URL = "https://i.ibb.co/khBX32g/Dunwich-7-Where-Doom-Awaits-4.jpg" + }, + { + Name = "VI - Where Doom Awaits 4", + URL = "https://i.ibb.co/S0hcwN8/Dunwich-7-Where-Doom-Awaits-5.jpg" + }, + { + Name = "VI - Where Doom Awaits 5", + URL = "https://i.ibb.co/Lxv1Bjp/Dunwich-7-Where-Doom-Awaits-Luca-Trentin.jpg" + }, + { + Name = "VII - Lost in Time and Space 1", + URL = "https://i.ibb.co/rtTpbDx/Dunwich-8-Lost-in-Time-amp-Space.jpg" + }, + { + Name = "VII - Lost in Time and Space 2", + URL = "https://i.ibb.co/dBXP0GL/Dunwich-8-Lost-in-Time-amp-Space-Chris-Ostrowski.jpg" + }, + { + Name = "VII - Lost in Time and Space 3", + URL = "https://i.ibb.co/0XcnxFD/Dunwich-8-Lost-in-Time-amp-Space-Lino-Drieghe.jpg" + } + }, + ["The Path to Carcosa"] = { + { + Name = "I - Curtain Call", + URL = "https://i.ibb.co/TcnKXJD/Carcosa-1-Curtain-Call-Mark-Molnar.jpg" + }, + { + Name = "II - Last King 1", + URL = "https://i.ibb.co/JRQJKR8/Carcosa-2-Last-King-Cristi-Balanescu.jpg" + }, + { + Name = "II - Last King 2", + URL = "https://i.ibb.co/NZzBwgv/Carcosa-2-Last-King-Cristi-Balanescu-2.jpg" + }, + { + Name = "II - Last King 3", + URL = "https://i.ibb.co/x56ZHt7/Carcosa-2-Last-King-Wu-Mengjia.jpg" + }, + { + Name = "III - Echoes of the Past", + URL = "https://i.ibb.co/R6gSm0D/Carcosa-3-Echoes-of-the-Past-Heather-Savage.jpg" + }, + { + Name = "IV - Unspeakable Oath 1", + URL = "https://i.ibb.co/DzzDQQQ/Carcosa-4-Unspeakable-Oath.jpg" + }, + { + Name = "IV - Unspeakable Oath 2", + URL = "https://i.ibb.co/9gqBzXr/Carcosa-4-Unspeakable-Oath-2-Mark-Molnar.jpg" + }, + { + Name = "IV - Unspeakable Oath 3", + URL = "https://i.ibb.co/wWL73c9/Carcosa-4-Unspeakable-Oath-Paul-Fairbairn.jpg" + }, + { + Name = "V - Phantom of Truth 1", + URL = "https://i.ibb.co/mzpz1Dd/Carcosa-5-Phantom-of-Truth-Lucas-Staniec.jpg" + }, + { + Name = "V - Phantom of Truth 2", + URL = "https://i.ibb.co/Vp1wNbT/Carcosa-5-Phantom-of-Truth-Tomasz-Jedruszek.jpg" + }, + { + Name = "VI - Pallid Mask 1", + URL = "https://i.ibb.co/Bf5LByY/Carcosa-6-Pallid-Mask-Greg-Bobrowski.jpg" + }, + { + Name = "VI - Pallid Mask 2", + URL = "https://i.ibb.co/1v1J9Xx/Carcosa-6-Pallid-Mask-Rafal-Pyra.jpg" + }, + { + Name = "VII - Black Star Rises 1", + URL = "https://i.ibb.co/TB451t7/Carcosa-7-Black-Star-Rises-Audric-Gatoux.jpg" + }, + { + Name = "VII - Black Star Rises 2", + URL = "https://i.ibb.co/nC8Ncxx/Carcosa-7-Black-Star-Rises-Chris-Kintner.jpg" + }, + { + Name = "VIII - Dim Carcosa 1", + URL = "https://i.ibb.co/QvS4y3D/Carcosa-8-Dim-Carcosa-Alexandr-Elichev.jpg" + }, + { + Name = "VIII - Dim Carcosa 2", + URL = "https://i.ibb.co/hR95x7k/Carcosa-8-Dim-Carcosa-Yuri-Shepherd.jpg" + } + }, + ["The Forgotten Age"] = { + { + Name = "I - Untamed Wilds 1", + URL = "https://i.ibb.co/BLhwCG1/Forgotten-Age-1-Untamed-Wilds-David-Frasheski.jpg" + }, + { + Name = "I - Untamed Wilds 2", + URL = "https://i.ibb.co/SnJfsNy/Forgotten-Age-1-Untamed-Wilds-David-Frasheski-2.jpg" + }, + { + Name = "I - Untamed Wilds 3", + URL = "https://i.ibb.co/kcx1tvp/Forgotten-Age-1-Untamed-Wilds-Ethan-Patrick-Harris.jpg" + }, + { + Name = "I - Untamed Wilds 4", + URL = "https://i.ibb.co/HPbJwXk/Forgotten-Age-1-Untamed-Wilds-Lucas-Staniec.jpg" + }, + { + Name = "I - Untamed Wilds 5", + URL = "https://i.ibb.co/bbq1ZrK/Forgotten-Age-1-Untamed-Wilds-Nele-Diel.jpg" + }, + { + Name = "II - Doom of Etzli 1", + URL = "https://i.ibb.co/Pw4by4q/Forgotten-Age-2-Doom-of-Eztli-Cristi-Balanescu.jpg" + }, + { + Name = "II - Doom of Etzli 2", + URL = "https://i.ibb.co/xqW6cXR/Forgotten-Age-2-Doom-of-Eztli-Greg-Bobrowski.jpg" + }, + { + Name = "II - Doom of Etzli 3", + URL = "https://i.ibb.co/kgsC3pb/Forgotten-Age-2-Doom-of-Eztli-Nele-Diel.jpg" + }, + { + Name = "III - Threads of Fate", + URL = "https://i.ibb.co/Bn0Pjng/Forgotten-Age-3-Threads-of-Fate-Jokubas-Uogintas.jpg" + }, + { + Name = "IV - Boundary Beyond 1", + URL = "https://i.ibb.co/yPZ9v2X/Forgotten-Age-4-Boundary-Beyond-Greg-Bobrowski-2-jpg.jpg" + }, + { + Name = "IV - Boundary Beyond 2", + URL = "https://i.ibb.co/vm0JgFs/Forgotten-Age-4-Boundary-Beyond-Greg-Bobrowski-jpg.jpg" + }, + { + Name = "IV - Boundary Beyond 3", + URL = "https://i.ibb.co/D1rh9Ry/Forgotten-Age-4-Boundary-Beyond-Nele-Diel.jpg" + }, + { + Name = "V - Heart of the Elders I-1", + URL = "https://i.ibb.co/jzKvv6P/Forgotten-Age-5-Heart-of-the-Elders-I-Lucas-Staniec.jpg" + }, + { + Name = "V - Heart of the Elders I-2", + URL = "https://i.ibb.co/mR79MX4/Forgotten-Age-5-Heart-of-the-Elders-I-Lucas-Staniec-2.jpg" + }, + { + Name = "V - Heart of the Elders II", + URL = "https://i.ibb.co/pQSbL0t/Forgotten-Age-5-Heart-of-the-Elders-II-Nele-Diel.jpg" + }, + { + Name = "VI - City of Archives 1", + URL = "https://i.ibb.co/f04DSPb/Forgotten-Age-6-City-of-Archives.jpg" + }, + { + Name = "VI - City of Archives 2", + URL = "https://i.ibb.co/WsSBrYj/Forgotten-Age-6-City-of-Archives-2.jpg" + }, + { + Name = "VI - City of Archives 3", + URL = "https://i.ibb.co/qdPbSZ8/Forgotten-Age-6-City-of-Archives-Chris-Ostrowski.jpg" + }, + { + Name = "VII - Depths of Yoth 1", + URL = "https://i.ibb.co/dbLKgGv/Forgotten-Age-7-Depths-of-Yoth-Diego-Arbetta.jpg" + }, + { + Name = "VII - Depths of Yoth 2", + URL = "https://i.ibb.co/NW7Wp98/Forgotten-Age-7-Depths-of-Yoth-Greg-Bobrowski.jpg" + }, + { + Name = "VII - Depths of Yoth 3", + URL = "https://i.ibb.co/257zr7c/Forgotten-Age-7-Depths-of-Yoth-Greg-Bobrowski-2-jpg.jpg" + }, + { + Name = "VIII - Shattered Aeons 1", + URL = "https://i.ibb.co/KwnWTGR/Forgotten-Age-8-Shattered-Aeons.jpg" + }, + { + Name = "VIII - Shattered Aeons 2", + URL = "https://i.ibb.co/b7kVd4F/Forgotten-Age-8-Shattered-Aeons-Alexandr-Elichev.jpg" + } + }, + ["The Circle Undone"] = { + { + Name = "0 - Prologue", + URL = "https://i.ibb.co/gm4C6yy/Circle-Undone-0-Prologue-Ted-Galaday.jpg" + }, + { + Name = "I - Witching Hour", + URL = "https://i.ibb.co/kgJ34WS/Circle-Undone-1-Witching-Hour-Nele-Diel.jpg" + }, + { + Name = "II - At Death's Doorstep 1", + URL = "https://i.ibb.co/qNWzH0Y/Circle-Undone-2-At-Death-039-s-Doorstep-Emilio-Rodriguez.jpg" + }, + { + Name = "II - At Death's Doorstep 2", + URL = "https://i.ibb.co/T1zp1QN/Circle-Undone-2-At-Death-039-s-Doorstep-Emilio-Rodriguez-2.jpg" + }, + { + Name = "II - At Death's Doorstep 3", + URL = "https://i.ibb.co/ZJfYZ1w/Circle-Undone-2-At-Death-039-s-Doorstep-Majid-Azim.jpg" + }, + { + Name = "III - The Secret Name 1", + URL = "https://i.ibb.co/hsBw4JQ/Circle-Undone-3-Secret-Name-Jeff-Jumper.jpg" + }, + { + Name = "III - The Secret Name 2", + URL = "https://i.ibb.co/MpcPXR5/Circle-Undone-3-Secret-Name-Pierre-Santamaria.jpg" + }, + { + Name = "III - The Secret Name 3", + URL = "https://i.ibb.co/LQ8rdKs/Circle-Undone-3-The-Secret-Name-Greg-Bobrowski.jpg" + }, + { + Name = "III - The Secret Name 4", + URL = "https://i.ibb.co/0D7LzxV/Circle-Undone-3-The-Secret-Name-Robert-Laskey.jpg" + }, + { + Name = "IV - Wages of Sin 1", + URL = "https://i.ibb.co/fDMqH1C/Circle-Undone-4-Wages-of-Sin-Emilio-Rodriguez.jpg" + }, + { + Name = "IV - Wages of Sin 2", + URL = "https://i.ibb.co/HDrKkZF/Circle-Undone-4-Wages-of-Sin-Emilio-Rodriguez-2.jpg" + }, + { + Name = "IV - Wages of Sin 3", + URL = "https://i.ibb.co/vkpG8cM/Circle-Undone-4-Wages-of-Sin-Greg-Bobrowski.jpg" + }, + { + Name = "IV - Wages of Sin 4", + URL = "https://i.ibb.co/CMj007q/Circle-Undone-4-Wages-of-Sin-Mateusz-Michalski.jpg" + }, + { + Name = "IV - Wages of Sin 5", + URL = "https://i.ibb.co/sj1bS5x/Circle-Undone-4-Wages-of-Sin-Serge-Da-Silva-Dias.jpg" + }, + { + Name = "V - For the Greater Good 1", + URL = "https://i.ibb.co/LDyqjbj/Circle-Undone-5-For-the-Greater-Good.jpg" + }, + { + Name = "V - For the Greater Good 2", + URL = "https://i.ibb.co/pPzXNd1/Circle-Undone-5-For-the-Greater-Good-2.jpg" + }, + { + Name = "V - For the Greater Good 3", + URL = "https://i.ibb.co/8rMLvJH/Circle-Undone-5-For-the-Greater-Good-Greg-Bobrowski.jpg" + }, + { + Name = "V - For the Greater Good 4", + URL = "https://i.ibb.co/vj1q4Cm/Circle-Undone-5-For-the-Greater-Good-Robert-Laskey.jpg" + }, + { + Name = "VI - Union and Disillusioned", + URL = "https://i.ibb.co/n7SD1tB/Circle-Undone-6-Union-amp-Disillusioned-Andreas-Rocha.jpg" + }, + { + Name = "VII - In the Clutches of Chaos 1", + URL = "https://i.ibb.co/bFXBNh7/Circle-Undone-7-In-the-Clutches-of-Chaos.jpg" + }, + { + Name = "VII - In the Clutches of Chaos 2", + URL = "https://i.ibb.co/m6DshNg/Circle-Undone-7-In-the-Clutches-of-Chaos-Alexandr-Elichev.jpg" + }, + { + Name = "VII - In the Clutches of Chaos 3", + URL = "https://i.ibb.co/k2p4yfG/Circle-Undone-7-In-the-Clutches-of-Chaos-Jokubas-Uogintas.jpg" + }, + { + Name = "VIII - Before the Black Throne 1", + URL = "https://i.ibb.co/9TPwvP6/Circle-Undone-8-Before-the-Black-Throne-Aaron-Luke-Wilson.jpg" + }, + { + Name = "VIII - Before the Black Throne 2", + URL = "https://i.ibb.co/VNtgH4v/Circle-Undone-8-Before-the-Black-Throne-Greg-Bobrowski.jpg" + } + }, + ["The Dream-Eaters"] = { + { + Name = "I-A - Beyond the Gates of Sleep 1", + URL = "https://i.ibb.co/S6sCy7G/Dream-Eaters-1-A-Beyond-the-Gates-of-Sleep-Phoebe-Herring.jpg" + }, + { + Name = "I-A - Beyond the Gates of Sleep 2", + URL = "https://i.ibb.co/kBfW9SC/Dream-Eaters-1-A-Beyond-the-Gates-of-Sleep-Regina-Kurnya.jpg" + }, + { + Name = "I-A - Beyond the Gates of Sleep 3", + URL = "https://i.ibb.co/HGvnxdX/Dream-Eaters-1-A-Beyond-the-Gates-of-Sleep-Jason-Scheier.jpg" + }, + { + Name = "I-B - Waking Nightmare", + URL = "https://i.ibb.co/sWsZCv8/Dream-Eaters-1-B-Waking-Nightmare-Josh-Gould-jpg.jpg" + }, + { + Name = "II-A - Search for Kadath 1", + URL = "https://i.ibb.co/4SwzCD8/Dream-Eaters-2-A-Search-for-Kadath-Andrei-Khrutskii.jpg" + }, + { + Name = "II-A - Search for Kadath 2", + URL = "https://i.ibb.co/WpZ4fMc/Dream-Eaters-2-A-Search-for-Kadath-Dan-Iorgulescu.jpg" + }, + { + Name = "II-A - Search for Kadath 3", + URL = "https://i.ibb.co/jwsn0jf/Dream-Eaters-2-A-Search-for-Kadath-Diana-Tsareva.jpg" + }, + { + Name = "II-A - Search for Kadath 4", + URL = "https://i.ibb.co/pd9vxmL/Dream-Eaters-2-A-Search-for-Kadath-Helen-Ilnytska.jpg" + }, + { + Name = "II-A - Search for Kadath 5", + URL = "https://i.ibb.co/MZ7Qtcc/Dream-Eaters-2-A-Search-for-Kadath-Nele-Diel.jpg" + }, + { + Name = "II-B - Thousand Shapes of Horror 1", + URL = "https://i.ibb.co/9s7M0PP/Dream-Eaters-2-B-Thousand-Shapes-of-Horror-Nele-Diel-2.jpg" + }, + { + Name = "II-B - Thousand Shapes of Horror 2", + URL = "https://i.ibb.co/T4Pqx0H/Dream-Eaters-2-B-Thousand-Shapes-of-Horror-Nele-Diel.jpg" + }, + { + Name = "II-B - Thousand Shapes of Horror 3", + URL = "https://i.ibb.co/VJFQVYd/Dream-Eaters-2-B-Thousand-Shapes-of-Horror-Greg-Bobrowski.jpg" + }, + { + Name = "III-A - Dark Side of the Moon 1", + URL = "https://i.ibb.co/B2DfXLZ/Dream-Eaters-3-A-Dark-Side-of-the-Moon-Dabanli.jpg" + }, + { + Name = "III-A - Dark Side of the Moon 2", + URL = "https://i.ibb.co/c27JRvv/Dream-Eaters-3-A-Dark-Side-of-the-Moon-Frej-Agelii.jpg" + }, + { + Name = "III-B - Point of No Return 1", + URL = "https://i.ibb.co/dMGNB9Y/Dream-Eaters-3-B-Point-of-No-Return-Daria-Khlebnikova.jpg" + }, + { + Name = "III-B - Point of No Return 2", + URL = "https://i.ibb.co/dpXxPmz/Dream-Eaters-3-B-Point-of-No-Return-Karine-Villette.jpg" + }, + { + Name = "IV-A - Where the Gods Dwell", + URL = "https://i.ibb.co/v4nqw6G/Dream-Eaters-4-A-Where-the-Gods-Dwell-Samantha-Franco.jpg" + }, + { + Name = "IV-B - Weaver of the Cosmos 1", + URL = "https://i.ibb.co/7btNBS1/Dream-Eaters-4-B-Weaver-of-the-Cosmos-Diana-Franco.jpg" + }, + { + Name = "IV-B - Weaver of the Cosmos 2", + URL = "https://i.ibb.co/RY7y22b/Dream-Eaters-4-B-Weaver-of-the-Cosmos-Leanna-Crossan.jpg" + }, + { + Name = "IV-B - Weaver of the Cosmos 3", + URL = "https://i.ibb.co/f8LBbFW/Dream-Eaters-4-B-Weaver-of-the-Cosmos-Nele-Diel.jpg" + } + }, + ["The Innsmouth Conspiracy"] = { + { + Name = "I - Pit of Despair 1", + URL = "https://i.ibb.co/2sc0F61/Innsmouth-1-Pit-of-Despair-Amanda-Castrillo.jpg" + }, + { + Name = "I - Pit of Despair 2", + URL = "https://i.ibb.co/Nj9JLBQ/Innsmouth-1-Pit-of-Despair-J-Mill.jpg" + }, + { + Name = "II - Vanishing of Elina Harper 1", + URL = "https://i.ibb.co/2j74cVn/Innsmouth-2-Vanishing-of-Elina-Harper-Konstantin-Vohwinkel.jpg" + }, + { + Name = "II - Vanishing of Elina Harper 2", + URL = "https://i.ibb.co/r2VqHSn/Innsmouth-2-Vanishing-of-Elina-Harper-Mihail-Bila.jpg" + }, + { + Name = "II - Vanishing of Elina Harper 3", + URL = "https://i.ibb.co/hFQMm7N/Innsmouth-2-Vanishing-of-Elina-Harper-Richard-Wright.jpg" + }, + { + Name = "II - Vanishing of Elina Harper 4", + URL = "https://i.ibb.co/2nZKGN6/Innsmouth-2-Vanishing-of-Elina-Harper-Tomasz-Jedruszek-1.jpg" + }, + { + Name = "II - Vanishing of Elina Harper 5", + URL = "https://i.ibb.co/WxLpKrM/Innsmouth-2-Vanishing-of-Elina-Harper-Tomasz-Jedruszek-2.jpg" + }, + { + Name = "III - In Too Deep 1", + URL = "https://i.ibb.co/SsQ3my4/Innsmouth-3-In-Too-Deep-David-Frasheski.jpg" + }, + { + Name = "III - In Too Deep 2", + URL = "https://i.ibb.co/jgQ8zQN/Innsmouth-3-In-Too-Deep-Klaudia-Bezak.jpg" + }, + { + Name = "III - In Too Deep 3", + URL = "https://i.ibb.co/VVgtNM1/Innsmouth-3-In-Too-Deep-Patrik-Antonescu.jpg" + }, + { + Name = "IV - Devil Reef 1", + URL = "https://i.ibb.co/Jrf6CJ0/Innsmouth-4-Devil-Reef-Ludovic-Sanson.jpg" + }, + { + Name = "IV - Devil Reef 2", + URL = "https://i.ibb.co/4jfwDZR/Innsmouth-4-Devil-Reef-Marc-Stewart.jpg" + }, + { + Name = "V - Horror in High Gear 1", + URL = "https://i.ibb.co/vqYJjYJ/Innsmouth-5-Horror-in-High-Gear-Greg-Bobrowski.jpg" + }, + { + Name = "V - Horror in High Gear 2", + URL = "https://i.ibb.co/yYrzbYS/Innsmouth-5-Horror-in-High-Gear-Greg-Bobrowski-2.jpg" + }, + { + Name = "V - Horror in High Gear 3", + URL = "https://i.ibb.co/fpKWhGY/Innsmouth-5-Horror-in-High-Gear-Guillem-H-Pongiluppi.jpg" + }, + { + Name = "V - Horror in High Gear 4", + URL = "https://i.ibb.co/YkLFy7y/Innsmouth-5-Horror-in-High-Gear-Rostyslav-Zagornov.jpg" + }, + { + Name = "VI - Light in the Fog 1", + URL = "https://i.ibb.co/v1rhgqJ/Innsmouth-6-Light-in-the-Fog-Florian-Aupetit.jpg" + }, + { + Name = "VI - Light in the Fog 2", + URL = "https://i.ibb.co/Db2pRd6/Innsmouth-6-Light-in-the-Fog-JB-Caillet.jpg" + }, + { + Name = "VII - Lair of Dagon 1", + URL = "https://i.ibb.co/QPwzQL5/Innsmouth-7-Lair-of-Dagon-Daria-Khlebnikova.jpg" + }, + { + Name = "VII - Lair of Dagon 2", + URL = "https://i.ibb.co/MZBpCbs/Innsmouth-7-Lair-of-Dagon-Guillem-H-Pongiluppi.jpg" + }, + { + Name = "VIII - Into the Maelstrom 1", + URL = "https://i.ibb.co/fkSXDgs/Innsmouth-8-Into-the-Maelstrom-Dimitri-Bielak.jpg" + }, + { + Name = "VIII - Into the Maelstrom 2", + URL = "https://i.ibb.co/k56Dn9q/Innsmouth-8-Into-the-Maelstrom-Mateusz-Michalski.jpg" + } + }, + ["Edge of the Earth"] = { + { + Name = "I - Ice and Death 1", + URL = "https://i.ibb.co/FWZMWtW/Edge-1-Ice-and-Death-David-Frasheski.png" + }, + { + Name = "I - Ice and Death 2", + URL = "https://i.ibb.co/QDGV0jQ/Edge-1-Ice-and-Death-Felix-Riano.png" + }, + { + Name = "I - Ice and Death 3", + URL = "https://i.ibb.co/hFJQM8v/Edge-1-Ice-and-Death-Mike-Gizienski.png" + }, + { + Name = "??? - Fatal Mirage", + URL = "https://i.ibb.co/KzwvjJN/Edge-2-Fatal-Mirage-David-Frasheski.png" + }, + { + Name = "II - Forbidden Peaks 1", + URL = "https://i.ibb.co/C2SLByt/Edge-2-Forbidden-Peaks-David-Frasheski-2.png" + }, + { + Name = "II - Forbidden Peaks 2", + URL = "https://i.ibb.co/0cGkkBL/Edge-3-Forbidden-Peaks-David-Frasheski.png" + }, + { + Name = "III - City of Elder Things 1", + URL = "https://i.ibb.co/FbpgBD3/Edge-4-City-Francois-Baranger.png" + }, + { + Name = "III - City of Elder Things 2", + URL = "https://i.ibb.co/ncRvHr3/Edge-4-City-Francois-Baranger-2.png" + }, + { + Name = "IV - Heart of Madness 1", + URL = "https://i.ibb.co/rk0qR4z/Edge-5-Heart-of-Madness-Karol-Sollich.png" + }, + { + Name = "IV - Heart of Madness 2", + URL = "https://i.ibb.co/NVFjx6N/Edge-5-Heart-of-Madness-Miguel-Coimbra.png" + } + }, + ["The Scarlet Keys"] = { + { + Name = "5-A Riddles and Rain", + URL = "http://cloud-3.steamusercontent.com/ugc/2037357792057358580/E9E5FE4028C08B3D4883406821221B73C8B5B2C7/" + }, + { + Name = "11-B Dead Heat", + URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566443853/CAD7771D90141EA6D5FFAFE1EC5E7AD9647C82DB/" + }, + { + Name = "16-D Sanguine Shadows", + URL = "http://cloud-3.steamusercontent.com/ugc/2037357792057358704/4A7261EB31511467CBC46E876476DD205F528A4B/" + }, + { + Name = "21-F Dealings in the Dark", + URL = "http://cloud-3.steamusercontent.com/ugc/2037357792057358816/7C9FE4C34CD0A7AE87EF054742D878F310C71AA7/" + }, + { + Name = "28-I Dancing Mad", + URL = "http://cloud-3.steamusercontent.com/ugc/2037357792056955518/EAB857DD5629EC6A3078FB0A3A703B85B5F514B9/" + }, + { + Name = "23-K On Thin Ice", + URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444026/EB5628E254AE25DA89A9C999EAAD995ECF67068E/" + }, + { + Name = "38-N Dogs of War", + URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444199/194FD9A713907197471A55411AE300B62C5F5278/" + }, + { + Name = "46-Q Shades of Suffering", + URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444330/3ED2CCE95DE933546E1B5CBBF445D773E6D65465/" + }, + { + Name = "56-Y ???", + URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444450/FE4C335B0F72E83900A4EED0FD1A1D304D70D6B7/" + }, + { + Name = "59-Z Congress of Keys I", + URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444576/5BB32469ED412D59BB0A46E57D226500B1D0568B/" + }, + { + Name = "59-Z Congress of Keys II", + URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444690/B01A1FEAB57473D9B6DF11B92D62C214AA1C2C02/" + } + } + }, + ["Official Scenarios"] = { + ["The Blob That Ate Everything"] = { + { + Name = "The Blob That Ate Everything 1", + URL = "https://i.ibb.co/JxFV4ZN/Blob-That-Ate-Everything-Emilio-Rodriguez.jpg" + }, + { + Name = "The Blob That Ate Everything 2", + URL = "https://i.ibb.co/qJzstWF/Blob-That-Ate-Everything-Emilio-Rodriguez.jpg" + } + }, + ["Carnevale of Horrors"] = { + { + Name = "Carnevale of Horrors 1", + URL = "https://i.ibb.co/ZchJBpz/Carnevale-of-Horrors.jpg" + }, + }, + ["Curse of the Rougarou"] = { + { + Name = "Curse of the Rougarou 1", + URL = "https://i.ibb.co/Qf7Sr7P/Curse-of-the-Rougarou.jpg" + }, + { + Name = "Curse of the Rougarou 2", + URL = "https://i.ibb.co/hs1Qjp0/Curse-of-the-Rougarou-Ann-Kovaleva.jpg" + }, + { + Name = "Curse of the Rougarou 3", + URL = "https://i.ibb.co/BK7rmJ9/Curse-of-the-Rougarou-Karine-Villette.jpg" + }, + { + Name = "Curse of the Rougarou 4", + URL = "https://i.ibb.co/ZxGTC1w/Curse-of-the-Rougarou-Lachlan-Page.jpg" + }, + { + Name = "Curse of the Rougarou 5", + URL = "https://i.ibb.co/HgNXJhW/Curse-of-the-Rougarou-Vladimir-Manyukhin.jpg" + } + }, + ["Guardians of the Abyss"] = { + { + Name = "Guardians of the Abyss 1", + URL = "https://i.ibb.co/gD3R6cw/Guardians-of-the-Abyss-Jake-Murray.jpg" + }, + { + Name = "Guardians of the Abyss 2", + URL = "https://i.ibb.co/jMHPcvz/Guardians-of-the-Abyss-Jose-Vega.jpg" + }, + { + Name = "Guardians of the Abyss 3", + URL = "https://i.ibb.co/99pqXQP/Guardians-of-the-Abyss-Koke-Nunez.jpg" + }, + { + Name = "Guardians of the Abyss 4", + URL = "https://i.ibb.co/QbMvjbx/Guardians-of-the-Abyss-Mike-Szabados.jpg" + }, + { + Name = "Guardians of the Abyss 5", + URL = "https://i.ibb.co/zFDt9Q8/Guardians-of-the-Abyss-Nele-Diel.jpg" + }, + { + Name = "Guardians of the Abyss 6", + URL = "https://i.ibb.co/Vpzptmt/Guardians-of-the-Abyss-Yujin-Choo.jpg" + } + }, + ["Labyrinths of Lunacy"] = { + { + Name = "Labyrinths of Lunacy 1", + URL = "https://i.ibb.co/f17PMCC/Labyrinths-of-Lunacy-Cordelia-Wolf.jpg" + }, + { + Name = "Labyrinths of Lunacy 2", + URL = "https://i.ibb.co/44DXfWw/Labyrinths-of-Lunacy-Richard-Wright.jpg" + }, + { + Name = "Labyrinths of Lunacy 3", + URL = "https://i.ibb.co/jMQhs68/Labyrinths-of-Lunacy-Robert-Berg.jpg" + } + }, + ["Murder at Excelsior Hotel"] = { + { + Name = "Murder at Excelsior Hotel 1", + URL = "https://i.ibb.co/5cQ6LvN/Murder-at-Excelsior-Hotel-Alistair-Mitchell.jpg" + }, + { + Name = "Murder at Excelsior Hotel 2", + URL = "https://i.ibb.co/vBQRHNS/Murder-at-Excelsior-Hotel-Romain-Bayle.jpg" + } + }, + ["War of the Outer Gods"] = { + { + Name = "War of the Outer Gods", + URL = "https://i.ibb.co/wLNGFTG/War-of-the-Outer-Gods-Joshua-Cairos.jpg" + } + } + }, + ["Fan-Made Campaigns"] = { + ["Cyclopean Foundations"] = { + { + Name = "I - Lost Moorings 1", + URL = "https://i.ibb.co/DQ76z3c/Cyclopean-1-Lost-Moorings-Care-Line-Art.png" + }, + { + Name = "I - Lost Moorings 2", + URL = "https://i.ibb.co/c6LJNfr/Cyclopean-1-Lost-Moorings-Jake-Murray.png" + }, + { + Name = "II - Going Twice", + URL = "https://i.ibb.co/P6h3vbm/Cyclopean-2-Going-Twice-Quentin-Bouilloud.png" + }, + { + Name = "III - Private Lives", + URL = "https://i.ibb.co/9qK9Fzd/Cyclopean-3-Private-Lives-Christian-Bravery.png" + }, + { + Name = "IV - Crumbling Masonry 1", + URL = "https://i.ibb.co/pdrGK6p/Cyclopean-4-Crumbling-Masonry-Pete-Amachree.png" + }, + { + Name = "IV - Crumbling Masonry 2", + URL = "https://i.ibb.co/5RFcGyP/Cyclopean-4-Crumbling-Masonry-Simon-Craghead.png" + }, + { + Name = "V - Across Dreadful Waters", + URL = "https://i.ibb.co/3mYfFNB/Cyclopean-5-Across-Dreadful-Waters-Ev-Shipard.png" + }, + { + Name = "VI - Blood From Stones", + URL = "https://i.ibb.co/ynmQNSB/Cyclopean-6-Blood-From-Stones-Marc-Simonetti.png" + }, + { + Name = "VII - Pyroclastic Flow 1", + URL = "https://i.ibb.co/s1JDkFv/Cyclopean-7-Pyroclastic-Flow-Bastien-Grivet.png" + }, + { + Name = "VII - Pyroclastic Flow 2", + URL = "https://i.ibb.co/qs8Sk2N/Cyclopean-7-Pyroclastic-Flow-Rachid-Lotf.png" + }, + { + Name = "VIII - Tomb of Dead Dreams 1", + URL = "https://i.ibb.co/0MwX460/Cyclopean-8-Tomb-of-Dead-Dreams-Guillem-H-Pongiluppi.png" + }, + { + Name = "VIII - Tomb of Dead Dreams 2", + URL = "https://i.ibb.co/mGnKNcy/Cyclopean-8-Tomb-of-Dead-Dreams-Richard-Benning.png" + }, + { + Name = "VIII - Tomb of Dead Dreams 3", + URL = "https://i.ibb.co/vmBM8x2/Cyclopean-8-Tomb-of-Dead-Dreams-Walter-Brocca.png" + } + }, + ["Dark Matter"] = { + { + Name = "I - Tatterdemalion 1", + URL = "https://i.ibb.co/DRMPGVt/Dark-Matter-1-Tatterdemalion-Andrey-Vozny.jpg" + }, + { + Name = "I - Tatterdemalion 2", + URL = "https://i.ibb.co/1JzrrX2/Dark-Matter-1-Tatterdemalion-Brian-Taylor.jpg" + }, + { + Name = "I - Tatterdemalion 3", + URL = "https://i.ibb.co/DzvvgGf/Dark-Matter-1-Tatterdemalion-John-Wallin-Liberto.jpg" + }, + { + Name = "I - Tatterdemalion 4", + URL = "https://i.ibb.co/sQf85b8/Dark-Matter-1-Tatterdemalion-Paul-Pepera.jpg" + }, + { + Name = "II - Electric Nightmares 1", + URL = "https://i.ibb.co/hLGVBt7/Dark-Matter-2-Electric-Nightmares-Dean-Lawrence.jpg" + }, + { + Name = "II - Electric Nightmares 2", + URL = "https://i.ibb.co/cTKZQ61/Dark-Matter-2-Electric-Nightmares-Robert-Thoma.jpg" + }, + { + Name = "IIIa - Lost Quantum", + URL = "https://i.ibb.co/6vyXv90/Dark-Matter-3-Lost-Quantum-Michael-Rajecki.jpg" + }, + { + Name = "IIIb - In the Shadow of Earth 1", + URL = "https://i.ibb.co/DfbTKHP/Dark-Matter-4-In-the-Shadow-of-Earth-Jihoo-Kim.jpg" + }, + { + Name = "IIIb - In the Shadow of Earth 2", + URL = "https://i.ibb.co/MCvPmCb/Dark-Matter-4-In-the-Shadow-of-Earth-N5-Luckybuuncle.jpg" + }, + { + Name = "IIIc - Strange Moons", + URL = "https://i.ibb.co/b2d8qvg/Dark-Matter-5-Strange-Moons-Hongyu-Yin.jpg" + }, + { + Name = "V - Fragment of Carcosa 1", + URL = "https://i.ibb.co/7WnTyYT/Dark-Matter-7-Fragment-of-Carcosa-Colin-Moore.jpg" + }, + { + Name = "V - Fragment of Carcosa 2", + URL = "https://i.ibb.co/mG2Brrd/Dark-Matter-7-Fragments-of-Carcosa-Matthieu-Rebuffat.jpg" + }, + { + Name = "VI - Starfall 1", + URL = "https://i.ibb.co/CJ3LKL7/Dark-Matter-8-Starfall-Vadim-Sadovski.jpg" + }, + { + Name = "VI - Starfall 2", + URL = "https://i.ibb.co/Njd1FcB/Dark-Matter-8-Starfall-Vadim-Sadovski-2.jpg" + }, + { + Name = "VI - Starfall 3", + URL = "https://i.ibb.co/W0Cx7bb/Dark-Matter-8-Starfall-Vadim-Sadovski-3.jpg" + } + }, + ["The Ghosts of Onigawa"] = { + { + Name = "I - The Ghosts of Onigawa", + URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-01.png?raw=true" + }, + { + Name = "II - In The Shadow Of Mount Kokoro", + URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-02.png?raw=true" + }, + { + Name = "III - The Onigawa River", + URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-03.png?raw=true" + }, + { + Name = "IV - The Crimson Butterfly", + URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-04.png?raw=true" + }, + { + Name = "V - The Koi Conspiracy", + URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-05.png?raw=true" + } + } + }, + ["Fan-Made Scenarios"] = { + ["Side Scenarios (FM)"] = { + { + Name = "Consternation on the Constellation", + URL = "https://i.ibb.co/Tw2xBP1/Consternation-Constellation.jpg" + }, + { + Name = "Symphony of Erich Zann", + URL = "https://i.ibb.co/SNr8tqN/Symphony-of-Erich-Zann-Hazel-Yingling.jpg" + } + } + }, + ["Other Images"] = { + ["Arkham Locations"] = { + { + Name = "Downtown 1", + URL = "https://i.ibb.co/FzRk98n/Arkham-Downtown-Cristi-Balanescu.jpg" + }, + { + Name = "Downtown 2", + URL = "https://i.ibb.co/W2yJ5QZ/Arkham-Downtown-Jokubas-Uogintas.jpg" + }, + { + Name = "Eastside 1", + URL = "https://i.ibb.co/W3QvdZW/Arkham-Eastside-Cristi-Balanescu.jpg" + }, + { + Name = "Eastside 2", + URL = "https://i.ibb.co/xfn1Fp8/Arkham-Eastside-Jokubas-Uogintas.jpg" + }, + { + Name = "French Hill", + URL = "https://i.ibb.co/N7Lk7jc/Arkham-French-Hill-Cristi-Balanescu.jpg" + }, + { + Name = "Merchant District", + URL = "https://i.ibb.co/HTNCCq4/Arkham-Merchant-District-Jokubas-Uogintas.jpg" + }, + { + Name = "Generic 1", + URL = "https://i.ibb.co/hswfZD6/Arkham-Guillem-H-Pongiluppi.jpg" + }, + { + Name = "Generic 2", + URL = "https://i.ibb.co/5h5cMyF/Arkham-Guillem-H-Pongiluppi-2.jpg" + }, + { + Name = "Generic 3", + URL = "https://i.ibb.co/ZBdVsWt/Arkham-Guillem-H-Pongiluppi-3.jpg" + }, + { + Name = "Generic 4", + URL = "https://i.ibb.co/6NwbM59/Arkham-Michele-Botticelli.jpg" + }, + { + Name = "Generic 5", + URL = "https://i.ibb.co/N6sxyq5/Arkham-Mihail-Bila.jpg" + }, + { + Name = "Generic 6", + URL = "https://i.ibb.co/B393zxv/Arkham-Tomasz-Jedruszek.jpg" + }, + { + Name = "Generic 7", + URL = "https://i.ibb.co/2WQ2Vt6/Arkham-Tomasz-Jedruszek-2.jpg" + }, + { + Name = "Generic 8", + URL = "https://i.ibb.co/R7pQ9Y7/Arkham-Tomasz-Jedruszek-3.jpg" + }, + { + Name = "Miskatonic University", + URL = "https://i.ibb.co/ncz9xjP/Arkham-Miskatonic-University-Jokubas-Uogintas.jpg" + }, + { + Name = "Northside", + URL = "https://i.ibb.co/sVWx1R3/Arkham-Northside-Jokubas-Uogintas.jpg" + }, + { + Name = "Rivertown", + URL = "https://i.ibb.co/RyJnHmz/Arkham-Rivertown-Jokubas-Uogintas.jpg" + }, + { + Name = "Southside", + URL = "https://i.ibb.co/5GW5jg5/Arkham-Southside-Jokubas-Uogintas.jpg" + }, + { + Name = "Uptown", + URL = "https://i.ibb.co/YXjvkMn/Arkham-Uptown-Jokubas-Uogintas.jpg" + } + }, + ["Default Image"] = { + { + Name = "Default Image", + URL = "http://cloud-3.steamusercontent.com/ugc/998015670465071049/FFAE162920D67CF38045EFBD3B85AD0F916147B2/" + } + }, + ["Unsorted"] = { + { + Name = "Kingsport", + URL = "https://i.ibb.co/rbkk7ys/Kingsport-Tomasz-Jedruszek.jpg" + }, + { + Name = "Devil", + URL = "http://cloud-3.steamusercontent.com/ugc/2115062479282248687/DD84A3CB3C4A475A5D093CB413A16A5CEA5FBF79/" + }, + { + Name = "Mystic Board", + URL = "http://cloud-3.steamusercontent.com/ugc/2115062479282248488/EC27B1215F558A39954C27477D8B4F916CA211E5/" + } + } + } +} +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) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/PlayAreaSelector") +end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Playmat Image Swapper b7b45b.yaml b/unpacked/Custom_Token Playmat Image Swapper b7b45b.yaml index ab1bbf044..8e87a947e 100644 --- a/unpacked/Custom_Token Playmat Image Swapper b7b45b.yaml +++ b/unpacked/Custom_Token Playmat Image Swapper b7b45b.yaml @@ -30,7 +30,7 @@ IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: true LuaScript: !include 'Custom_Token Playmat Image Swapper b7b45b.ttslua' -LuaScriptState: '' +LuaScriptState: '{"selectionIndex":1,"typeIndex":1}' MeasureMovement: false Name: Custom_Token Nickname: Playmat Image Swapper diff --git a/unpacked/Custom_Token Resources cd15ac.ttslua b/unpacked/Custom_Token Resources cd15ac.ttslua index 85608f361..3e8cdcc2f 100644 --- a/unpacked/Custom_Token Resources cd15ac.ttslua +++ b/unpacked/Custom_Token Resources cd15ac.ttslua @@ -41,6 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/GenericCounter") +end) __bundle_register("core/GenericCounter", function(require, _LOADED, __bundle_register, __bundle_modules) MIN_VALUE = 0 MAX_VALUE = 99 @@ -97,7 +100,4 @@ function addOrSubtract(_, _, isRightClick) self.editButton({ index = 0, label = tostring(val) }) end end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/GenericCounter") -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token SCED Tour 0e5aa8.ttslua b/unpacked/Custom_Token SCED Tour 0e5aa8.ttslua index bc570632f..1b433d1ae 100644 --- a/unpacked/Custom_Token SCED Tour 0e5aa8.ttslua +++ b/unpacked/Custom_Token SCED Tour 0e5aa8.ttslua @@ -41,6 +41,9 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) +require("core/tour/TourStarter") +end) __bundle_register("core/tour/TourStarter", function(require, _LOADED, __bundle_register, __bundle_modules) local tourManager = require("core/tour/TourManager") @@ -81,8 +84,9 @@ __bundle_register("core/tour/TourManager", function(require, _LOADED, __bundle_r do require("core/tour/TourScript") require("core/tour/TourCard") - local TourManager = { } - local internal = { } + local TourManager = {} + local internal = {} + local guidReferenceApi = require("core/GUIDReferenceApi") -- Base IDs for various tour card UI elements. Actual IDs will have _[playerColor] appended local CARD_ID = "tourCard" @@ -203,8 +207,9 @@ do delay = delay + 0.5 end local lookPos - if TOUR_SCRIPT[cardIndex].showObj ~= nil then - local lookAtObj = getObjectFromGUID(TOUR_SCRIPT[cardIndex].showObj) + local objReferenceData = TOUR_SCRIPT[cardIndex].objReferenceData + if objReferenceData ~= nil then + local lookAtObj = guidReferenceApi.getObjectByOwnerAndType(objReferenceData.owner, objReferenceData.type) lookPos = lookAtObj.getPosition() lookPos.y = TOUR_SCRIPT[cardIndex].distanceFromObj or 0 -- Since camera isn't directly above the hook, changing the Y affects the visual position of @@ -362,6 +367,36 @@ do return TourManager 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) __bundle_register("core/tour/TourCard", function(require, _LOADED, __bundle_register, __bundle_modules) -- Table definition for the tour card layout. This is functionally XMLUI in Lua form, but using -- this for dynamic creation ensures we can handle any player color without needing 10 @@ -475,7 +510,7 @@ TOUR_SCRIPT = { { narrator = "Daisy", text = "If you're new to the game, the library here has everything you'll need. A little research can go a long way, and looking into old newspapers for the weird and unusual can yield some surprisingly helpful information.\n\nI put a few right there that might prove enlightening.", - showObj = "d99993", + objReferenceData = { owner = "Mythos", type = "RulesReference" }, distanceFromObj = 20, position = "west", speakerSide = "right" @@ -483,7 +518,7 @@ TOUR_SCRIPT = { { narrator = "Mandy", text = "To survive what's coming you'll need a deck. If it's safely hidden away on ArkhamDB you can load it here, and even find the newest version after an upgrade without changing the ID.\n\nNo need to publish all your decks, use 'Private' and you can see it. Just make sure to select 'Make your decks public' in ArkhamDB.", - showObj = "a28140", + objReferenceData = { owner = "Mythos", type = "DeckImporter" }, distanceFromObj = -5, position = "northwest", skipCentering = true, @@ -491,7 +526,7 @@ TOUR_SCRIPT = { { narrator = "Daniela", text = "I prefer the hands-on approach to building things, if you do too you can build a deck yourself.\n\nAll the cards you could ever need are here, laid out like a disassembled engine. Place the cards on the table, copy them for your deck, and you'll be ready for anything.", - showObj = "2d30ee", + objReferenceData = { owner = "Mythos", type = "PlayerCardPanel" }, distanceFromObj = -7, position = "south", speakerSide = "right" @@ -499,7 +534,7 @@ TOUR_SCRIPT = { { narrator = "Finn", text = "Ready to face the unknown? We've smuggled shocking revelations and devious enemies from all over the world. Download the campaign you want to play, then Place it on the table to see the scenarios.\n\nJust remember - if it turns out to be too much for you, I was never here.", - showObj = "aca04c", + objReferenceData = { owner = "Mythos", type = "CampaignThePathToCarcosa" }, distanceFromObj = 20, position = "northwest", }, @@ -537,7 +572,7 @@ TOUR_SCRIPT = { { narrator = "Preston", text = "I can afford to buy what I need, but for those less well-off we've provided an endless pool of tokens to track your game. Simply drag one out of the pools here.\n\nResources are my favorite of course, but damage and horror are as inevitable as taxes. I leave those to my bookkeeper though. Those tokens can work like counters, use the number keys to change the value.", - showObj = "9fadf9", + objReferenceData = { owner = "Mythos", type = "ResourceTokenBag" }, position = "north", skipCentering = true, speakerSide = "right" @@ -550,7 +585,4 @@ TOUR_SCRIPT = { }, } end) -__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) -require("core/tour/TourStarter") -end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Custom_Token Search-A-Card 24051a.ttslua b/unpacked/Custom_Token Search-A-Card 24051a.ttslua index 526b860fa..f5819ebf6 100644 --- a/unpacked/Custom_Token Search-A-Card 24051a.ttslua +++ b/unpacked/Custom_Token Search-A-Card 24051a.ttslua @@ -41,6 +41,36 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("playercards/CardSearch") end) @@ -167,30 +197,34 @@ end) __bundle_register("playercards/AllCardsBagApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local AllCardsBagApi = {} - local ALL_CARDS_BAG_GUID = "15bb07" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getAllCardsBag() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "AllCardsBag") + end -- Returns a specific card from the bag, based on ArkhamDB ID - -- @param table: - -- id: String ID of the card to retrieve - -- @return: If the indexes are still being constructed, an empty table is - -- returned. Otherwise, a single table with the following fields - -- cardData: TTS object data, suitable for spawning the card - -- cardMetadata: Table of parsed metadata + ---@param id table String ID of the card to retrieve + ---@return table table + -- If the indexes are still being constructed, an empty table is + -- returned. Otherwise, a single table with the following fields + -- cardData: TTS object data, suitable for spawning the card + -- cardMetadata: Table of parsed metadata AllCardsBagApi.getCardById = function(id) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardById", {id = id}) + return getAllCardsBag().call("getCardById", {id = id}) end -- Gets a random basic weakness from the bag. Once a given ID has been returned -- it will be removed from the list and cannot be selected again until a reload -- occurs or the indexes are rebuilt, which will refresh the list to include all -- weaknesses. - -- @return: String ID of the selected weakness. + ---@return id String ID of the selected weakness. AllCardsBagApi.getRandomWeaknessId = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getRandomWeaknessId") + return getAllCardsBag().call("getRandomWeaknessId") end AllCardsBagApi.isIndexReady = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("isIndexReady") + return getAllCardsBag().call("isIndexReady") end -- Called by Hotfix bags when they load. If we are still loading indexes, then @@ -199,40 +233,38 @@ do -- called once indexing is complete it means the hotfix bag has been added -- later, and we should rebuild the index to integrate the hotfix bag. AllCardsBagApi.rebuildIndexForHotfix = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("rebuildIndexForHotfix") + return getAllCardsBag().call("rebuildIndexForHotfix") end -- Searches the bag for cards which match the given name and returns a list. Note that this is -- an O(n) search without index support. It may be slow. - -- @param - -- name String or string fragment to search for names - -- exact Whether the name match should be exact + ---@param name String or string fragment to search for names + ---@param exact Boolean Whether the name match should be exact AllCardsBagApi.getCardsByName = function(name, exact) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardsByName", {name = name, exact = exact}) + return getAllCardsBag().call("getCardsByName", {name = name, exact = exact}) end AllCardsBagApi.isBagPresent = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID) and true + return getAllCardsBag() and true end -- Returns a list of cards from the bag matching a class and level (0 or upgraded) - -- @param - -- class: String class to retrieve ("Guardian", "Seeker", etc) - -- upgraded: true for upgraded cards (Level 1-5), false for Level 0 - -- @return: If the indexes are still being constructed, returns an empty table. + ---@param class String class to retrieve ("Guardian", "Seeker", etc) + ---@param upgraded Boolean true for upgraded cards (Level 1-5), false for Level 0 + ---@return: If the indexes are still being constructed, returns an empty table. -- Otherwise, a list of tables, each with the following fields -- cardData: TTS object data, suitable for spawning the card -- cardMetadata: Table of parsed metadata AllCardsBagApi.getCardsByClassAndLevel = function(class, upgraded) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardsByClassAndLevel", {class = class, upgraded = upgraded}) + return getAllCardsBag().call("getCardsByClassAndLevel", {class = class, upgraded = upgraded}) end AllCardsBagApi.getCardsByCycle = function(cycle) - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getCardsByCycle", cycle) + return getAllCardsBag().call("getCardsByCycle", cycle) end AllCardsBagApi.getUniqueWeaknesses = function() - return getObjectFromGUID(ALL_CARDS_BAG_GUID).call("getUniqueWeaknesses") + return getAllCardsBag().call("getUniqueWeaknesses") end return AllCardsBagApi diff --git a/unpacked/Custom_Token Token Arranger 022907.ttslua b/unpacked/Custom_Token Token Arranger 022907.ttslua index 270353aa8..76d2fa9fc 100644 --- a/unpacked/Custom_Token Token Arranger 022907.ttslua +++ b/unpacked/Custom_Token Token Arranger 022907.ttslua @@ -44,16 +44,25 @@ end)(nil) __bundle_register("core/MythosAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local MythosAreaApi = {} - local MYTHOS_AREA_GUID = "9f334f" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getMythosArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "MythosArea") + end -- returns the chaos token metadata (if provided through scenario reference card) MythosAreaApi.returnTokenData = function() - return getObjectFromGUID(MYTHOS_AREA_GUID).call("returnTokenData") + return getMythosArea().call("returnTokenData") + end + + -- returns an object reference to the encounter deck + MythosAreaApi.getEncounterDeck = function() + return getMythosArea().call("getEncounterDeck") end -- draw an encounter card to the requested position/rotation MythosAreaApi.drawEncounterCard = function(pos, rotY, alwaysFaceUp) - getObjectFromGUID(MYTHOS_AREA_GUID).call("drawEncounterCard", { + getMythosArea().call("drawEncounterCard", { pos = pos, rotY = rotY, alwaysFaceUp = alwaysFaceUp @@ -63,6 +72,36 @@ do return MythosAreaApi 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) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("accessories/TokenArranger") end) @@ -138,7 +177,13 @@ function onLoad(saveState) end createButtonsAndInputs() - + + -- maybe trigger layout() to draw percentage buttons + local objList = getObjectsWithTag("tempToken") + if #objList > 0 then + Wait.time(layout, 0.5) + end + -- context menu items self.addContextMenuItem("Load default values", function() loadDefaultValues() @@ -302,7 +347,7 @@ end -- creates buttons as labels as display for percentage values function createPercentageButton(tokenCount, valueCount, tokenName) - local startPos = Vector(2.3, -0.05, 0.875 * valueCount) + local startPos = Vector(2.3, -0.04, 0.875 * valueCount) if percentage == "cumulative" then percentageLabel.scale = { 1.5, 1.5, 1.5 } @@ -381,6 +426,10 @@ function layout(_, _, isRightClick) local value = tonumber(objData.Nickname) local precedence = tokenPrecedence[objData.Nickname] + -- remove GUID to avoid issues for high latency clients + objData["GUID"] = nil + + -- store data with value / precendence data[i] = { token = objData, value = value or precedence[1] diff --git a/unpacked/Custom_Token Token Arranger 022907.yaml b/unpacked/Custom_Token Token Arranger 022907.yaml index 1650ef333..6220ed80b 100644 --- a/unpacked/Custom_Token Token Arranger 022907.yaml +++ b/unpacked/Custom_Token Token Arranger 022907.yaml @@ -39,8 +39,6 @@ Name: Custom_Token Nickname: Token Arranger Snap: true Sticky: true -Tags: -- TokenArranger Tooltip: true Transform: posX: -42.3 diff --git a/unpacked/Custom_Token Victory Display 6ccd6d.ttslua b/unpacked/Custom_Token Victory Display 6ccd6d.ttslua index 44c54c9a8..94135b13d 100644 --- a/unpacked/Custom_Token Victory Display 6ccd6d.ttslua +++ b/unpacked/Custom_Token Victory Display 6ccd6d.ttslua @@ -41,11 +41,162 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local PlayAreaApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getPlayArea() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayArea") + end + + local function getInvestigatorCounter() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "InvestigatorCounter") + end + + -- Returns the current value of the investigator counter from the playmat + ---@return Integer. Number of investigators currently set on the counter + PlayAreaApi.getInvestigatorCount = function() + return getInvestigatorCounter().getVar("val") + end + + -- Updates the current value of the investigator counter from the playmat + ---@param count Number of investigators to set on the counter + PlayAreaApi.setInvestigatorCount = function(count) + getInvestigatorCounter().call("updateVal", count) + end + + -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain + -- fixed objects will be ignored, as will anything the player has tagged with 'displacement_excluded' + ---@param playerColor Color Color of the player requesting the shift for messages + PlayAreaApi.shiftContentsUp = function(playerColor) + return getPlayArea().call("shiftContentsUp", playerColor) + end + + PlayAreaApi.shiftContentsDown = function(playerColor) + return getPlayArea().call("shiftContentsDown", playerColor) + end + + PlayAreaApi.shiftContentsLeft = function(playerColor) + return getPlayArea().call("shiftContentsLeft", playerColor) + end + + PlayAreaApi.shiftContentsRight = function(playerColor) + return getPlayArea().call("shiftContentsRight", playerColor) + end + + -- Reset the play area's tracking of which cards have had tokens spawned. + PlayAreaApi.resetSpawnedCards = function() + return getPlayArea().call("resetSpawnedCards") + end + + -- Event to be called when the current scenario has changed. + ---@param scenarioName Name of the new scenario + PlayAreaApi.onScenarioChanged = function(scenarioName) + getPlayArea().call("onScenarioChanged", scenarioName) + end + + -- Sets this playmat's snap points to limit snapping to locations or not. + -- If matchTypes is false, snap points will be reset to snap all cards. + ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. + PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) + getPlayArea().call("setLimitSnapsByType", matchCardTypes) + end + + -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged + -- cards before they're destroyed by entering the container + PlayAreaApi.tryObjectEnterContainer = function(container, object) + getPlayArea().call("tryObjectEnterContainer", { container = container, object = object }) + end + + -- counts the VP on locations in the play area + PlayAreaApi.countVP = function() + return getPlayArea().call("countVP") + end + + -- highlights all locations in the play area without metadata + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightMissingData = function(state) + return getPlayArea().call("highlightMissingData", state) + end + + -- highlights all locations in the play area with VP + ---@param state Boolean True if highlighting should be enabled + PlayAreaApi.highlightCountedVP = function(state) + return getPlayArea().call("countVP", state) + end + + -- Checks if an object is in the play area (returns true or false) + PlayAreaApi.isInPlayArea = function(object) + return getPlayArea().call("isInPlayArea", object) + end + + PlayAreaApi.getSurface = function() + return getPlayArea().getCustomObject().image + end + + PlayAreaApi.updateSurface = function(url) + return getPlayArea().call("updateSurface", url) + end + + -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the + -- data to the local token manager instance. + ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call + PlayAreaApi.updateLocations = function(args) + getPlayArea().call("updateLocations", args) + end + + PlayAreaApi.getCustomDataHelper = function() + return getPlayArea().getVar("customDataHelper") + end + + return PlayAreaApi +end +end) +__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local CHAOS_TOKEN_NAMES = { + ["Elder Sign"] = true, + ["+1"] = true, + ["0"] = true, + ["-1"] = true, + ["-2"] = true, + ["-3"] = true, + ["-4"] = true, + ["-5"] = true, + ["-6"] = true, + ["-7"] = true, + ["-8"] = true, + ["Skull"] = true, + ["Cultist"] = true, + ["Tablet"] = true, + ["Elder Thing"] = true, + ["Auto-fail"] = true, + ["Bless"] = true, + ["Curse"] = true, + ["Frost"] = true + } + + local TokenChecker = {} + + -- returns true if the passed object is a chaos token (by name) + TokenChecker.isChaosToken = function(obj) + if CHAOS_TOKEN_NAMES[obj.getName()] then + return true + else + return false + end + end + + return TokenChecker +end +end) __bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules) require("core/VictoryDisplay") end) __bundle_register("core/VictoryDisplay", function(require, _LOADED, __bundle_register, __bundle_modules) local chaosBagApi = require("chaosbag/ChaosBagApi") +local guidReferenceApi = require("core/GUIDReferenceApi") local playAreaApi = require("core/PlayAreaApi") local tokenChecker = require("core/token/TokenChecker") @@ -57,13 +208,8 @@ local countedVP = {} local highlightMissing = false local highlightCounted = false -local TRASHCAN -local TRASHCAN_GUID = "70b9f6" - -- button creation when loading the game function onLoad() - TRASHCAN = getObjectFromGUID(TRASHCAN_GUID) - -- index 0: VP - "Display" local buttonParameters = {} buttonParameters.label = "0" @@ -263,8 +409,7 @@ end function highlightMissingData() self.editButton({ index = 3, - tooltip = (highlightMissing and "Enable" or "Disable") .. - " highlighting of cards without metadata (VP on these is not counted)." + tooltip = (highlightMissing and "Enable" or "Disable") .. " highlighting of cards without metadata (VP on these is not counted)." }) for _, obj in pairs(missingData) do if obj ~= nil then @@ -283,8 +428,7 @@ end function highlightCountedVP() self.editButton({ index = 4, - tooltip = (highlightCounted and "Enable" or "Disable") .. - " highlighting of cards with VP." + tooltip = (highlightCounted and "Enable" or "Disable") .. " highlighting of cards with VP." }) for _, obj in pairs(countedVP) do if obj ~= nil then @@ -301,6 +445,8 @@ end -- places the provided card in the first empty spot function placeCard(card) + local trash = guidReferenceApi.getObjectByOwnerAndType("Mythos", "Trash") + -- check snap point states local snaps = self.getSnapPoints() table.sort(snaps, function(a, b) return a.position.x > b.position.x end) @@ -330,7 +476,7 @@ function placeCard(card) local chaosBag = chaosBagApi.findChaosBag() chaosBag.putObject(obj) elseif obj.memo ~= nil and obj.getLock() == false then - TRASHCAN.putObject(obj) + trash.putObject(obj) end end @@ -374,16 +520,6 @@ function checkSnapPointState(pos) origin = pos }) end - --- search a table for a value, return true if found (else returns false) -function tableContains(table, value) - for _, v in ipairs(table) do - if v == value then - return true - end - end - return false -end end) __bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules) do @@ -461,150 +597,34 @@ do return ChaosBagApi end end) -__bundle_register("core/PlayAreaApi", function(require, _LOADED, __bundle_register, __bundle_modules) +__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlayAreaApi = { } - local PLAY_AREA_GUID = "721ba2" - local INVESTIGATOR_COUNTER_GUID = "f182ee" + local GUIDReferenceApi = {} - -- Returns the current value of the investigator counter from the playmat - ---@return Integer. Number of investigators currently set on the counter - PlayAreaApi.getInvestigatorCount = function() - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).getVar("val") + local function getGuidHandler() + return getObjectFromGUID("123456") end - -- Updates the current value of the investigator counter from the playmat - ---@param count Number of investigators to set on the counter - PlayAreaApi.setInvestigatorCount = function(count) - return getObjectFromGUID(INVESTIGATOR_COUNTER_GUID).call("updateVal", count) + -- 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 - -- Move all contents on the play area (cards, tokens, etc) one slot in the given direction. Certain - -- fixed objects will be ignored, as will anything the player has tagged with - -- 'displacement_excluded' - ---@param playerColor Color of the player requesting the shift. Used solely to send an error - --- message in the unlikely case that the scripting zone has been deleted - PlayAreaApi.shiftContentsUp = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsUp", playerColor) + -- 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 - PlayAreaApi.shiftContentsDown = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsDown", playerColor) + -- 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 - PlayAreaApi.shiftContentsLeft = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsLeft", playerColor) - end - - PlayAreaApi.shiftContentsRight = function(playerColor) - return getObjectFromGUID(PLAY_AREA_GUID).call("shiftContentsRight", playerColor) - end - - -- Reset the play area's tracking of which cards have had tokens spawned. - PlayAreaApi.resetSpawnedCards = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("resetSpawnedCards") - end - - -- Event to be called when the current scenario has changed. - ---@param scenarioName Name of the new scenario - PlayAreaApi.onScenarioChanged = function(scenarioName) - getObjectFromGUID(PLAY_AREA_GUID).call("onScenarioChanged", scenarioName) - end - - -- Sets this playmat's snap points to limit snapping to locations or not. - -- If matchTypes is false, snap points will be reset to snap all cards. - ---@param matchTypes Boolean Whether snap points should only snap for the matching card types. - PlayAreaApi.setLimitSnapsByType = function(matchCardTypes) - getObjectFromGUID(PLAY_AREA_GUID).call("setLimitSnapsByType", matchCardTypes) - end - - -- Receiver for the Global tryObjectEnterContainer event. Used to clear vector lines from dragged - -- cards before they're destroyed by entering the container - PlayAreaApi.tryObjectEnterContainer = function(container, object) - getObjectFromGUID(PLAY_AREA_GUID).call("tryObjectEnterContainer", - { container = container, object = object }) - end - - -- counts the VP on locations in the play area - PlayAreaApi.countVP = function() - return getObjectFromGUID(PLAY_AREA_GUID).call("countVP") - end - - -- highlights all locations in the play area without metadata - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightMissingData = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightMissingData", state) - end - - -- highlights all locations in the play area with VP - ---@param state Boolean True if highlighting should be enabled - PlayAreaApi.highlightCountedVP = function(state) - return getObjectFromGUID(PLAY_AREA_GUID).call("highlightCountedVP", state) - end - - -- Checks if an object is in the play area (returns true or false) - PlayAreaApi.isInPlayArea = function(object) - return getObjectFromGUID(PLAY_AREA_GUID).call("isInPlayArea", object) - end - - PlayAreaApi.getSurface = function() - return getObjectFromGUID(PLAY_AREA_GUID).getCustomObject().image - end - - PlayAreaApi.updateSurface = function(url) - return getObjectFromGUID(PLAY_AREA_GUID).call("updateSurface", url) - end - - -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the - -- data to the local token manager instance. - ---@param args Table Single-value array holding the GUID of the Custom Data Helper making the call - PlayAreaApi.updateLocations = function(args) - getObjectFromGUID(PLAY_AREA_GUID).call("updateLocations", args) - end - - PlayAreaApi.getCustomDataHelper = function() - return getObjectFromGUID(PLAY_AREA_GUID).getVar("customDataHelper") - end - - return PlayAreaApi -end -end) -__bundle_register("core/token/TokenChecker", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local CHAOS_TOKEN_NAMES = { - ["Elder Sign"] = true, - ["+1"] = true, - ["0"] = true, - ["-1"] = true, - ["-2"] = true, - ["-3"] = true, - ["-4"] = true, - ["-5"] = true, - ["-6"] = true, - ["-7"] = true, - ["-8"] = true, - ["Skull"] = true, - ["Cultist"] = true, - ["Tablet"] = true, - ["Elder Thing"] = true, - ["Auto-fail"] = true, - ["Bless"] = true, - ["Curse"] = true, - ["Frost"] = true - } - - local TokenChecker = {} - - -- returns true if the passed object is a chaos token (by name) - TokenChecker.isChaosToken = function(obj) - if CHAOS_TOKEN_NAMES[obj.getName()] then - return true - else - return false - end - end - - return TokenChecker + return GUIDReferenceApi end end) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/Deck Tarot Deck 77f1e5.yaml b/unpacked/Deck Tarot Deck 77f1e5.yaml index bfdfdbb3c..a35bea040 100644 --- a/unpacked/Deck Tarot Deck 77f1e5.yaml +++ b/unpacked/Deck Tarot Deck 77f1e5.yaml @@ -627,8 +627,7 @@ ContainedObjects: to require ' .. identifier .. ', but no such module has been registered')\n\t\t\t\telse\n\t\t\t\t\treturn superRequire(name)\n\t\t\t\tend\n\t\t\tend\n\n\t\t\tloaded[name] = loadingPlaceholder\n\t\t\tloadedModule = modules[name](require, loaded, register, modules)\n\t\t\tloaded[name] = loadedModule\n\t\tend\n\n\t\treturn - loadedModule\n\tend\n\n\treturn require, loaded, register, modules\nend)(nil)\n__bundle_register(\"__root\", - function(require, _LOADED, __bundle_register, __bundle_modules)\nrequire(\"playercards/Tarotcard\")\nend)\n__bundle_register(\"playercards/Tarotcard\", + loadedModule\n\tend\n\n\treturn require, loaded, register, modules\nend)(nil)\n__bundle_register(\"playercards/Tarotcard\", function(require, _LOADED, __bundle_register, __bundle_modules)\n-- context menu to manually fix rotation\nfunction onLoad()\n self.addContextMenuItem(\"Rotate Preview\", rotatePreview)\n self.addContextMenuItem(\"Rotate Card+Preview\", @@ -636,7 +635,9 @@ ContainedObjects: \ local angle = self.alt_view_angle\n if angle.y == 0 then\n angle.y = 180\n \ else\n angle.y = 0\n end\n self.alt_view_angle = angle\nend\n\n-- rotates this card and the preview\nfunction rotateSelfAndPreview()\n self.setRotationSmooth(self.getRotation() - + Vector(0, 180, 0))\n rotatePreview()\nend\nend)\nreturn __bundle_require(\"__root\")" + + Vector(0, 180, 0))\n rotatePreview()\nend\nend)\n__bundle_register(\"__root\", + function(require, _LOADED, __bundle_register, __bundle_modules)\nrequire(\"playercards/Tarotcard\")\nend)\nreturn + __bundle_require(\"__root\")" LuaScriptState: '' MeasureMovement: false Name: Card @@ -1492,7 +1493,8 @@ ContainedObjects: to require ' .. identifier .. ', but no such module has been registered')\n\t\t\t\telse\n\t\t\t\t\treturn superRequire(name)\n\t\t\t\tend\n\t\t\tend\n\n\t\t\tloaded[name] = loadingPlaceholder\n\t\t\tloadedModule = modules[name](require, loaded, register, modules)\n\t\t\tloaded[name] = loadedModule\n\t\tend\n\n\t\treturn - loadedModule\n\tend\n\n\treturn require, loaded, register, modules\nend)(nil)\n__bundle_register(\"playercards/Tarotcard\", + loadedModule\n\tend\n\n\treturn require, loaded, register, modules\nend)(nil)\n__bundle_register(\"__root\", + function(require, _LOADED, __bundle_register, __bundle_modules)\nrequire(\"playercards/Tarotcard\")\nend)\n__bundle_register(\"playercards/Tarotcard\", function(require, _LOADED, __bundle_register, __bundle_modules)\n-- context menu to manually fix rotation\nfunction onLoad()\n self.addContextMenuItem(\"Rotate Preview\", rotatePreview)\n self.addContextMenuItem(\"Rotate Card+Preview\", @@ -1500,9 +1502,7 @@ ContainedObjects: \ local angle = self.alt_view_angle\n if angle.y == 0 then\n angle.y = 180\n \ else\n angle.y = 0\n end\n self.alt_view_angle = angle\nend\n\n-- rotates this card and the preview\nfunction rotateSelfAndPreview()\n self.setRotationSmooth(self.getRotation() - + Vector(0, 180, 0))\n rotatePreview()\nend\nend)\n__bundle_register(\"__root\", - function(require, _LOADED, __bundle_register, __bundle_modules)\nrequire(\"playercards/Tarotcard\")\nend)\nreturn - __bundle_require(\"__root\")" + + Vector(0, 180, 0))\n rotatePreview()\nend\nend)\nreturn __bundle_require(\"__root\")" LuaScriptState: '' MeasureMovement: false Name: Card diff --git a/unpacked/HandTrigger 0285cc.yaml b/unpacked/HandTrigger 0285cc.yaml index dd7288097..fc5d95893 100644 --- a/unpacked/HandTrigger 0285cc.yaml +++ b/unpacked/HandTrigger 0285cc.yaml @@ -29,13 +29,13 @@ Snap: true Sticky: true Tooltip: true Transform: - posX: -30.5 + posX: -30.35 posY: 6 - posZ: 36.05 + posZ: 36.6 rotX: 0 rotY: 180 rotZ: 0 - scaleX: 21.96 + scaleX: 22 scaleY: 7 scaleZ: 5 Value: 0 diff --git a/unpacked/HandTrigger 5fe087.yaml b/unpacked/HandTrigger 5fe087.yaml index ac09c3688..8449fa035 100644 --- a/unpacked/HandTrigger 5fe087.yaml +++ b/unpacked/HandTrigger 5fe087.yaml @@ -29,13 +29,13 @@ Snap: true Sticky: true Tooltip: true Transform: - posX: -65.7 + posX: -65 posY: 6 - posZ: -15.5 + posZ: -16.1 rotX: 0 rotY: 90 rotZ: 0 - scaleX: 22.96 + scaleX: 22 scaleY: 7 scaleZ: 5 Value: 0 diff --git a/unpacked/HandTrigger a70eee.yaml b/unpacked/HandTrigger a70eee.yaml index 8b5c1a579..48ccbbbdf 100644 --- a/unpacked/HandTrigger a70eee.yaml +++ b/unpacked/HandTrigger a70eee.yaml @@ -29,13 +29,13 @@ Snap: true Sticky: true Tooltip: true Transform: - posX: -65.7 + posX: -65 posY: 6 - posZ: 15.5 + posZ: 16.1 rotX: 0 rotY: 90 rotZ: 0 - scaleX: 22.96 + scaleX: 22 scaleY: 7 scaleZ: 5 Value: 0 diff --git a/unpacked/HandTrigger be2f17.yaml b/unpacked/HandTrigger be2f17.yaml index b9d322441..09ab9ea00 100644 --- a/unpacked/HandTrigger be2f17.yaml +++ b/unpacked/HandTrigger be2f17.yaml @@ -29,13 +29,13 @@ Snap: true Sticky: true Tooltip: true Transform: - posX: -30.5 + posX: -30.35 posY: 6 - posZ: -36.36 + posZ: -36.6 rotX: 0 rotY: 0 rotZ: 0 - scaleX: 21.96 + scaleX: 22 scaleY: 7 scaleZ: 5 Value: 0 diff --git a/unpacked/Notecard Arkham SCE 3.3.0 - 1092023 - Page 1 964222.yaml b/unpacked/Notecard Arkham SCE 3.3.0 - 1092023 - Page 1 964222.yaml deleted file mode 100644 index 46ef04004..000000000 --- a/unpacked/Notecard Arkham SCE 3.3.0 - 1092023 - Page 1 964222.yaml +++ /dev/null @@ -1,237 +0,0 @@ -AltLookAngle: - x: 0 - y: 0 - z: 0 -Autoraise: true -ColorDiffuse: - b: 1 - g: 1 - r: 1 -Description: 'Thanks for downloading Arkham SCE 3.3.0! - - - - Added 2023-08-30 taboo list. Note that the prior 2022-08-26 taboo list is no longer - supported. - - - Added some of the previewed player cards from Feast of Hemlock Vale. - - - Removed broken content from and cleaned up the community player card/investigator - box.' -DragSelectable: true -GMNotes: '' -GUID: '964222' -Grid: true -GridProjection: false -Hands: false -HideWhenFaceDown: false -IgnoreFoW: false -LayoutGroupSortIndex: 0 -Locked: false -LuaScript: '' -LuaScriptState: '' -MeasureMovement: false -Name: Notecard -Nickname: Arkham SCE 3.3.0 - 10/9/2023 - Page 1 -Snap: true -States: - '2': - AltLookAngle: - x: 0 - y: 0 - z: 0 - Autoraise: true - ColorDiffuse: - b: 1 - g: 1 - r: 1 - Description: "- Added the following community contributions:\n Buffy the Vampire - Slayer by AtomicZ!\n City of Secrets by Exhaled Innards!\n Circus Ex Mortis - Investigator Expansion by The\n Beard!\n Heart of Darkness by Vinn Quest!\n - \ The Red Coterie Investigators by\n Mattastrophic!\n (continued)" - DragSelectable: true - GMNotes: '' - GUID: d7faf7 - Grid: true - GridProjection: false - Hands: false - HideWhenFaceDown: false - IgnoreFoW: false - LayoutGroupSortIndex: 0 - Locked: false - LuaScript: '' - LuaScriptState: '' - MeasureMovement: false - Name: Notecard - Nickname: Arkham SCE 3.3.0 - 10/9/2023 - Page 2 - Snap: true - Sticky: true - Tooltip: true - Transform: - posX: -26.88849 - posY: 1.551499 - posZ: -60.2882576 - rotX: 0 - rotY: 90 - rotZ: 0 - scaleX: 3 - scaleY: 1 - scaleZ: 3 - Value: 0 - XmlUI: '' - '3': - AltLookAngle: - x: 0 - y: 0 - z: 0 - Autoraise: true - ColorDiffuse: - b: 1 - g: 1 - r: 1 - Description: " The Sands of Memphis by Myriad!\n Souls of Darkness by JackOfHearts!\n- - The options panel has a new option to spawn clickable counters only on \"0 uses\" - cards. Try the \"Chef's Selection\" option for the best of both worlds!\n- Increased - readability of master Clue Counter's text." - DragSelectable: true - GMNotes: '' - GUID: 50d85e - Grid: true - GridProjection: false - Hands: false - HideWhenFaceDown: false - IgnoreFoW: false - LayoutGroupSortIndex: 0 - Locked: false - LuaScript: '' - LuaScriptState: '' - MeasureMovement: false - Name: Notecard - Nickname: Arkham SCE 3.3.0 - 10/9/2023 - Page 3 - Snap: true - Sticky: true - Tooltip: true - Transform: - posX: -26.88849 - posY: 1.551499 - posZ: -60.2882576 - rotX: 0 - rotY: 90 - rotZ: 0 - scaleX: 3 - scaleY: 1 - scaleZ: 3 - Value: 0 - XmlUI: '' - '4': - AltLookAngle: - x: 0 - y: 0 - z: 0 - Autoraise: true - ColorDiffuse: - b: 1 - g: 1 - r: 1 - Description: '- General refactoring of code involving encounter card drawing, - metadata, and the deck importer. - - - Added context menu option to Well-Connected to auto-calculate its skill bonus. - - - Fixed clues not spawning properly at very high clue counts. - - - Underworld Market helper no longer breaks when saving and loading.' - DragSelectable: true - GMNotes: '' - GUID: e4e509 - Grid: true - GridProjection: false - Hands: false - HideWhenFaceDown: false - IgnoreFoW: false - LayoutGroupSortIndex: 0 - Locked: false - LuaScript: '' - LuaScriptState: '' - MeasureMovement: false - Name: Notecard - Nickname: Arkham SCE 3.3.0 - 10/9/2023 - Page 4 - Snap: true - Sticky: true - Tooltip: true - Transform: - posX: -26.88849 - posY: 1.551499 - posZ: -60.2882576 - rotX: 0 - rotY: 90 - rotZ: 0 - scaleX: 3 - scaleY: 1 - scaleZ: 3 - Value: 0 - XmlUI: '' - '5': - AltLookAngle: - x: 0 - y: 0 - z: 0 - Autoraise: true - ColorDiffuse: - b: 1 - g: 1 - r: 1 - Description: '- Fixed Token Arranger to be much less likely to "explode". - - - Resource spawning via hotkey on a card now auto-detects the right type of - resource to spawn. - - - Various bits of community content have been updated to their most recent Workshop - versions. - - - - Thank you everyone for continuing to report bugs and create content for the - mod!' - DragSelectable: true - GMNotes: '' - GUID: c0ef49 - Grid: true - GridProjection: false - Hands: false - HideWhenFaceDown: false - IgnoreFoW: false - LayoutGroupSortIndex: 0 - Locked: false - LuaScript: '' - LuaScriptState: '' - MeasureMovement: false - Name: Notecard - Nickname: Arkham SCE 3.3.0 - 10/9/2023 - Page 5 - Snap: true - Sticky: true - Tooltip: true - Transform: - posX: -25.7359982 - posY: 1.70084918 - posZ: -59.9714432 - rotX: 0 - rotY: 90 - rotZ: 0 - scaleX: 3 - scaleY: 1 - scaleZ: 3 - Value: 0 - XmlUI: '' -Sticky: true -Tooltip: true -Transform: - posX: -26.98 - posY: 1.55 - posZ: -56.16 - rotX: 0 - rotY: 90 - rotZ: 0 - scaleX: 3 - scaleY: 1 - scaleZ: 3 -Value: 0 -XmlUI: '' diff --git a/unpacked/Notecard Arkham SCE 3.4.0 - 11182023 - Page 1 964222.yaml b/unpacked/Notecard Arkham SCE 3.4.0 - 11182023 - Page 1 964222.yaml new file mode 100644 index 000000000..6604f9df5 --- /dev/null +++ b/unpacked/Notecard Arkham SCE 3.4.0 - 11182023 - Page 1 964222.yaml @@ -0,0 +1,89 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +ColorDiffuse: + b: 1 + g: 1 + r: 1 +Description: "Thanks for downloading Arkham SCE 3.4.0!\n\r\n- Revamped the download + menu! This is now the primary way to access custom content instead of the container + with placeholder boxes.\n- Added Parallel Jim and Parallel Zoey!\n- Added new community + content!\n- Added a helper for Subject 5U-21.\r\n- Added a tool to hide unused playermats.\n" +DragSelectable: true +GMNotes: '' +GUID: '964222' +Grid: true +GridProjection: false +Hands: false +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: false +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: Notecard +Nickname: Arkham SCE 3.4.0 - 11/18/2023 - Page 1 +Snap: true +States: + '2': + AltLookAngle: + x: 0 + y: 0 + z: 0 + Autoraise: true + ColorDiffuse: + b: 1 + g: 1 + r: 1 + Description: "- Added an image gallery for play area images.\n- Added QoL features + for Norman Withers\r.\n\r- Added a discard gamekey.\r\n- Increased readability + of master clue counter.\r\n- Cleaned up the option panel.\n- Added default camera + states (Shift + 1/2).\n- Fixed bugs with discarding cards from hand, the token + arranger, and taboo card widths.\r\n- Misc. metadata fixes." + DragSelectable: true + GMNotes: '' + GUID: d7faf7 + Grid: true + GridProjection: false + Hands: false + HideWhenFaceDown: false + IgnoreFoW: false + LayoutGroupSortIndex: 0 + Locked: false + LuaScript: '' + LuaScriptState: '' + MeasureMovement: false + Name: Notecard + Nickname: Arkham SCE 3.4.0 - 11/18/2023 - Page 2 + Snap: true + Sticky: true + Tooltip: true + Transform: + posX: -23.74739 + posY: 1.55149889 + posZ: -57.1334763 + rotX: 2.26350938e-08 + rotY: 90.00001 + rotZ: 2.55191921e-08 + scaleX: 3 + scaleY: 1 + scaleZ: 3 + Value: 0 + XmlUI: '' +Sticky: true +Tooltip: true +Transform: + posX: -27 + posY: 1.55 + posZ: -56.16 + rotX: 0 + rotY: 90 + rotZ: 0 + scaleX: 3 + scaleY: 1 + scaleZ: 3 +Value: 0 +XmlUI: '' diff --git a/unpacked/Checker_black Arkham Deck Cutter 445115.yaml b/unpacked/ScriptingTrigger TokenDiscardZone 457de3.yaml similarity index 52% rename from unpacked/Checker_black Arkham Deck Cutter 445115.yaml rename to unpacked/ScriptingTrigger TokenDiscardZone 457de3.yaml index 46b81daf7..b77650413 100644 --- a/unpacked/Checker_black Arkham Deck Cutter 445115.yaml +++ b/unpacked/ScriptingTrigger TokenDiscardZone 457de3.yaml @@ -4,13 +4,14 @@ AltLookAngle: z: 0 Autoraise: true ColorDiffuse: - b: 0 - g: 0 - r: 0 + a: 0.5098 + b: 1 + g: 1 + r: 1 Description: '' DragSelectable: true GMNotes: '' -GUID: '445115' +GUID: 457de3 Grid: true GridProjection: false Hands: false @@ -18,25 +19,23 @@ HideWhenFaceDown: false IgnoreFoW: false LayoutGroupSortIndex: 0 Locked: true -LuaScript: !include 'Checker_black Arkham Deck Cutter 445115.ttslua' +LuaScript: '' LuaScriptState: '' MeasureMovement: false -Name: Checker_black -Nickname: Arkham Deck Cutter +Name: ScriptingTrigger +Nickname: TokenDiscardZone Snap: true Sticky: true -Tags: -- arkham_setup_memory_object -Tooltip: true +Tooltip: false Transform: - posX: 78 - posY: 1.21 - posZ: 6.32 + posX: -65 + posY: 1.5 + posZ: 16.1 rotX: 0 - rotY: 270 - rotZ: 180 - scaleX: 0.25 - scaleY: 0.25 - scaleZ: 0.25 + rotY: 90 + rotZ: 0 + scaleX: 22 + scaleY: 0.5 + scaleZ: 5 Value: 0 XmlUI: '' diff --git a/unpacked/ScriptingTrigger TokenDiscardZone 457de4.yaml b/unpacked/ScriptingTrigger TokenDiscardZone 457de4.yaml new file mode 100644 index 000000000..955817fee --- /dev/null +++ b/unpacked/ScriptingTrigger TokenDiscardZone 457de4.yaml @@ -0,0 +1,41 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +ColorDiffuse: + a: 0.5098 + b: 1 + g: 1 + r: 1 +Description: '' +DragSelectable: true +GMNotes: '' +GUID: 457de4 +Grid: true +GridProjection: false +Hands: false +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: true +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: ScriptingTrigger +Nickname: TokenDiscardZone +Snap: true +Sticky: true +Tooltip: false +Transform: + posX: -65 + posY: 1.5 + posZ: -16.1 + rotX: 0 + rotY: 90 + rotZ: 0 + scaleX: 22 + scaleY: 0.5 + scaleZ: 5 +Value: 0 +XmlUI: '' diff --git a/unpacked/ScriptingTrigger TokenDiscardZone 457de5.yaml b/unpacked/ScriptingTrigger TokenDiscardZone 457de5.yaml new file mode 100644 index 000000000..3150d3034 --- /dev/null +++ b/unpacked/ScriptingTrigger TokenDiscardZone 457de5.yaml @@ -0,0 +1,41 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +ColorDiffuse: + a: 0.5098 + b: 1 + g: 1 + r: 1 +Description: '' +DragSelectable: true +GMNotes: '' +GUID: 457de5 +Grid: true +GridProjection: false +Hands: false +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: true +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: ScriptingTrigger +Nickname: TokenDiscardZone +Snap: true +Sticky: true +Tooltip: false +Transform: + posX: -30.35 + posY: 1.5 + posZ: 36.6 + rotX: 0 + rotY: 180 + rotZ: 0 + scaleX: 22 + scaleY: 0.5 + scaleZ: 5 +Value: 0 +XmlUI: '' diff --git a/unpacked/ScriptingTrigger TokenDiscardZone 457de6.yaml b/unpacked/ScriptingTrigger TokenDiscardZone 457de6.yaml new file mode 100644 index 000000000..a64a49a0c --- /dev/null +++ b/unpacked/ScriptingTrigger TokenDiscardZone 457de6.yaml @@ -0,0 +1,41 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +ColorDiffuse: + a: 0.5098 + b: 1 + g: 1 + r: 1 +Description: '' +DragSelectable: true +GMNotes: '' +GUID: 457de6 +Grid: true +GridProjection: false +Hands: false +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: true +LuaScript: '' +LuaScriptState: '' +MeasureMovement: false +Name: ScriptingTrigger +Nickname: TokenDiscardZone +Snap: true +Sticky: true +Tooltip: false +Transform: + posX: -30.35 + posY: 1.5 + posZ: -36.6 + rotX: 0 + rotY: 0 + rotZ: 0 + scaleX: 22 + scaleY: 0.5 + scaleZ: 5 +Value: 0 +XmlUI: '' diff --git a/unpacked/go_game_piece_black Navigation Overlay Handler 797ede.ttslua b/unpacked/go_game_piece_black Navigation Overlay Handler 797ede.ttslua index 9de1ce4b6..bca59e5a1 100644 --- a/unpacked/go_game_piece_black Navigation Overlay Handler 797ede.ttslua +++ b/unpacked/go_game_piece_black Navigation Overlay Handler 797ede.ttslua @@ -375,7 +375,7 @@ function loadCamera(player, index) end -- search on the playmat for objects - local bounds = getDynamicViewBounds(playmatApi.searchPlaymat(matColor)) + local bounds = getDynamicViewBounds(playmatApi.searchAroundPlaymat(matColor)) lookHere = { position = { bounds.middleX, 0, bounds.middleZ }, @@ -455,229 +455,263 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi 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) return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/go_game_piece_white GUID Reference Handler 123456.ttslua b/unpacked/go_game_piece_white GUID Reference Handler 123456.ttslua new file mode 100644 index 000000000..410b2da4c --- /dev/null +++ b/unpacked/go_game_piece_white GUID Reference Handler 123456.ttslua @@ -0,0 +1,154 @@ +-- 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("core/GUIDReferenceHandler") +end) +__bundle_register("core/GUIDReferenceHandler", function(require, _LOADED, __bundle_register, __bundle_modules) +local GuidReferences = { + White = { + ClueCounter = "d86b7c", + ClickableClueCounter = "db85d6", + DamageCounter = "eb08d6", + HandZone = "a70eee", + HorrorCounter = "468e88", + InvestigatorSkillTracker = "e598c2", + Playermat = "8b081b", + ResourceCounter = "4406f0", + TokenDiscardZone = "457de3", + Trash = "147e80" + }, + Orange = { + ClueCounter = "1769ed", + ClickableClueCounter = "3f22e5", + DamageCounter = "e64eec", + HandZone = "5fe087", + HorrorCounter = "0257d9", + InvestigatorSkillTracker = "b4a5f7", + Playermat = "bd0ff4", + ResourceCounter = "816d84", + TokenDiscardZone = "457de4", + Trash = "f7b6c8" + }, + Green = { + ClueCounter = "032300", + ClickableClueCounter = "891403", + DamageCounter = "1f5a0a", + HandZone = "0285cc", + HorrorCounter = "7b5729", + InvestigatorSkillTracker = "af7ed7", + Playermat = "383d8b", + ResourceCounter = "cd15ac", + TokenDiscardZone = "457de5", + Trash = "5f896a" + }, + Red = { + ClueCounter = "37be78", + ClickableClueCounter = "4111de", + DamageCounter = "591a45", + HandZone = "be2f17", + HorrorCounter = "beb964", + InvestigatorSkillTracker = "e74881", + Playermat = "0840d5", + ResourceCounter = "a4b60d", + TokenDiscardZone = "457de6", + Trash = "4b8594" + }, + Mythos = { + AllCardsBag = "15bb07", + BlessCurseManager = "5933fb", + CampaignThePathToCarcosa = "aca04c", + DataHelper = "708279", + DeckImporter = "a28140", + DoomCounter = "85c4c6", + DoomInPlayCounter = "652ff3", + InvestigatorCounter = "f182ee", + MasterClueCounter = "4a3aa4", + MythosArea = "9f334f", + NavigationOverlayHandler = "797ede", + OptionPanelSource = "830bd0", + PlaceholderBoxDummy = "a93466", + PlayArea = "721ba2", + PlayAreaZone = "a2f932", + PlayerCardPanel = "2d30ee", + ResourceTokenBag = "9fadf9", + RulesReference = "d99993", + SoundCube = "3c988f", + TokenArranger = "022907", + TokenSource = "124381", + TokenSpawnTracker = "e3ffc9", + TourStarter = "0e5aa8", + Trash = "70b9f6", + VictoryDisplay = "6ccd6d" + } +} + +function getObjectByOwnerAndType(params) + local owner = params.owner or "Mythos" + local type = params.type + return getObjectFromGUID(GuidReferences[owner][type]) +end + +function getObjectsByType(type) + local objList = {} + for owner, objects in pairs(GuidReferences) do + local obj = getObjectFromGUID(objects[type]) + if obj then + objList[owner] = obj + end + end + return objList +end + +function getObjectsByOwner(owner) + local objList = {} + for type, guid in pairs(GuidReferences[owner]) do + local obj = getObjectFromGUID(guid) + if obj then + objList[type] = obj + end + end + return objList +end +end) +return __bundle_require("__root") \ No newline at end of file diff --git a/unpacked/go_game_piece_white GUID Reference Handler 123456.yaml b/unpacked/go_game_piece_white GUID Reference Handler 123456.yaml new file mode 100644 index 000000000..5e514fdb4 --- /dev/null +++ b/unpacked/go_game_piece_white GUID Reference Handler 123456.yaml @@ -0,0 +1,40 @@ +AltLookAngle: + x: 0 + y: 0 + z: 0 +Autoraise: true +ColorDiffuse: + b: 0.116 + g: 0.116 + r: 0.716 +Description: This object handles GUID references to objects. +DragSelectable: true +GMNotes: '' +GUID: '123456' +Grid: true +GridProjection: false +Hands: false +HideWhenFaceDown: false +IgnoreFoW: false +LayoutGroupSortIndex: 0 +Locked: true +LuaScript: !include 'go_game_piece_white GUID Reference Handler 123456.ttslua' +LuaScriptState: '' +MeasureMovement: false +Name: go_game_piece_white +Nickname: GUID Reference Handler +Snap: true +Sticky: true +Tooltip: true +Transform: + posX: 78 + posY: 1.33 + posZ: -8 + rotX: 0 + rotY: 0 + rotZ: 0 + scaleX: 1 + scaleY: 1 + scaleZ: 1 +Value: 0 +XmlUI: '' diff --git a/unpacked/go_game_piece_white Game Key Handler fce69c.ttslua b/unpacked/go_game_piece_white Game Key Handler fce69c.ttslua index 6cfafbd3c..e14b1dda4 100644 --- a/unpacked/go_game_piece_white Game Key Handler fce69c.ttslua +++ b/unpacked/go_game_piece_white Game Key Handler fce69c.ttslua @@ -41,6 +41,84 @@ local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = ( return require, loaded, register, modules end)(nil) +__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) +do + local BlessCurseManagerApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getManager() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager") + end + + -- removes all taken tokens and resets the counts + BlessCurseManagerApi.removeTakenTokensAndReset = function() + local BlessCurseManager = getManager() + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) + Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) + Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.sealedToken = function(type, guid) + getManager().call("sealedToken", { type = type, guid = guid }) + end + + -- updates the internal count (called by cards that seal bless/curse tokens) + BlessCurseManagerApi.releasedToken = function(type, guid) + getManager().call("releasedToken", { type = type, guid = guid }) + end + + -- broadcasts the current status for bless/curse tokens + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.broadcastStatus = function(playerColor) + getManager().call("broadcastStatus", playerColor) + end + + -- removes all bless / curse tokens from the chaos bag and play + ---@param playerColor String Color of the player to show the broadcast to + BlessCurseManagerApi.removeAll = function(playerColor) + getManager().call("doRemove", playerColor) + end + + -- adds Wendy's menu to the hovered card (allows sealing of tokens) + ---@param color String Color of the player to show the broadcast to + BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) + getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) + end + + return BlessCurseManagerApi +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) __bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local OptionPanelApi = {} @@ -62,19 +140,23 @@ end) __bundle_register("core/VictoryDisplayApi", function(require, _LOADED, __bundle_register, __bundle_modules) do local VictoryDisplayApi = {} - local VD_GUID = "6ccd6d" + local guidReferenceApi = require("core/GUIDReferenceApi") + + local function getVictoryDisplay() + return guidReferenceApi.getObjectByOwnerAndType("Mythos", "VictoryDisplay") + end -- triggers an update of the Victory count ---@param delay Number Delay in seconds after which the update call is executed VictoryDisplayApi.update = function(delay) - getObjectFromGUID(VD_GUID).call("startUpdate", delay) + getVictoryDisplay().call("startUpdate", delay) end -- moves a card to the victory display (in the first empty spot) ---@param object Object Object that should be checked and potentially moved VictoryDisplayApi.placeCard = function(object) if object ~= nil and object.tag == "Card" then - getObjectFromGUID(VD_GUID).call("placeCard", object) + getVictoryDisplay().call("placeCard", object) end end @@ -83,228 +165,232 @@ end end) __bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules) do - local PlaymatApi = { } - local internal = { } + local PlaymatApi = {} + local guidReferenceApi = require("core/GUIDReferenceApi") - local MAT_IDS = { - White = "8b081b", - Orange = "bd0ff4", - Green = "383d8b", - Red = "0840d5" - } - - local CLUE_COUNTER_GUIDS = { - White = "37be78", - Orange = "1769ed", - Green = "032300", - Red = "d86b7c" - } - - local CLUE_CLICKER_GUIDS = { - White = "db85d6", - Orange = "3f22e5", - Green = "891403", - Red = "4111de" - } - - -- Returns the color of the by position requested playermat as string - ---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat - PlaymatApi.getMatColorByPosition = function(startPos) - if startPos.x < -42 then - if startPos.z > 0 then - return "White" - else - return "Orange" - end + -- Convenience function to look up a mat's object by color, or get all mats. + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@return array Table Single-element if only single playmat is requested + local function getMatForColor(matColor) + if matColor == "All" then + return guidReferenceApi.getObjectsByType("Playermat") else - if startPos.z > 0 then - return "Green" - else - return "Red" + return { matColor = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") } + end + end + + -- Returns the color of the closest playmat + ---@param startPos Table Starting position to get the closest mat from + PlaymatApi.getMatColorByPosition = function(startPos) + local result, smallestDistance + for matColor, mat in pairs(getMatForColor("All")) do + local distance = Vector.between(startPos, mat.getPosition()):magnitude() + if smallestDistance == nil or distance < smallestDistance then + smallestDistance = distance + result = matColor + end + end + return result + end + + -- Returns the color of the player's hand that is seated next to the playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getPlayerColor = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("playerColor") + end + end + + -- Returns the color of the playmat that owns the playercolor's hand + ---@param handColor String Color of the playmat + PlaymatApi.getMatColor = function(handColor) + for matColor, mat in pairs(getMatForColor("All")) do + local playerColor = mat.getVar("playerColor") + if playerColor == handColor then + return matColor end end end - -- Returns the color of the player's hand that is seated next to the playermat - ---@param matColor String Color of the playermat - PlaymatApi.getPlayerColor = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("playerColor") - end - - -- Returns the color of the playermat that owns the playercolor's hand - ---@param handColor String Color of the playermat - PlaymatApi.getMatColor = function(handColor) - local matColors = {"White", "Orange", "Green", "Red"} - for i, mat in ipairs(internal.getMatForColor("All")) do - local color = mat.getVar("playerColor") - if color == handColor then return matColors[i] end - end - return "NOT_FOUND" - end - - -- Returns the result of a cast in the specificed playermat's area - ---@param matColor String Color of the playermat - PlaymatApi.searchPlaymat = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("searchAroundSelf") - end - - -- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat - ---@param matColor String Color of the playermat + -- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.isDES = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("isDES") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("isDES") + end end - -- Returns the draw deck of the requested playmat - ---@param matColor String Color of the playermat - PlaymatApi.getDrawDeck = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + -- Performs a search of the deck area of the requested playmat and returns the result as table + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.getDeckAreaObjects = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") + end end -- Returns the position of the discard pile of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.getDiscardPosition = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("returnGlobalDiscardPosition") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("returnGlobalDiscardPosition") + end end -- Transforms a local position into a global position ---@param localPos Table Local position to be transformed - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.transformLocalPosition = function(localPos, matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.positionToWorld(localPos) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.positionToWorld(localPos) + end end -- Returns the rotation of the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnRotation = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getRotation() + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getRotation() + end end -- Triggers the Upkeep for the requested playmat - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All ---@param playerColor String Color of the calling player (for messages) PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("doUpkeepFromHotkey", playerColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("doUpkeepFromHotkey", playerColor) + end + end + + -- Handles discarding for the requested playmat for the provided list of objects + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param objList Table List of objects to discard + PlaymatApi.discardListOfObjects = function(matColor, objList) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("discardListOfObjects", objList) + end end -- Returns the active investigator id - ---@param matColor String Color of the playermat + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") PlaymatApi.returnInvestigatorId = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.getVar("activeInvestigatorId") + for _, mat in pairs(getMatForColor(matColor)) do + return mat.getVar("activeInvestigatorId") + end end - -- Sets the requested playermat's snap points to limit snapping to matching card types or not. If + -- Sets the requested playmat's snap points to limit snapping to matching card types or not. If -- matchTypes is true, the main card slot snap points will only snap assets, while the -- investigator area point will only snap Investigators. If matchTypes is false, snap points will -- be reset to snap all cards. - ---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card - -- types. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + ---@param matchCardTypes Boolean Whether snap points should only snap for the matching card types + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("setLimitSnapsByType", matchCardTypes) end end - -- Sets the requested playermat's draw 1 button to visible - ---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Sets the requested playmat's draw 1 button to visible + ---@param isDrawButtonVisible Boolean Whether the draw 1 button should be visible or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("showDrawButton", isDrawButtonVisible) end end - -- Shows or hides the clickable clue counter for the requested playermat - ---@param showCounter Boolean. Whether the clickable counter should be present or not - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Shows or hides the clickable clue counter for the requested playmat + ---@param showCounter Boolean Whether the clickable counter should be present or not + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.clickableClues = function(showCounter, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("clickableClues", showCounter) end end - -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will apply the setting to all four mats. + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.removeClues = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("removeClues") end end - -- Reports the clue count for the requested playermat + -- Reports the clue count for the requested playmat ---@param useClickableCounters Boolean Controls which type of counter is getting checked PlaymatApi.getClueCount = function(useClickableCounters, matColor) local count = 0 - for _, mat in ipairs(internal.getMatForColor(matColor)) do - count = count + tonumber(mat.call("getClueCount", useClickableCounters)) + for _, mat in pairs(getMatForColor(matColor)) do + count = count + mat.call("getClueCount", useClickableCounters) end return count end - -- Adds the specified amount of resources to the requested playermat's resource counter - PlaymatApi.gainResources = function(amount, matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do - mat.call("gainResources", amount) + -- updates the specified owned counter + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param type String Counter to target + ---@param newValue Number Value to set the counter to + ---@param modifier Number If newValue is not provided, the existing value will be adjusted by this modifier + PlaymatApi.updateCounter = function(matColor, type, newValue, modifier) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier }) end end - -- Returns the resource counter amount for the requested playermat - PlaymatApi.getResourceCount = function(matColor) - local mat = getObjectFromGUID(MAT_IDS[matColor]) - return mat.call("getResourceCount") + -- returns the resource counter amount + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + ---@param type String Counter to target + PlaymatApi.getCounterValue = function(matColor, type) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("getCounterValue", type) + end + end + + -- resets the specified skill tracker to "1, 1, 1, 1" + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + PlaymatApi.resetSkillTracker = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("resetSkillTracker") + end + end + + -- finds all objects on the playmat and associated set aside zone and returns a table + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All + ---@param filter Function Optional filter function (return true for desired objects) + PlaymatApi.searchAroundPlaymat = function(matColor, filter) + local objList = {} + for _, mat in pairs(getMatForColor(matColor)) do + for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do + table.insert(objList, obj) + end + end + return objList end -- Discard a non-hidden card from the corresponding player's hand + ---@param matColor String Color of the playmat - White, Orange, Green, Red or All PlaymatApi.doDiscardOne = function(matColor) - for _, mat in ipairs(internal.getMatForColor(matColor)) do + for _, mat in pairs(getMatForColor(matColor)) do mat.call("doDiscardOne") end end + -- Triggers the metadata sync for all playmats PlaymatApi.syncAllCustomizableCards = function() - for _, mat in ipairs(internal.getMatForColor("All")) do + for _, mat in pairs(getMatForColor("All")) do mat.call("syncAllCustomizableCards") end end - PlaymatApi.updateClueClicker = function(playerColor, val) - return getObjectFromGUID(CLUE_CLICKER_GUIDS[playerColor]).call("updateVal", val) - end - - -- Convenience function to look up a mat's object by color, or get all mats. - ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also - -- accepts "All" as a special value which will return all four mats. - ---@return: Array of playermat objects. If a single mat is requested, will return a single-element - -- array to simplify processing by consumers. - internal.getMatForColor = function(matColor) - local targetMatGuid = MAT_IDS[matColor] - if targetMatGuid != nil then - return { getObjectFromGUID(targetMatGuid) } - end - if matColor == "All" then - return { - getObjectFromGUID(MAT_IDS.White), - getObjectFromGUID(MAT_IDS.Orange), - getObjectFromGUID(MAT_IDS.Green), - getObjectFromGUID(MAT_IDS.Red), - } - end - end - return PlaymatApi end end) @@ -313,6 +399,7 @@ require("core/GameKeyHandler") end) __bundle_register("core/GameKeyHandler", function(require, _LOADED, __bundle_register, __bundle_modules) local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi") +local guidReferenceApi = require("core/GUIDReferenceApi") local optionPanelApi = require("core/OptionPanelApi") local playmatApi = require("playermat/PlaymatApi") local victoryDisplayApi = require("core/VictoryDisplayApi") @@ -320,7 +407,9 @@ local victoryDisplayApi = require("core/VictoryDisplayApi") function onLoad() addHotkey("Add Doom to Agenda", addDoomToAgenda) addHotkey("Bless/Curse Status", showBlessCurseStatus) + addHotkey("Discard Object", discardObject) addHotkey("Move card to Victory Display", moveCardToVictoryDisplay) + addHotkey("Remove a use", removeOneUse) addHotkey("Take clue from location", takeClueFromLocation) addHotkey("Upkeep", triggerUpkeep) addHotkey("Upkeep (Multi-handed)", triggerUpkeepMultihanded) @@ -355,7 +444,65 @@ end -- adds 1 doom to the agenda function addDoomToAgenda() - getObjectFromGUID("85c4c6").call("addVal", 1) + local doomCounter = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DoomCounter") + doomCounter.call("addVal", 1) +end + +-- discard the hovered object to the respective trashcan and discard tokens on it if it was a card +function discardObject(playerColor, hoveredObject) + -- only continue if an unlocked card, deck or tile was hovered + if hoveredObject == nil + or (hoveredObject.type ~= "Card" and hoveredObject.type ~= "Deck" and hoveredObject.type ~= "Tile") + or hoveredObject.locked then + broadcastToColor("Hover a token/tile or a card/deck and try again.", playerColor, "Yellow") + return + end + + -- warning for locations since these are usually not meant to be discarded + if hoveredObject.hasTag("Location") then + broadcastToAll("Watch out: A location was discarded.", "Yellow") + end + + -- initialize list of objects to discard + local discardTheseObjects = { hoveredObject } + + -- discard tokens / tiles on cards / decks + if hoveredObject.type ~= "Tile" then + for _, v in ipairs(searchOnObj(hoveredObject)) do + if v.hit_object.type == "Tile" then + table.insert(discardTheseObjects, v.hit_object) + end + end + end + + local discardForMatColor = getColorToDiscardFor(hoveredObject, playerColor) + playmatApi.discardListOfObjects(discardForMatColor, discardTheseObjects) +end + +-- helper function to get the player to trigger the discard function for +function getColorToDiscardFor(hoveredObject, playerColor) + local pos = hoveredObject.getPosition() + local closestMatColor = playmatApi.getMatColorByPosition(pos) + + -- check if actually on the closest playmat + local closestMat = guidReferenceApi.getObjectByOwnerAndType(closestMatColor, "Playermat") + local bounds = closestMat.getBounds() + + -- define the area "near" the playmat + local bufferAroundPlaymat = 2 + local areaNearPlaymat = {} + areaNearPlaymat.minX = bounds.center.x - bounds.size.x / 2 - bufferAroundPlaymat + areaNearPlaymat.maxX = bounds.center.x + bounds.size.x / 2 + bufferAroundPlaymat + areaNearPlaymat.minZ = bounds.center.z - bounds.size.z / 2 - bufferAroundPlaymat + areaNearPlaymat.maxZ = bounds.center.z + bounds.size.z / 2 + bufferAroundPlaymat + + -- discard to closest mat if near it, use triggering playmat if not + local discardForMatColor + if inArea(pos, areaNearPlaymat) then + return closestMatColor + else + return playmatApi.getMatColor(playerColor) + end end -- moves the hovered card to the victory display @@ -363,6 +510,80 @@ function moveCardToVictoryDisplay(_, hoveredObject) victoryDisplayApi.placeCard(hoveredObject) end +-- removes a use from a card (or a token if hovered) +function removeOneUse(playerColor, hoveredObject) + -- only continue if an unlocked card or tile was hovered + if hoveredObject == nil + or (hoveredObject.type ~= "Card" and hoveredObject.type ~= "Tile") + or hoveredObject.locked then + broadcastToColor("Hover a token/tile or a card and try again.", playerColor, "Yellow") + return + end + + local targetObject = nil + + -- discard hovered token / tile + if hoveredObject.type == "Tile" then + targetObject = hoveredObject + elseif hoveredObject.type == "Card" then + -- grab the first use type from the metadata (or nil) + local notes = JSON.decode(hoveredObject.getGMNotes()) or {} + local usesData = notes.uses or {} + local useInfo = usesData[1] or {} + local searchForType = useInfo.type + if searchForType then searchForType = searchForType:lower() end + + for _, v in ipairs(searchOnObj(hoveredObject)) do + local obj = v.hit_object + if obj.type == "Tile" and not obj.locked and obj.memo ~= "resourceCounter" then + -- check for matching object, otherwise use the first hit + if obj.memo == searchForType then + targetObject = obj + break + elseif not targetObject then + targetObject = obj + end + end + end + end + + -- error handling + if not targetObject then + broadcastToColor("No tokens found!", playerColor, "Yellow") + return + end + + -- handling for stacked tokens + if targetObject.getQuantity() > 1 then + targetObject = targetObject.takeObject() + end + + -- feedback message + local tokenName = targetObject.getName() + if tokenName == "" then + if targetObject.memo ~= "" then + -- name handling for clue / doom + if targetObject.memo == "clueDoom" then + if targetObject.is_face_down then + tokenName = "Doom" + else + tokenName = "Clue" + end + else + tokenName = titleCase(targetObject.memo) + end + else + tokenName = "Unknown" + end + end + + local playerName = Player[playerColor].steam_name + broadcastToAll(playerName .. " removed a token: " .. tokenName, playerColor) + + local discardForMatColor = getColorToDiscardFor(hoveredObject, playerColor) + playmatApi.discardListOfObjects(discardForMatColor, { targetObject }) +end + -- takes a clue from a location, player needs to hover the clue directly or the location function takeClueFromLocation(playerColor, hoveredObject) local cardName, clue @@ -370,7 +591,7 @@ function takeClueFromLocation(playerColor, hoveredObject) if hoveredObject == nil then broadcastToColor("Hover a clue or card with clues and try again.", playerColor, "Yellow") return - elseif hoveredObject.tag == "Card" then + elseif hoveredObject.type == "Card" then cardName = hoveredObject.getName() for _, v in ipairs(searchOnObj(hoveredObject)) do @@ -403,7 +624,7 @@ function takeClueFromLocation(playerColor, hoveredObject) for _, v in ipairs(search) do local obj = v.hit_object - if obj.tag == "Card" then + if obj.type == "Card" then cardName = obj.getName() break end @@ -419,7 +640,7 @@ function takeClueFromLocation(playerColor, hoveredObject) local pos = nil if clickableClues then pos = {x = 0.49, y = 2.66, z = 0.00} - playmatApi.updateClueClicker(playerColor, playmatApi.getClueCount(clickableClues, playerColor) + 1) + playmatApi.updateCounter(matColor, "ClickableClueCounter", _, 1) else pos = playmatApi.transformLocalPosition({x = -1.12, y = 0.05, z = 0.7}, matColor) end @@ -464,49 +685,22 @@ function searchOnObj(obj) origin = obj.getPosition() }) end -end) -__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules) -do - local BlessCurseManagerApi = {} - local MANAGER_GUID = "5933fb" - -- removes all taken tokens and resets the counts - BlessCurseManagerApi.removeTakenTokensAndReset = function() - local BlessCurseManager = getObjectFromGUID(MANAGER_GUID) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05) - Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10) - Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15) - end +-- Simple method to check if the given point is in a specified area +---@param point Vector Point to check, only x and z values are relevant +---@param bounds Table Defined area to see if the point is within +function inArea(point, bounds) + return (point.x > bounds.minX + and point.x < bounds.maxX + and point.z > bounds.minZ + and point.z < bounds.maxZ) +end - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.sealedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid }) - end - - -- updates the internal count (called by cards that seal bless/curse tokens) - BlessCurseManagerApi.releasedToken = function(type, guid) - getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid }) - end - - -- broadcasts the current status for bless/curse tokens - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.broadcastStatus = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("broadcastStatus", playerColor) - end - - -- removes all bless / curse tokens from the chaos bag and play - ---@param playerColor String Color of the player to show the broadcast to - BlessCurseManagerApi.removeAll = function(playerColor) - getObjectFromGUID(MANAGER_GUID).call("doRemove", playerColor) - end - - -- adds Wendy's menu to the hovered card (allows sealing of tokens) - ---@param color String Color of the player to show the broadcast to - BlessCurseManagerApi.addWendysMenu = function(playerColor, hoveredObject) - getObjectFromGUID(MANAGER_GUID).call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject }) - end - - return BlessCurseManagerApi +-- capitalizes the first letter +function titleCase(str) + local first = str:sub(1, 1) + local rest = str:sub(2) + return first:upper() .. rest:lower() end end) return __bundle_require("__root") \ No newline at end of file