From aef8865bbbce319a0e26ae5d76d09472298849ae Mon Sep 17 00:00:00 2001 From: Buhallin Date: Fri, 11 Nov 2022 10:49:25 -0800 Subject: [PATCH] Re-extract config.json to get correctly bundled LuaScript --- config.json | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/config.json b/config.json index c899591d..803884ba 100644 --- a/config.json +++ b/config.json @@ -2,7 +2,6 @@ "CameraStates_path": "CameraStates.json", "ComponentTags_path": "ComponentTags.json", "CustomUIAssets_path": "CustomUIAssets.json", - "Date": "11/10/2022 11:58:28 PM", "DecalPallet": [ { "ImageURL": "http://cloud-3.steamusercontent.com/ugc/1474319121424323663/BC5570ECF747F1B30224461B576E8B0FE7FA5F33/", @@ -11,7 +10,6 @@ } ], "Decals_path": "Decals.json", - "EpochTime": 1668153508, "GameComplexity": "", "GameMode": "Arkham Horror LCG - Super Complete Edition", "GameType": "", @@ -23,7 +21,7 @@ "Hiding": 0 }, "Lighting_path": "Lighting.json", - "LuaScript": "-- Bundled by luabundle {\"version\":\"1.6.0\"}\nlocal __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)\n\tlocal loadingPlaceholder = {[{}] = true}\n\n\tlocal register\n\tlocal modules = {}\n\n\tlocal require\n\tlocal loaded = {}\n\n\tregister = function(name, body)\n\t\tif not modules[name] then\n\t\t\tmodules[name] = body\n\t\tend\n\tend\n\n\trequire = function(name)\n\t\tlocal loadedModule = loaded[name]\n\n\t\tif loadedModule then\n\t\t\tif loadedModule == loadingPlaceholder then\n\t\t\t\treturn nil\n\t\t\tend\n\t\telse\n\t\t\tif not modules[name] then\n\t\t\t\tif not superRequire then\n\t\t\t\t\tlocal identifier = type(name) == 'string' and '\\\"' .. name .. '\\\"' or tostring(name)\n\t\t\t\t\terror('Tried 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(\"core/Global\")\nend)\n__bundle_register(\"core/Global\", function(require, _LOADED, __bundle_register, __bundle_modules)\n--[[ Lua code. See documentation: http://berserk-games.com/knowledgebase/scripting/ --]]\r\n-- Card size used for autodealing --\r\n\r\n-- global position constants\r\nENCOUNTER_DECK_POS = {-3.8, 1, 5.7}\r\nENCOUNTER_DECK_SPAWN_POS = {-3.8, 3, 5.7}\r\nENCOUNTER_DECK_DISCARD_POSITION = {-3.8, 0.5, 10.5}\r\ng_cardWith=2.30;\r\ng_cardHeigth=3.40;\r\n\r\ncontainerId = 'fea079'\r\ntokenDataId = '708279'\r\n\r\n\r\nmaxSquid = 0\r\n\r\nCACHE = {\r\n object = {},\r\n data = {}\r\n}\r\n\r\n--[[ The OnLoad function. This is called after everything in the game save finishes loading.\r\nMost of your script code goes here. --]]\r\nfunction onload()\r\n --Player.White.changeColor('Yellow')\r\n tokenplayerone = {\r\n damageone = \"http://cloud-3.steamusercontent.com/ugc/1758068501357115146/903D11AAE7BD5C254C8DC136E9202EE516289DEA/\",\r\n damagethree = \"http://cloud-3.steamusercontent.com/ugc/1758068501357113055/8A45F27B2838FED09DEFE492C9C40DD82781613A/\",\r\n horrorone = \"http://cloud-3.steamusercontent.com/ugc/1758068501357163535/6D9E0756503664D65BDB384656AC6D4BD713F5FC/\",\r\n horrorthree = \"http://cloud-3.steamusercontent.com/ugc/1758068501357162977/E5D453CC14394519E004B4F8703FC425A7AE3D6C/\",\r\n resource = \"http://cloud-3.steamusercontent.com/ugc/1758068501357192910/11DDDC7EF621320962FDCF3AE3211D5EDC3D1573/\",\r\n resourcethree = \"https://i.imgur.com/1GZsDTt.png\",\r\n doom = \"https://i.imgur.com/EoL7yaZ.png\",\r\n clue = \"http://cloud-3.steamusercontent.com/ugc/1758068501357164917/1D06F1DC4D6888B6F57124BD2AFE20D0B0DA15A8/\"\r\n }\r\n\r\n TOKEN_DATA = {\r\n clue = {image = tokenplayerone.clue, scale = {0.15, 0.15, 0.15}},\r\n resource = {image = tokenplayerone.resource, scale = {0.17, 0.17, 0.17}},\r\n doom = {image = tokenplayerone.doom, scale = {0.17, 0.17, 0.17}},\r\n damage = {image = tokenplayerone.damageone, scale = {0.17, 0.17, 0.17}},\r\n horror = {image = tokenplayerone.horrorone, scale = {0.17, 0.17, 0.17}}\r\n }\r\n\r\n getObjectFromGUID(\"6161b4\").interactable=false\r\n getObjectFromGUID(\"721ba2\").interactable=false\r\n getObjectFromGUID(\"9f334f\").interactable=false\r\n getObjectFromGUID(\"23a43c\").interactable=false\r\n getObjectFromGUID(\"5450cc\").interactable=false\r\n getObjectFromGUID(\"463022\").interactable=false\r\n getObjectFromGUID(\"9487a4\").interactable=false\r\n getObjectFromGUID(\"91dd9b\").interactable=false\r\n getObjectFromGUID(\"f182ee\").interactable=false\r\n getObjectFromGUID(\"7bff34\").interactable=false\r\n\r\nend\r\n\r\nfunction onObjectDrop(player, obj)\r\n-- local mat = getObjectFromGUID(\"dsbd0ff4\")\r\n-- log(mat.positionToLocal(obj.getPosition()))\r\nend\r\n\r\nfunction take_callback(object_spawned, mat)\r\n customObject = object_spawned.getCustomObject()\r\n local player = mat.getGUID();\r\n\r\n local image = customObject.image\r\n\r\n -- Update global stats\r\n if PULLS[image] == nil then\r\n PULLS[image] = 0\r\n end\r\n PULLS[image] = PULLS[image] + 1\r\n -- Update player stats\r\n if PLAYER_PULLS[player][image] == nil then\r\n PLAYER_PULLS[player][image] = 0\r\n end\r\n PLAYER_PULLS[player][image] = PLAYER_PULLS[player][image] + 1\r\n\r\nend\r\nMAT_GUID_TO_COLOUR = {\r\n [\"8b081b\"] = \"White\",\r\n -- player 2 conrad\r\n [\"bd0ff4\"] = \"Orange\",\r\n -- player\r\n [\"383d8b\"] = \"Green\",\r\n -- playur 4 olivia\r\n [\"0840d5\"] = \"Red\"\r\n}\r\n\r\n\r\nPLAYER_PULLS = {\r\n -- player 1 max\r\n [\"8b081b\"] = {},\r\n -- player 2 conrad\r\n [\"bd0ff4\"] = {},\r\n -- player\r\n [\"383d8b\"] = {},\r\n -- playur 4 olivia\r\n [\"0840d5\"] = {}\r\n}\r\n\r\nPULLS = {\r\n -- cultist\r\n [\"https://i.imgur.com/VzhJJaH.png\"] = 0,\r\n -- skull\r\n [\"https://i.imgur.com/stbBxtx.png\"] = 0,\r\n -- tablet\r\n [\"https://i.imgur.com/1plY463.png\"] = 0,\r\n -- curse\r\n [\"http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/\"] = 0,\r\n -- tentacle\r\n [\"https://i.imgur.com/lns4fhz.png\"] = 0,\r\n -- minus eight\r\n [\"https://i.imgur.com/9t3rPTQ.png\"] = 0,\r\n -- minus seven\r\n [\"https://i.imgur.com/4WRD42n.png\"] = 0,\r\n -- minus six\r\n [\"https://i.imgur.com/c9qdSzS.png\"] = 0,\r\n -- minus five\r\n [\"https://i.imgur.com/3Ym1IeG.png\"] = 0,\r\n -- minus four\r\n [\"https://i.imgur.com/qrgGQRD.png\"] = 0,\r\n -- minus three\r\n [\"https://i.imgur.com/yfs8gHq.png\"] = 0,\r\n -- minus two\r\n [\"https://i.imgur.com/bfTg2hb.png\"] = 0,\r\n -- minus one\r\n [\"https://i.imgur.com/w3XbrCC.png\"] = 0,\r\n -- zero\r\n [\"https://i.imgur.com/btEtVfd.png\"] = 0,\r\n -- plus one\r\n [\"https://i.imgur.com/uIx8jbY.png\"] = 0,\r\n -- elder thing\r\n [\"https://i.imgur.com/ttnspKt.png\"] = 0,\r\n -- bless\r\n [\"http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/\"] = 0,\r\n -- elder sign\r\n [\"https://i.imgur.com/nEmqjmj.png\"] = 0,\r\n -- frost\r\n [\"http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/\"] = 0,\r\n}\r\n\r\nIMAGE_TOKEN_MAP = {\r\n -- elder sign\r\n [\"https://i.imgur.com/nEmqjmj.png\"] = \"Elder Sign\",\r\n -- plus one\r\n [\"https://i.imgur.com/uIx8jbY.png\"] = \"+1\",\r\n -- zero\r\n [\"https://i.imgur.com/btEtVfd.png\"] = \"0\",\r\n -- minus one\r\n [\"https://i.imgur.com/w3XbrCC.png\"] = \"-1\",\r\n -- minus two\r\n [\"https://i.imgur.com/bfTg2hb.png\"] = \"-2\",\r\n -- minus three\r\n [\"https://i.imgur.com/yfs8gHq.png\"] = \"-3\",\r\n -- minus four\r\n [\"https://i.imgur.com/qrgGQRD.png\"] = \"-4\",\r\n -- minus five\r\n [\"https://i.imgur.com/3Ym1IeG.png\"] = \"-5\",\r\n -- minus six\r\n [\"https://i.imgur.com/c9qdSzS.png\"] = \"-6\",\r\n -- minus seven\r\n [\"https://i.imgur.com/4WRD42n.png\"] = \"-7\",\r\n -- minus eight\r\n [\"https://i.imgur.com/9t3rPTQ.png\"] = \"-8\",\r\n -- skull\r\n [\"https://i.imgur.com/stbBxtx.png\"] = \"Skull\",\r\n -- cultist\r\n [\"https://i.imgur.com/VzhJJaH.png\"] = \"Cultist\",\r\n -- tablet\r\n [\"https://i.imgur.com/1plY463.png\"] = \"Tablet\",\r\n -- elder thing\r\n [\"https://i.imgur.com/ttnspKt.png\"] = \"Elder Thing\",\r\n -- tentacle\r\n [\"https://i.imgur.com/lns4fhz.png\"] = \"Auto-fail\",\r\n -- bless\r\n [\"http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/\"] = \"Bless\",\r\n -- curse\r\n [\"http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/\"] = \"Curse\",\r\n\t-- frost\r\n\t[\"http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/\"] = \"Frost\"\r\n}\r\n\r\nfunction resetStats()\r\n for key,value in pairs(PULLS) do\r\n PULLS[key] = 0\r\n end\r\n for playerKey, playerValue in pairs(PLAYER_PULLS) do\r\n for key,value in pairs(PULLS) do\r\n PLAYER_PULLS[playerKey][key] = value\r\n end\r\n end\r\n\r\n\r\nend\r\n\r\nfunction getPlayerName(playerMatGuid)\r\n local playerColour = MAT_GUID_TO_COLOUR[playerMatGuid]\r\n if Player[playerColour].seated then\r\n return Player[playerColour].steam_name\r\n else\r\n return playerColour\r\n end\r\nend\r\n\r\nfunction printStats()\r\n local squidKing = \"Nobody\"\r\n\r\n\r\n printToAll(\"\\nOverall Game stats\\n\")\r\n printNonZeroTokenPairs(PULLS)\r\n printToAll(\"\\nIndividual Stats\\n\")\r\n for playerMatGuid, countTable in pairs(PLAYER_PULLS) do\r\n local playerName = getPlayerName(playerMatGuid)\r\n printToAll(playerName .. \" Stats\", {r=255,g=0,b=0})\r\n printNonZeroTokenPairs(PLAYER_PULLS[playerMatGuid])\r\n playerSquidCount = PLAYER_PULLS[playerMatGuid][\"https://i.imgur.com/lns4fhz.png\"]\r\n if playerSquidCount ~= nil and playerSquidCount \u003e maxSquid then\r\n squidKing = playerName\r\n\t maxSquid = playerSquidCount\r\n end\r\n end\r\n printToAll(squidKing .. \" is an auto-fail magnet.\", {r=255,g=0,b=0})\r\nend\r\n\r\nfunction printNonZeroTokenPairs(theTable)\r\n for key,value in pairs(theTable) do\r\n if value ~= 0 then\r\n printToAll(IMAGE_TOKEN_MAP[key] .. '=' .. tostring(value))\r\n end\r\n end\r\nend\r\n\r\n-- Remove comments to enable autorotate cards on hands.\r\n-- function onObjectEnterScriptingZone(zone, object)\r\n-- Autorotate cards with right side up when entering hand.\r\n-- if zone.getGUID() == \"c506bf\" or -- white\r\n-- zone.getGUID() == \"cbc751\" then -- orange\r\n-- object.setRotationSmooth({0,270,0})\r\n-- elseif zone.getGUID() == \"67ce9a\" then -- green\r\n-- object.setRotationSmooth({0,0,0})\r\n-- elseif zone.getGUID() == \"57c22c\" then -- red\r\n-- object.setRotationSmooth({0,180,0})\r\n--end\r\n--end\r\n\r\nfunction findInRadiusBy(pos, radius, filter, debug)\r\n local radius = (radius or 1)\r\n local objList = Physics.cast({\r\n origin = pos,\r\n direction = {0,1,0},\r\n type = 2,\r\n size = {radius, radius, radius},\r\n max_distance = 0,\r\n debug = (debug or false)\r\n })\r\n\r\n local filteredList = {}\r\n for _, obj in ipairs(objList) do\r\n if filter == nil then\r\n table.insert(filteredList, obj.hit_object)\r\n elseif filter and filter(obj.hit_object) then\r\n table.insert(filteredList, obj.hit_object)\r\n end\r\n end\r\n return filteredList\r\nend\r\n\r\nfunction dealCardsInRows(paramlist)\r\n \tlocal currPosition={};\r\n local numRow=1;\r\n\tlocal numCard=0;\r\n\tlocal invMultiplier=1;\r\n\tlocal allCardsDealed=0;\r\n\t\tif paramlist.inverse then\r\n\t\tinvMultiplier=-1;\r\n\tend\r\n\t\tif paramlist.maxCardsDealed==nil then\r\n\r\n\t\tallCardsDealed=0;\r\n\t\tparamlist.maxCardsDealed=paramlist.cardDeck.getQuantity()\r\n\r\n\telseif paramlist.maxCardsDealed\u003e=paramlist.cardDeck.getQuantity() or paramlist.maxCardsDealed\u003c=0 then\r\n\r\n\t\tallCardsDealed=0;\r\n\t\tparamlist.maxCardsDealed=paramlist.cardDeck.getQuantity()\r\n\r\n\telse\r\n\r\n\t\tallCardsDealed=1;\r\n\r\n\tend\r\n\r\n\tif paramlist.mode==\"x\" then\r\n\t\tcurrPosition={paramlist.iniPosition[1]+(2*g_cardWith*invMultiplier*allCardsDealed),paramlist.iniPosition[2],paramlist.iniPosition[3]};\r\n\r\n\telse\r\n\t\tcurrPosition={paramlist.iniPosition[1],paramlist.iniPosition[2],paramlist.iniPosition[3]+(2*g_cardWith*invMultiplier*allCardsDealed)};\r\n\r\n\tend\r\n\r\n\tfor i = 1,paramlist.maxCardsDealed,1 do\r\n\r\n paramlist.cardDeck.takeObject\r\n ({\r\n position= currPosition,\r\n smooth= true\r\n });\r\n\r\n\t\tnumCard=numCard+1;\r\n\t\tif numCard\u003e=paramlist.maxCardRow then\r\n\r\n\t\t\tif paramlist.mode==\"x\" then\r\n\t\t\t\tcurrPosition={paramlist.iniPosition[1]+(2*g_cardWith*invMultiplier*allCardsDealed),paramlist.iniPosition[2],paramlist.iniPosition[3]};\r\n\t\t\t\tcurrPosition[3]=currPosition[3]-(numRow*g_cardHeigth*invMultiplier);\r\n\t\t\telse\r\n\t\t\t\tcurrPosition={paramlist.iniPosition[1],paramlist.iniPosition[2],paramlist.iniPosition[3]+(2*g_cardWith*invMultiplier*allCardsDealed)};\r\n\t\t\t\tcurrPosition[1]=currPosition[1]+(numRow*g_cardHeigth*invMultiplier);\r\n\t\t\tend\r\n\t\t\tnumCard=0;\r\n\t\t\tnumRow=numRow+1;\r\n\r\n\t\telse\r\n\t\t\tif paramlist.mode==\"x\" then\r\n\t\t\t\tcurrPosition[1]=currPosition[1]+(g_cardWith*invMultiplier);\r\n\t\t\telse\r\n\t\t\t\tcurrPosition[3]=currPosition[3]+(g_cardWith*invMultiplier);\r\n\t\t\tend\r\n\t\tend\r\n end\r\nend\r\n\r\nfunction isDeck(x)\r\n return x.tag == 'Deck'\r\nend\r\n\r\nfunction isCardOrDeck(x)\r\n return x.tag == 'Card' or isDeck(x)\r\nend\r\n\r\nfunction drawEncountercard(params) --[[ Parameter Table Position, Table Rotation]]\r\n local position = params[1]\r\n local rotation = params[2]\r\n local alwaysFaceUp = params[3]\r\n local faceUpRotation\r\n local card\r\n local items = findInRadiusBy(ENCOUNTER_DECK_POS, 4, isCardOrDeck)\r\n if #items \u003e 0 then\r\n for i, v in ipairs(items) do\r\n if v.tag == 'Deck' then\r\n card = v.takeObject({index = 0})\r\n break\r\n end\r\n end\r\n -- we didn't find the deck so just pull the first thing we did find\r\n if card == nil then card = items[1] end\r\n actualEncounterCardDraw(card, params)\r\n return\r\n end\r\n-- nothing here, time to reshuffle\r\n reshuffleEncounterDeck(params)\r\nend\r\n\r\nfunction actualEncounterCardDraw(card, params)\r\n local position = params[1]\r\n local rotation = params[2]\r\n local alwaysFaceUp = params[3]\r\n local faceUpRotation = 0\r\n if not alwaysFaceUp then\r\n if getObjectFromGUID(tokenDataId).call('checkHiddenCard', card.getName()) then\r\n faceUpRotation = 180\r\n end\r\n end\r\n card.setPositionSmooth(position, false, false)\r\n card.setRotationSmooth({0,rotation.y,faceUpRotation}, false, false)\r\nend\r\n\r\nIS_RESHUFFLING = false\r\nfunction reshuffleEncounterDeck(params)\r\n -- finishes moving the deck back and draws a card\r\n local function move(deck)\r\n deck.setPositionSmooth(ENCOUNTER_DECK_SPAWN_POS, true, false)\r\n actualEncounterCardDraw(deck.takeObject({index=0}), params)\r\n Wait.time(function()\r\n IS_RESHUFFLING = false\r\n end, 1)\r\n end\r\n -- bail out if we're mid reshuffle\r\n if IS_RESHUFFLING then\r\n return\r\n end\r\n local discarded = findInRadiusBy(ENCOUNTER_DECK_DISCARD_POSITION, 4, isDeck)\r\n if #discarded \u003e 0 then\r\n IS_RESHUFFLING = true\r\n local deck = discarded[1]\r\n if not deck.is_face_down then\r\n deck.flip()\r\n end\r\n deck.shuffle()\r\n Wait.time(|| move(deck), 0.3)\r\n else\r\n printToAll(\"couldn't find encounter discard pile to reshuffle\", {1, 0, 0})\r\n end\r\nend\r\n\r\nCHAOS_TOKENS = {}\r\nCHAOS_TOKENS_LAST_MAT = nil\r\nfunction putBackChaosTokens()\r\n local chaosbagposition = chaosbag.getPosition()\r\n for k, token in pairs(CHAOS_TOKENS) do\r\n if token ~= nil then\r\n chaosbag.putObject(token)\r\n token.setPosition({chaosbagposition[1],chaosbagposition[2]+0.5,chaosbagposition[3]})\r\n end\r\n end\r\n CHAOS_TOKENS = {}\r\n end\r\n\r\nfunction drawChaostoken(params)\r\n local mat = params[1]\r\n local tokenOffset = params[2]\r\n local isRightClick = params[3]\r\n local isSameMat = (CHAOS_TOKENS_LAST_MAT == nil or CHAOS_TOKENS_LAST_MAT == mat)\r\n if not isSameMat then\r\n putBackChaosTokens()\r\n end\r\n CHAOS_TOKENS_LAST_MAT = mat\r\n -- if we have left clicked and have no tokens OR if we have right clicked\r\n if isRightClick or #CHAOS_TOKENS == 0 then\r\n local items = getObjectFromGUID(\"83ef06\").getObjects()\r\n for i,v in ipairs(items) do\r\n if items[i].getDescription() == \"Chaos Bag\" then\r\n chaosbag = getObjectFromGUID(items[i].getGUID())\r\n break\r\n end\r\n end\r\n -- bail out if we have no tokens\r\n if #chaosbag.getObjects() == 0 then\r\n return\r\n end\r\n chaosbag.shuffle()\r\n -- add the token to the list, compute new position based on list length\r\n tokenOffset[1] = tokenOffset[1] + (0.17 * #CHAOS_TOKENS)\r\n local toPosition = mat.positionToWorld(tokenOffset)\r\n local token = chaosbag.takeObject({\r\n index = 0,\r\n position = toPosition,\r\n rotation = mat.getRotation(),\r\n\t callback_function = function(obj) take_callback(obj, mat) end\r\n })\r\n CHAOS_TOKENS[#CHAOS_TOKENS + 1] = token\r\n return\r\n else\r\n putBackChaosTokens()\r\n end\r\nend\r\n\r\nfunction spawnToken(params)\r\n -- Position to spawn,\r\n -- rotation vector to apply\r\n -- translation vector to apply\r\n -- token type\r\n local position = params[1]\r\n local tokenType = params[2]\r\n local tokenData = TOKEN_DATA[tokenType]\r\n if tokenData == nil then\r\n error(\"no token data found for '\" .. tokenType .. \"'\")\r\n end\r\n\r\n local token = spawnObject({\r\n type = 'Custom_Token',\r\n position = position,\r\n\trotation = {x=0, y=270, z=0}\r\n })\r\n token.setCustomObject({\r\n image = tokenData['image'],\r\n thickness = 0.3,\r\n merge_distance = 5.0,\r\n stackable = true,\r\n })\r\n token.use_snap_points=false\r\n token.scale(tokenData['scale'])\r\n return token\r\nend\r\n\r\nfunction round(params) -- Parameter (int number, int numberDecimalPlaces)\r\n return tonumber(string.format(\"%.\" .. (params[2] or 0) .. \"f\", params[1]))\r\nend\r\n\r\nfunction roundposition(params) -- Parameter (Table position)\r\n return {round({params[1], 2}),round({params[2], 2}),round({params[3], 2})}\r\nend\r\n\r\nfunction isEqual(params) --Parameter (Table table1, Table table2) returns true if the tables are equal\r\n if params[1][1] == params[2][1] and params[1][2] == params[2][2] and params[1][3] == params[2][3] then\r\n return true\r\n else\r\n return false\r\n end\r\nend\r\n\r\nfunction isFaceup(params) --Object object\r\n if params.getRotation()[3] \u003e -5 and params.getRotation()[3] \u003c 5 then\r\n return true\r\n else\r\n return false\r\n end\r\nend\r\n\r\n--Difficulty selector script\r\n\r\nfunction createSetupButtons(args)\r\n local data = getDataValue('modeData', args.key)\r\n if data ~= nil then\r\n local z = -0.15\r\n if data.easy ~= nil then\r\n args.object.createButton({\r\n label = 'Easy',\r\n click_function = 'easyClick',\r\n function_owner = args.object,\r\n position = {0, 0.1, z},\r\n rotation = {0, 0, 0},\r\n scale = {0.47, 1, 0.47},\r\n height = 200,\r\n width = 1150,\r\n font_size = 100,\r\n color = {0.87, 0.8, 0.70},\r\n font_color = {0, 0, 0}\r\n })\r\n z = z + 0.20\r\n end\r\n if data.normal ~= nil then\r\n args.object.createButton({\r\n label = 'Standard',\r\n click_function = 'normalClick',\r\n function_owner = args.object,\r\n position = {0, 0.1, z},\r\n rotation = {0, 0, 0},\r\n scale = {0.47, 1, 0.47},\r\n height = 200,\r\n width = 1150,\r\n font_size = 100,\r\n color = {0.87, 0.8, 0.70},\r\n font_color = {0, 0, 0}\r\n })\r\n z = z + 0.20\r\n end\r\n if data.hard ~= nil then\r\n args.object.createButton({\r\n label = 'Hard',\r\n click_function = 'hardClick',\r\n function_owner = args.object,\r\n position = {0, 0.1, z},\r\n rotation = {0, 0, 0},\r\n scale = {0.47, 1, 0.47},\r\n height = 200,\r\n width = 1150,\r\n font_size = 100,\r\n color = {0.87, 0.8, 0.70},\r\n font_color = {0, 0, 0}\r\n })\r\n z = z + 0.20\r\n end\r\n if data.expert ~= nil then\r\n args.object.createButton({\r\n label = 'Expert',\r\n click_function = 'expertClick',\r\n function_owner = args.object,\r\n position = {0, 0.1, z},\r\n rotation = {0, 0, 0},\r\n scale = {0.47, 1, 0.47},\r\n height = 200,\r\n width = 1150,\r\n font_size = 100,\r\n color = {0.87, 0.8, 0.70},\r\n font_color = {0, 0, 0}\r\n })\r\n z = z + 0.20\r\n end\r\n z = z + 0.10\r\n if data.standalone ~= nil then\r\n args.object.createButton({\r\n label = 'Standalone',\r\n click_function = 'standaloneClick',\r\n function_owner = args.object,\r\n position = {0, 0.1, z},\r\n rotation = {0, 0, 0},\r\n scale = {0.47, 1, 0.47},\r\n height = 200,\r\n width = 1150,\r\n font_size = 100,\r\n color = {0.87, 0.8, 0.70},\r\n font_color = {0, 0, 0}\r\n })\r\n end\r\n end\r\nend\r\n\r\nfunction fillContainer(args)\r\n local container = getObjectCache(containerId)\r\n\r\n if container ~= nil then\r\n local data = getDataValue('modeData', args.key)\r\n if data == nil then return end\r\n\r\n local value = data[args.mode]\r\n if value == nil or value.token == nil then return end\r\n\r\n local pos = container.getPosition()\r\n if args.object ~= nil then\r\n pos = args.object.getPosition()\r\n end\r\n\r\n cleanContainer(container)\r\n\r\n for _, token in ipairs(value.token) do\r\n local obj = spawnToken_2(token, pos)\r\n if obj ~= nil then\r\n container.putObject(obj)\r\n end\r\n end\r\n\r\n if value.append ~= nil then\r\n for _, token in ipairs(value.append) do\r\n local obj = spawnToken_2(token, pos)\r\n if obj ~= nil then\r\n container.putObject(obj)\r\n end\r\n end\r\n end\r\n\r\n if value.random then\r\n local n = #value.random\r\n if n \u003e 0 then\r\n for _, token in ipairs(value.random[getRandomCount(n)]) do\r\n local obj = spawnToken_2(token, pos)\r\n if obj ~= nil then\r\n container.putObject(obj)\r\n end\r\n end\r\n end\r\n end\r\n\r\n if value.message then\r\n broadcastToAll(value.message)\r\n end\r\n if value.warning then\r\n broadcastToAll(value.warning, { 1, 0.5, 0.5 })\r\n end\r\n end\r\nend\r\n\r\nfunction spawnToken_2(id, pos)\r\n local url = getImageUrl(id)\r\n if url ~= '' then\r\n local obj = spawnObject({\r\n type = 'Custom_Tile',\r\n position = {pos.x, pos.y + 3, pos.z},\r\n rotation = {x = 0, y = 260, z = 0}\r\n })\r\n obj.setCustomObject({\r\n type = 2,\r\n image = url,\r\n thickness = 0.10,\r\n })\r\n obj.scale {0.81, 1, 0.81}\r\n obj.setName(getTokenName({ url=url }))\r\n return obj\r\n end\r\nend\r\n\r\nfunction getTokenName(params)\r\n local name = IMAGE_TOKEN_MAP[params.url]\r\n if name == nil then name = \"\" end\r\n return name\r\nend\r\n\r\nfunction getImageUrl(id)\r\n if id == 'p1' then return 'https://i.imgur.com/uIx8jbY.png' end\r\n if id == '0' then return 'https://i.imgur.com/btEtVfd.png' end\r\n if id == 'm1' then return 'https://i.imgur.com/w3XbrCC.png' end\r\n if id == 'm2' then return 'https://i.imgur.com/bfTg2hb.png' end\r\n if id == 'm3' then return 'https://i.imgur.com/yfs8gHq.png' end\r\n if id == 'm4' then return 'https://i.imgur.com/qrgGQRD.png' end\r\n if id == 'm5' then return 'https://i.imgur.com/3Ym1IeG.png' end\r\n if id == 'm6' then return 'https://i.imgur.com/c9qdSzS.png' end\r\n if id == 'm7' then return 'https://i.imgur.com/4WRD42n.png' end\r\n if id == 'm8' then return 'https://i.imgur.com/9t3rPTQ.png' end\r\n if id == 'skull' then return 'https://i.imgur.com/stbBxtx.png' end\r\n if id == 'cultist' then return 'https://i.imgur.com/VzhJJaH.png' end\r\n if id == 'tablet' then return 'https://i.imgur.com/1plY463.png' end\r\n if id == 'elder' then return 'https://i.imgur.com/ttnspKt.png' end\r\n if id == 'red' then return 'https://i.imgur.com/lns4fhz.png' end\r\n if id == 'blue' then return 'https://i.imgur.com/nEmqjmj.png' end\r\n\tif id == 'frost' then return 'http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/' end\r\n return ''\r\nend\r\n\r\nfunction cleanContainer(container)\r\n for _, item in ipairs(container.getObjects()) do\r\n destroyObject(container.takeObject({}))\r\n end\r\nend\r\n\r\nfunction getObjectsInZone(zoneId)\r\n local zoneObject = getObjectCache(zoneId)\r\n\r\n if zoneObject == nil then\r\n return\r\n end\r\n\r\n local objectsInZone = zoneObject.getObjects()\r\n local objectsFound = {}\r\n\r\n for i = 1, #objectsInZone do\r\n local object = objectsInZone[i]\r\n if object.tag == 'Bag' then\r\n table.insert(objectsFound, object.guid)\r\n end\r\n end\r\n\r\n if #objectsFound \u003e 0 then\r\n return objectsFound\r\n end\r\nend\r\n\r\nfunction getObjectCache(id)\r\n if CACHE.object[id] == nil then\r\n CACHE.object[id] = getObjectFromGUID(id)\r\n end\r\n return CACHE.object[id]\r\nend\r\n\r\nfunction getDataTable(storage)\r\n if CACHE.data[storage] == nil then\r\n local obj = getObjectCache(tokenDataId)\r\n if obj ~= nil then\r\n CACHE.data[storage] = obj.getTable(storage)\r\n end\r\n end\r\n return CACHE.data[storage]\r\nend\r\n\r\nfunction getDataValue(storage, key)\r\n local data = getDataTable(storage)\r\n if data ~= nil then\r\n local value = data[key]\r\n if value ~= nil then\r\n local res = {}\r\n for m, v in pairs(value) do\r\n res[m] = v\r\n if res[m].parent ~= nil then\r\n local parentData = getDataValue(storage, res[m].parent)\r\n if parentData ~= nil and parentData[m] ~= nil and parentData[m].token ~= nil then\r\n res[m].token = parentData[m].token\r\n end\r\n res[m].parent = nil\r\n end\r\n end\r\n return res\r\n end\r\n end\r\nend\r\n\r\nfunction getRandomCount(to)\r\n updateRandomSeed()\r\n return math.random(1, to)\r\nend\r\n\r\nfunction updateRandomSeed()\r\n local chance = math.random(1,10)\r\n if chance == 1 then\r\n math.randomseed(os.time())\r\n end\r\nend\r\n\r\n\r\n-- Content Importing\r\n\r\n\r\n--- Loadable Items test\r\n\r\nlocal source_repo = 'https://raw.githubusercontent.com/seth-sced/loadable-objects/main'\r\nlocal list_url = 'library.json'\r\nlocal library = nil\r\n\r\nlocal request_obj\r\n\r\n---\r\n\r\nfunction get_source_repo()\r\n return source_repo\r\nend\r\n\r\n---\r\n\r\nfunction onClick_toggleUi(player, window)\r\n toggle_ui(window)\r\nend\r\n\r\nfunction onClick_refreshList()\r\n local request = WebRequest.get(get_source_repo() .. '/' .. list_url, completed_list_update)\r\n request_obj = request\r\n startLuaCoroutine(Global, 'my_coroutine')\r\nend\r\n\r\nfunction onClick_select(player, params)\r\n params = JSON.decode(urldecode(params))\r\n local url = get_source_repo() .. '/' .. params.url\r\n local request = WebRequest.get(url, function (request) complete_obj_download(request, params) end )\r\n request_obj = request\r\n startLuaCoroutine(Global, 'my_coroutine')\r\nend\r\n\r\nfunction onClick_load()\r\n UI.show('progress_display')\r\n UI.hide('load_button')\r\nend\r\n\r\nfunction onClick_cancel()\r\nend\r\n\r\n---\r\n\r\nfunction toggle_ui(title)\r\n UI.hide('load_ui')\r\n if UI.getValue('title') == title or title == 'Hidden' then\r\n UI.setValue('title', 'Hidden')\r\n else\r\n UI.setValue('title', title)\r\n update_window_content(title)\r\n UI.show('load_ui')\r\n end\r\nend\r\n\r\nfunction my_coroutine()\r\n while request_obj do\r\n UI.setAttribute('download_progress', 'percentage', request_obj.download_progress * 100)\r\n coroutine.yield(0)\r\n end\r\n return 1\r\nend\r\n\r\n\r\nfunction update_list(objects)\r\n local ui = UI.getXmlTable()\r\n local update_height = find_tag_with_id(ui, 'ui_update_height')\r\n local update_children = find_tag_with_id(update_height.children, 'ui_update_point')\r\n\r\n update_children.children = {}\r\n\r\n for i,v in ipairs(objects) do\r\n local s = JSON.encode(v);\r\n --print(s)\r\n table.insert(update_children.children,\r\n {\r\n tag = 'Text',\r\n value = v.name,\r\n attributes = { onClick = 'onClick_select('.. urlencode(JSON.encode(v)) ..')',\r\n alignment = 'MiddleLeft' }\r\n }\r\n )\r\n end\r\n\r\n update_height.attributes.height = #(update_children.children) * 24\r\n UI.setXmlTable(ui)\r\nend\r\n\r\nfunction update_window_content(new_title)\r\n if not library then\r\n return\r\n end\r\n\r\n if new_title == 'Campaigns' then\r\n update_list(library.campaigns)\r\n elseif new_title == 'Standalone Scenarios' then\r\n update_list(library.scenarios)\r\n elseif new_title == 'Investigators' then\r\n update_list(library.investigators)\r\n elseif new_title == 'Community Content' then\r\n update_list(library.community)\r\n elseif new_title == 'Extras' then\r\n update_list(library.extras)\r\n else\r\n update_list({})\r\n end\r\nend\r\n\r\nfunction complete_obj_download(request, params)\r\n assert(request.is_done)\r\n if request.is_error or request.response_code ~= 200 then\r\n print('error: ' .. request.error)\r\n else\r\n if pcall(function ()\r\n local replaced_object\r\n pcall(function ()\r\n if params.replace then\r\n replaced_object = getObjectFromGUID(params.replace)\r\n end\r\n end)\r\n local json = request.text\r\n if replaced_object then\r\n local pos = replaced_object.getPosition()\r\n local rot = replaced_object.getRotation()\r\n destroyObject(replaced_object)\r\n Wait.frames(function () spawnObjectJSON({json = json, position = pos, rotation = rot}) end, 1)\r\n else\r\n spawnObjectJSON({json = json})\r\n end\r\n end) then\r\n print('Object loaded.')\r\n else\r\n print('Error loading object.')\r\n end\r\n end\r\n\r\n request_obj = nil\r\n UI.setAttribute('download_progress', 'percentage', 100)\r\n\r\nend\r\n\r\n-- the download button on the placeholder objects calls this to directly initiate a download\r\nfunction placeholder_download(params)\r\n -- params is a table with url and guid of replacement object, which happens to match what onClick_select wants\r\n onClick_select(nil, JSON.encode(params))\r\nend\r\n\r\nfunction completed_list_update(request)\r\n assert(request.is_done)\r\n if request.is_error or request.response_code ~= 200 then\r\n print('error: ' .. request.error)\r\n else\r\n local json_response = nil\r\n if pcall(function () json_response = JSON.decode(request.text) end) then\r\n library = json_response\r\n update_window_content(UI.getValue('title'))\r\n else\r\n print('error parsing downloaded library')\r\n end\r\n end\r\n\r\n request_obj = nil\r\n UI.setAttribute('download_progress', 'percentage', 100)\r\nend\r\n\r\n---\r\n\r\nfunction find_tag_with_id(ui, id)\r\n for i,obj in ipairs(ui) do\r\n if obj.attributes and obj.attributes.id and obj.attributes.id == id then\r\n return obj\r\n end\r\n if obj.children then\r\n local result = find_tag_with_id(obj.children, id)\r\n if result then return result end\r\n end\r\n end\r\n return nil\r\nend\r\n\r\nfunction urlencode(str)\r\n str = string.gsub(str, \"([^A-Za-z0-9-_.~])\",\r\n function (c) return string.format(\"%%%02X\", string.byte(c)) end)\r\n return str\r\nend\r\n\r\nfunction urldecode(str)\r\n str = string.gsub(str, \"%%(%x%x)\",\r\n function (h) return string.char(tonumber(h, 16)) end)\r\n return str\r\nend\r\n\nend)\nreturn __bundle_require(\"__root\")", + "LuaScript": "require(\"core/Global\")", "LuaScriptState": "", "MusicPlayer_path": "MusicPlayer.json", "Note": "",