From af3a238aa4502e912270c7c63a0874aa5d5188c3 Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Fri, 26 Jan 2024 15:30:37 +0100 Subject: [PATCH 1/8] updated Ghosts of Onigawa playarea images --- src/core/PlayAreaImageData.ttslua | 36 ++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/src/core/PlayAreaImageData.ttslua b/src/core/PlayAreaImageData.ttslua index c7cc294b..e1354fdb 100644 --- a/src/core/PlayAreaImageData.ttslua +++ b/src/core/PlayAreaImageData.ttslua @@ -854,29 +854,45 @@ PLAYAREA_IMAGE_DATA = { }, ["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 = "I - The Hidden Village", + URL = "https://i.imgur.com/btTQffc.jpeg" }, { - Name = "II - In The Shadow Of Mount Kokoro", - URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-02.png?raw=true" + Name = "II - The House on the Hill", + URL = "https://i.imgur.com/YTHt8JQ.jpeg" }, { - Name = "III - The Onigawa River", - URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-03.png?raw=true" + Name = "III - The River Delta", + URL = "https://i.imgur.com/9Zk3iLJ.png" }, { - Name = "IV - The Crimson Butterfly", - URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-04.png?raw=true" + Name = "IV - The War Eternal", + URL = "https://i.imgur.com/6UtFHhc.jpeg" }, { - Name = "V - The Koi Conspiracy", - URL = "https://github.com/ArkhamDotCards/theghostsofonigawa/blob/main/product/onigawa-playmat-05.png?raw=true" + Name = "V - Half Light", + URL = "https://i.imgur.com/hul7lLL.png" + }, + { + Name = "VI - The End of August", + URL = "https://i.imgur.com/PKWtpG7.jpeg" + }, + { + Name = "VII - The Molten Armory", + URL = "https://i.imgur.com/kMSdBRh.jpeg" + }, + { + Name = "VIII - The Black Harvest", + URL = "https://i.imgur.com/6ySucTS.jpeg" } } }, ["Fan-Made Scenarios"] = { ["Side Scenarios (FM)"] = { + { + Name = "Code Red at Bleeding Heart", + URL = "https://i.imgur.com/nTstdlj.jpeg" + }, { Name = "Consternation on the Constellation", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725512402/37F34A14CEEA9D2F889F7B97B065C0193F268FE1/" From 4710a5105f9e37f0d2b2b5b6e4849a5a693d4efe Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Sun, 28 Jan 2024 10:49:05 +0100 Subject: [PATCH 2/8] fixed name --- src/core/PlayAreaImageData.ttslua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/PlayAreaImageData.ttslua b/src/core/PlayAreaImageData.ttslua index e1354fdb..ad6a2c75 100644 --- a/src/core/PlayAreaImageData.ttslua +++ b/src/core/PlayAreaImageData.ttslua @@ -630,11 +630,11 @@ PLAYAREA_IMAGE_DATA = { URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444450/FE4C335B0F72E83900A4EED0FD1A1D304D70D6B7/" }, { - Name = "59-Z Congress of Keys 1", + Name = "59-Z Congress of the Keys 1", URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444576/5BB32469ED412D59BB0A46E57D226500B1D0568B/" }, { - Name = "59-Z Congress of Keys 2", + Name = "59-Z Congress of the Keys 2", URL = "http://cloud-3.steamusercontent.com/ugc/2038485431566444690/B01A1FEAB57473D9B6DF11B92D62C214AA1C2C02/" } } From 3b700cf94799a63d13de08f91cb9df671aec9fa6 Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Sun, 4 Feb 2024 21:57:44 +0100 Subject: [PATCH 3/8] added playername to broadcast --- src/playermat/Playmat.ttslua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/playermat/Playmat.ttslua b/src/playermat/Playmat.ttslua index 2187ed20..99e3b861 100644 --- a/src/playermat/Playmat.ttslua +++ b/src/playermat/Playmat.ttslua @@ -487,7 +487,9 @@ function doDiscardOne() -- get a random non-hidden card (from the "choices" table) local num = math.random(1, #choices) deckLib.placeOrMergeIntoDeck(hand[choices[num]], returnGlobalDiscardPosition(), self.getRotation()) - broadcastToAll(playerColor .. " randomly discarded card " .. choices[num] .. "/" .. #hand .. ".", "White") + + local playerName = Player[playerColor].steam_name or playerColor + broadcastToAll(playerName .. " randomly discarded card " .. choices[num] .. "/" .. #hand .. ".", "White") end end From 0e5a83f948cf865b3512f0e42fd270a4629e95a2 Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Sun, 4 Feb 2024 22:02:38 +0100 Subject: [PATCH 4/8] fixed missing playmat handling --- src/accessories/CleanUpHelper.ttslua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/accessories/CleanUpHelper.ttslua b/src/accessories/CleanUpHelper.ttslua index 9cf93302..bbfd1c04 100644 --- a/src/accessories/CleanUpHelper.ttslua +++ b/src/accessories/CleanUpHelper.ttslua @@ -280,7 +280,7 @@ function tidyPlayerMatCoroutine() local trash = guidReferenceApi.getObjectByOwnerAndType(COLORS[i], "Trash") if trash == nil then printToAll("Trashcan for " .. COLORS[i] .. " playmat could not be found!", "Red") - break + goto continue end local objList @@ -315,6 +315,7 @@ function tidyPlayerMatCoroutine() end end end + ::continue:: end -- reset spawned data From b2f08eb46615a87a6881616ac210ea996dd7a69d Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Sun, 4 Feb 2024 22:46:52 +0100 Subject: [PATCH 5/8] re-added collision disabling --- config.json | 3 ++- src/core/MythosArea.ttslua | 11 ++++++++- src/core/PlayArea.ttslua | 45 ++++++++++++++++-------------------- src/core/PlayAreaApi.ttslua | 5 ---- src/playermat/Playmat.ttslua | 2 +- 5 files changed, 33 insertions(+), 33 deletions(-) diff --git a/config.json b/config.json index ceb0d46b..14238f9a 100644 --- a/config.json +++ b/config.json @@ -20,6 +20,7 @@ "Note": "", "ObjectStates_order": [ "GUIDReferenceHandler.123456", + "TokenSpawnTracker.e3ffc9", "HandTrigger.5fe087", "HandTrigger.be2f17", "HandTrigger.0285cc", @@ -167,7 +168,7 @@ "PhaseTrackerCache.49922d", "PhaseTrackerCache.16832f", "PhaseTrackerCache.645841", - "TokenSpawnTracker.e3ffc9", + "TokenSource.124381", "GameData.3dbe47", "SCEDTour.0e5aa8", diff --git a/src/core/MythosArea.ttslua b/src/core/MythosArea.ttslua index b9b94001..6cef6680 100644 --- a/src/core/MythosArea.ttslua +++ b/src/core/MythosArea.ttslua @@ -19,6 +19,7 @@ local ENCOUNTER_DISCARD_AREA = { local ENCOUNTER_DECK_POS = { x = -3.93, y = 1, z = 5.76 } local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1, z = 10.38 } local isReshuffling = false +local collisionEnabled = false local currentScenario, useFrontData, tokenData local TRASH, DATA_HELPER @@ -31,6 +32,8 @@ function onLoad(saveState) end TRASH = guidReferenceApi.getObjectByOwnerAndType("Mythos", "Trash") DATA_HELPER = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DataHelper") + + Wait.time(function() collisionEnabled = true end, 0.1) end function onSave() @@ -47,8 +50,14 @@ end -- TTS event handler. Handles scenario name event triggering and encounter card token resets. function onCollisionEnter(collisionInfo) + if not collisionEnabled then return end + local object = collisionInfo.collision_object + -- early exit for better performance + if object.type ~= "Card" then return end + + -- get scenario name and maybe fire followup event if object.getName() == "Scenario" then local description = object.getDescription() @@ -72,7 +81,7 @@ function onCollisionEnter(collisionInfo) local localPos = self.positionToLocal(object.getPosition()) if inArea(localPos, ENCOUNTER_DECK_AREA) or inArea(localPos, ENCOUNTER_DISCARD_AREA) then - tokenSpawnTrackerApi.resetTokensSpawned(object.getGUID()) + Wait.frames(function() tokenSpawnTrackerApi.resetTokensSpawned(object.getGUID()) end, 1) removeTokensFromObject(object) end end diff --git a/src/core/PlayArea.ttslua b/src/core/PlayArea.ttslua index 89390bc0..76ce5567 100644 --- a/src/core/PlayArea.ttslua +++ b/src/core/PlayArea.ttslua @@ -39,13 +39,12 @@ local LOC_LINK_EXCLUDE_SCENARIOS = { ["The Heart of Madness"] = true } -local clueData = {} -local spawnedLocationGUIDs = {} local locations = {} local locationConnections = {} local draggingGuids = {} local missingData = {} -local locationData, currentScenario, connectionsEnabled +local collisionEnabled = false +local currentScenario, connectionsEnabled --------------------------------------------------------- -- general code @@ -67,6 +66,8 @@ function onLoad(savedData) currentScenario = loadedData.currentScenario connectionColor = loadedData.connectionColor or { 0.4, 0.4, 0.4, 1 } connectionsEnabled = loadedData.connectionsEnabled or true + + Wait.time(function() collisionEnabled = true end, 0.1) end -- Called by Custom Data Helpers to push their location data into the Data Helper. This adds the @@ -105,31 +106,30 @@ end -- TTS event, called for each object that is placed on the playarea function onCollisionEnter(collisionInfo) - local obj = collisionInfo.collision_object - local objType = obj.name + if not collisionEnabled then return end + + local object = collisionInfo.collision_object + + if object.type == "Deck" then + table.insert(missingData, object) + end -- only continue for cards - if objType ~= "Card" and objType ~= "CardCustom" then - if objType == "Deck" then - table.insert(missingData, obj) - end - return - end + if object.type ~= "Card" then return end -- check if we should spawn clues here and do so according to playercount - local card = collisionInfo.collision_object - if shouldSpawnTokens(card) then - tokenManager.spawnForCard(card) + if shouldSpawnTokens(object) then + tokenManager.spawnForCard(object) 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 + if draggingGuids[object.getGUID()] ~= nil then + object.setVectorLines(nil) + draggingGuids[object.getGUID()] = nil end - - maybeTrackLocation(card) + + maybeTrackLocation(object) end function shouldSpawnTokens(card) @@ -540,11 +540,6 @@ function isInPlayArea(object) return position.x > c1.x and position.x < c2.x and position.z > c1.z and position.z < c2.z end --- Reset the play area's tracking of which cards have had tokens spawned. -function resetSpawnedCards() - spawnedLocationGUIDs = {} -end - function onScenarioChanged(scenarioName) currentScenario = scenarioName if not showLocationLinks() then diff --git a/src/core/PlayAreaApi.ttslua b/src/core/PlayAreaApi.ttslua index 9f0fdac3..e88b84a1 100644 --- a/src/core/PlayAreaApi.ttslua +++ b/src/core/PlayAreaApi.ttslua @@ -41,11 +41,6 @@ do 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 - -- Sets whether location connections should be drawn PlayAreaApi.setConnectionDrawState = function(state) getPlayArea().call("setConnectionDrawState", state) diff --git a/src/playermat/Playmat.ttslua b/src/playermat/Playmat.ttslua index 2187ed20..1d2bc2db 100644 --- a/src/playermat/Playmat.ttslua +++ b/src/playermat/Playmat.ttslua @@ -144,8 +144,8 @@ function onLoad(saveState) end showDrawButton(isDrawButtonVisible) - collisionEnabled = true math.randomseed(os.time()) + Wait.time(function() collisionEnabled = true end, 0.1) end --------------------------------------------------------- From 3aed124ed5bbb19610a314052e23d07c004bbe66 Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Sun, 4 Feb 2024 22:52:01 +0100 Subject: [PATCH 6/8] added uses to necronomicon --- .../AllPlayerCards.15bb07/TheNecronomicon.5b2e10.gmnotes | 7 +++++++ .../AllPlayerCards.15bb07/TheNecronomicon.6b2550.gmnotes | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/objects/AllPlayerCards.15bb07/TheNecronomicon.5b2e10.gmnotes b/objects/AllPlayerCards.15bb07/TheNecronomicon.5b2e10.gmnotes index f3e985fa..b3057d11 100644 --- a/objects/AllPlayerCards.15bb07/TheNecronomicon.5b2e10.gmnotes +++ b/objects/AllPlayerCards.15bb07/TheNecronomicon.5b2e10.gmnotes @@ -4,6 +4,13 @@ "slot": "Hand", "class": "Neutral", "traits": "Item. Tome.", + "uses": [ + { + "count": 3, + "type": "Horror", + "token": "horror" + } + ], "weakness": true, "cycle": "Standalone" } diff --git a/objects/AllPlayerCards.15bb07/TheNecronomicon.6b2550.gmnotes b/objects/AllPlayerCards.15bb07/TheNecronomicon.6b2550.gmnotes index d5c7964c..d92a188b 100644 --- a/objects/AllPlayerCards.15bb07/TheNecronomicon.6b2550.gmnotes +++ b/objects/AllPlayerCards.15bb07/TheNecronomicon.6b2550.gmnotes @@ -7,6 +7,13 @@ "slot": "Hand", "class": "Neutral", "traits": "Item. Tome.", + "uses": [ + { + "count": 3, + "type": "Horror", + "token": "horror" + } + ], "weakness": true, "cycle": "Core" } From fb593ebd1e31b8e6ebea4e471f0e8a8a9266a0a0 Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Mon, 5 Feb 2024 00:47:56 +0100 Subject: [PATCH 7/8] some name fixes --- src/core/PlayAreaImageData.ttslua | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/core/PlayAreaImageData.ttslua b/src/core/PlayAreaImageData.ttslua index ad6a2c75..3cf5d3f2 100644 --- a/src/core/PlayAreaImageData.ttslua +++ b/src/core/PlayAreaImageData.ttslua @@ -704,27 +704,27 @@ PLAYAREA_IMAGE_DATA = { URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725491658/5446E231AEF72CF4F7B4892116671FF7175EFA0F/" } }, - ["Labyrinths of Lunacy"] = { + ["The Labyrinths of Lunacy"] = { { - Name = "Labyrinths of Lunacy 1", + Name = "The Labyrinths of Lunacy 1", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725489685/D2D342844212C8A21E030418935A227C2E3279DB/" }, { - Name = "Labyrinths of Lunacy 2", + Name = "The Labyrinths of Lunacy 2", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725489820/E3E18B0940C2604F62E564AD43F178FF9F13B3C9/" }, { - Name = "Labyrinths of Lunacy 3", + Name = "The Labyrinths of Lunacy 3", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725489972/6A34CF53190EAAAF57C31FB97A3C2ACBD27FEE40/" } }, - ["Murder at Excelsior Hotel"] = { + ["Murder at the Excelsior Hotel"] = { { - Name = "Murder at Excelsior Hotel 1", + Name = "Murder at the Excelsior Hotel 1", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725488868/7F7FE8BB3C7E3645B4377F86366C6073CDB8F113/" }, { - Name = "Murder at Excelsior Hotel 2", + Name = "Murder at the Excelsior Hotel 2", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725489144/53A920E2D1A9F41937B21B0A5B1A4E450ABFC460/" } }, @@ -792,19 +792,19 @@ PLAYAREA_IMAGE_DATA = { }, ["Dark Matter"] = { { - Name = "I - Tatterdemalion 1", + Name = "I - The Tatterdemalion 1", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725504118/AC852F478D5BDA0C8A54A499B07A66E872560EC7/" }, { - Name = "I - Tatterdemalion 2", + Name = "I - The Tatterdemalion 2", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725504319/5B24BB2080AC76D836708AABC1BC90FD884F043D/" }, { - Name = "I - Tatterdemalion 3", + Name = "I - The Tatterdemalion 3", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725504461/73E4632A2EAAFA918924E60A64B03838CA6DDD77/" }, { - Name = "I - Tatterdemalion 4", + Name = "I - The Tatterdemalion 4", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725504602/6DB8F081CC907A0D6F364E5045BB7E8FADA91B5C/" }, { @@ -831,6 +831,10 @@ PLAYAREA_IMAGE_DATA = { Name = "IIIc - Strange Moons", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725506071/78597C2FBE2DE55BFC86AEC9F42FE1B20D26544C/" }, + { + Name = "IV - The Machine in Yellow", + URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725426327/41F6192EDCFFD6AAE2EE44C2BB5708B19D7464A9/" + }, { Name = "V - Fragment of Carcosa 1", URL = "http://cloud-3.steamusercontent.com/ugc/2279446315725506388/A299C8D58171A6D78CF55D911C2B81C63D88444F/" From c4d61200e8f143535119a8ce2bbb42351bdd82ef Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Tue, 6 Feb 2024 16:32:14 +0100 Subject: [PATCH 8/8] updated attachment helper --- .../AttachmentHelper.d45664.json | 4 +- src/accessories/AttachmentHelper.ttslua | 153 +++++++++++------- 2 files changed, 94 insertions(+), 63 deletions(-) diff --git a/objects/OptionPanelSource.830bd0/AttachmentHelper.7f4976/AttachmentHelper.d45664.json b/objects/OptionPanelSource.830bd0/AttachmentHelper.7f4976/AttachmentHelper.d45664.json index 72c7bbcf..6b22d1e9 100644 --- a/objects/OptionPanelSource.830bd0/AttachmentHelper.7f4976/AttachmentHelper.d45664.json +++ b/objects/OptionPanelSource.830bd0/AttachmentHelper.7f4976/AttachmentHelper.d45664.json @@ -35,7 +35,7 @@ "LayoutGroupSortIndex": 0, "Locked": false, "LuaScript": "require(\"accessories/AttachmentHelper\")", - "LuaScriptState": "[[],true,true]", + "LuaScriptState": "[[],true]", "MaterialIndex": -1, "MeasureMovement": false, "MeshIndex": -1, @@ -54,7 +54,7 @@ "posZ": -19.636, "rotX": 0, "rotY": 270, - "rotZ": 359, + "rotZ": 0, "scaleX": 0.8, "scaleY": 1, "scaleZ": 0.8 diff --git a/src/accessories/AttachmentHelper.ttslua b/src/accessories/AttachmentHelper.ttslua index 4b2345ed..7c5dfda9 100644 --- a/src/accessories/AttachmentHelper.ttslua +++ b/src/accessories/AttachmentHelper.ttslua @@ -1,97 +1,110 @@ local searchLib = require("util/SearchLib") -local fontColor +local fontColor, lastRejectedName local BACKGROUNDS = { { title = "Ancestral Knowledge", url = "http://cloud-3.steamusercontent.com/ugc/1915746489207287888/2F9F6F211ED0F98E66C9D35D93221E4C7FB6DD3C/", - fontcolor = { 1, 1, 1 } + fontcolor = { 1, 1, 1 }, + icons = true }, { title = "Astronomical Atlas", url = "http://cloud-3.steamusercontent.com/ugc/1754695853007989004/9153BC204FC707AE564ECFAC063A11CB8C2B5D1E/", - fontcolor = { 1, 1, 1 } + fontcolor = { 1, 1, 1 }, + icons = true }, { title = "Backpack", url = "http://cloud-3.steamusercontent.com/ugc/2018212896278691928/F55BEFFC2540109C6333179532F583B367FF2EBC/", - fontcolor = { 0, 0, 0 } + fontcolor = { 0, 0, 0 }, + icons = false + }, + { + title = "Bewitching", + url = "http://cloud-3.steamusercontent.com/ugc/2342503480966345423/F2070B5479C814F35780373966D77D91767A97CC/", + fontcolor = { 1, 1, 1 }, + icons = false }, { title = "Binder's Jar", url = "http://cloud-3.steamusercontent.com/ugc/2021606446228642191/4C149527851C1DBB3015F93DE91667937A3F91DD/", - fontcolor = { 1, 1, 1 } + fontcolor = { 1, 1, 1 }, + icons = false }, { title = "Crystallizer of Dreams", url = "http://cloud-3.steamusercontent.com/ugc/1915746489207280958/100F16441939E5E23818651D1EB5C209BF3125B9/", - fontcolor = { 1, 1, 1 } + fontcolor = { 1, 1, 1 }, + icons = true }, { title = "Diana Stanley", url = "http://cloud-3.steamusercontent.com/ugc/1754695635919071208/1AB7222850201630826BFFBA8F2BD0065E2D572F/", - fontcolor = { 1, 1, 1 } + fontcolor = { 1, 1, 1 }, + icons = false }, { title = "Gloria Goldberg", url = "http://cloud-3.steamusercontent.com/ugc/1754695635919102502/453D4426118C8A6DE2EA281184716E26CA924C84/", - fontcolor = { 1, 1, 1 } + fontcolor = { 1, 1, 1 }, + icons = false }, { title = "Ikiaq", url = "http://cloud-3.steamusercontent.com/ugc/2021606446228198966/5A408D8D760221DEA164E986B9BE1F79C4803071/", - fontcolor = { 1, 1, 1 } + fontcolor = { 1, 1, 1 }, + icons = false }, { title = "Katja Eastbank", url = "http://cloud-3.steamusercontent.com/ugc/2021606446228203475/62EEE12F4DB1EB80D79B087677459B954380215F/", - fontcolor = { 1, 1, 1 } + fontcolor = { 1, 1, 1 }, + icons = false }, { title = "Ravenous", url = "http://cloud-3.steamusercontent.com/ugc/2021606446228208075/EAC598A450BEE504A7FE179288F1FBBF7ABFA3E0/", - fontcolor = { 0, 0, 0 } + fontcolor = { 0, 0, 0 }, + icons = false }, { title = "Sefina Rousseau", url = "http://cloud-3.steamusercontent.com/ugc/1754695635919099826/3C3CBFFAADB2ACA9957C736491F470AE906CC953/", - fontcolor = { 0, 0, 0 } + fontcolor = { 0, 0, 0 }, + icons = false }, { title = "Stick to the Plan", url = "http://cloud-3.steamusercontent.com/ugc/2018214163838897493/8E38B96C5A8D703A59009A932432CBE21ABE63A2/", - fontcolor = { 1, 1, 1 } + fontcolor = { 1, 1, 1 }, + icons = false }, { title = "Subject 5U-21", url = "http://cloud-3.steamusercontent.com/ugc/2021606446228199363/CE43D58F37C9F48BDD6E6E145FE29BADEFF4DBC5/", - fontcolor = { 1, 1, 1 } + fontcolor = { 1, 1, 1 }, + icons = false }, { title = "Wooden Sledge", url = "http://cloud-3.steamusercontent.com/ugc/1750192233783143973/D526236AAE16BDBB98D3F30E27BAFC1D3E21F4AC/", - fontcolor = { 0, 0, 0 } + fontcolor = { 0, 0, 0 }, + icons = false } } -- save state and options to restore onLoad -function onSave() return JSON.encode({ cardsInBag, showCost, showIcons }) end +function onSave() return JSON.encode({ cardsInBag, showIcons }) end -- load variables and create context menu function onLoad(savedData) local loadedData = JSON.decode(savedData) - cardsInBag = loadedData[1] or {} - showCost = loadedData[2] or true - showIcons = loadedData[3] or true + cardsInBag = loadedData[1] + showIcons = loadedData[2] fontColor = getFontColor() recreateButtons() self.addContextMenuItem("Select image", selectImage) - self.addContextMenuItem("Toggle cost", function(color) - showCost = not showCost - printToColor("Show cost of cards: " .. tostring(showCost), color, "White") - refresh() - end) - self.addContextMenuItem("Toggle skill icons", function(color) showIcons = not showIcons printToColor("Show skill icons of cards: " .. tostring(showIcons), color, "White") @@ -124,6 +137,7 @@ function onDrop(playerColor) for _, bgInfo in ipairs(BACKGROUNDS) do if bgInfo.title == syncName then printToColor("Background for '" .. syncName .. "' loaded!", playerColor, "Green") + showIcons = bgInfo.icons updateImage(bgInfo.url) return end @@ -141,13 +155,14 @@ function selectImage(color) -- prompt user to select option Player[color].showOptionsDialog("Select image:", options, 1, function(_, optionIndex) + showIcons = BACKGROUNDS[optionIndex].icons updateImage(BACKGROUNDS[optionIndex].url) end) end -- sets background to the provided URL function updateImage(url) - self.script_state = JSON.encode({ cardsInBag, showCost, showIcons }) + self.script_state = JSON.encode({ cardsInBag, showIcons }) local customInfo = self.getCustomObject() customInfo.diffuse = url self.setCustomObject(customInfo) @@ -155,23 +170,28 @@ function updateImage(url) end -- only allow cards to enter, split decks and reject other objects -function onObjectEnterContainer(container, object) - if container ~= self then return end +function tryObjectEnter(object) + -- block repeated collisions + if object.getName() == lastRejectedName then return end + if object.type == "Deck" then - takeDeckOut(object.getGUID(), self.getPosition() + Vector(0, 0.1, 0)) + local pos = self.getPosition() + for i = 1, #object.getObjects() do + local card = object.takeObject({ position = pos + Vector(0, 0.1 * i, 0), smooth = false }) + findCard(card.getGUID(), card.getName(), card.getGMNotes()) + self.putObject(card) + end + recreateButtons() + return false elseif object.type ~= "Card" then - broadcastToAll("The 'Attachment Helper' is meant to be used for cards.", "White") + broadcastToAll("The 'Attachment Helper' only supports cards.", "Orange") + lastRejectedName = object.getName() + Wait.time(function() lastRejectedName = nil end, 1) + return false else findCard(object.getGUID(), object.getName(), object.getGMNotes()) recreateButtons() - end -end - --- takes the deck out and splits in into single cards -function takeDeckOut(guid, pos) - local deck = self.takeObject({ guid = guid, position = pos, smooth = false }) - for i = 1, #deck.getObjects() do - self.putObject(deck.takeObject({ position = pos + Vector(0, 0.1 * i, 0), smooth = false })) + return true end end @@ -181,7 +201,7 @@ function onObjectLeaveContainer(container, object) local guid = object.getGUID() local found = false for i, card in ipairs(cardsInBag) do - if card.id == guid then + if card.guid == guid then table.remove(cardsInBag, i) found = true break @@ -212,22 +232,16 @@ end -- gets cost and icons for a card function findCard(guid, name, GMNotes) - local cost = "" local icons = {} - local metadata = {} - local displayName = name + local metadata = JSON.decode(GMNotes) or {} + local buttonLabel = name or "unnamed" - if displayName == nil or displayName == "" then displayName = "unnamed" end - if showCost or showIcons then metadata = JSON.decode(GMNotes) end - - if showCost then - if GMNotes ~= "" then cost = metadata.cost end - if cost == nil or cost == "" then cost = "–" end - displayName = "[" .. cost .. "] " .. displayName + if metadata.cost then + buttonLabel = "[" .. metadata.cost .. "] " .. buttonLabel end if showIcons then - if GMNotes ~= "" then + if metadata ~= {} then icons[1] = metadata.wildIcons icons[2] = metadata.willpowerIcons icons[3] = metadata.intellectIcons @@ -240,15 +254,16 @@ function findCard(guid, name, GMNotes) for i = 1, 5 do if icons[i] ~= nil and icons[i] ~= "" then if found == false then - displayName = displayName .. "\n" .. IconTypes[i] .. ": " .. icons[i] + buttonLabel = buttonLabel .. "\n" found = true else - displayName = displayName .. " " .. IconTypes[i] .. ": " .. icons[i] + buttonLabel = buttonLabel .. " " end + buttonLabel = buttonLabel .. IconTypes[i] .. ": " .. icons[i] end end end - table.insert(cardsInBag, { name = name, displayName = displayName, id = guid }) + table.insert(cardsInBag, { buttonLabel = buttonLabel, hasIcons = (#icons > 0), name = name, guid = guid }) end -- recreates buttons with up-to-date labels @@ -256,20 +271,36 @@ function recreateButtons() self.clearButtons() local verticalPosition = 1.65 - for _, card in ipairs(cardsInBag) do - local id = card.id - local funcName = "removeCard" .. id - self.setVar(funcName, function() removeCard(id) end) + -- create buttons for the last 7 cards that entered + for i = #cardsInBag, 1, -1 do + if (i + 7) == #cardsInBag then + printToAll("Only displaying buttons for the last 7 cards.", "Orange") + break + end + + local card = cardsInBag[i] + + -- click function + local funcName = "removeCard" .. card.guid + self.setVar(funcName, function() removeCard(card.guid) end) + + -- font size + local fontSize = 100 + if card.hasIcons or string.len(card.buttonLabel) > 20 then + fontSize = 75 + end + + -- button creation self.createButton({ - label = card.displayName, + label = card.buttonLabel, click_function = funcName, function_owner = self, position = { 0, -0.1, verticalPosition }, height = 200, width = 1200, - font_size = string.len(card.displayName) > 20 and 75 or 100 + font_size = fontSize }) - verticalPosition = verticalPosition - 0.5 + verticalPosition = verticalPosition - 0.485 end local countLabel = #cardsInBag @@ -280,7 +311,7 @@ function recreateButtons() end self.createButton({ - label = countLabel, + label = tostring(countLabel), click_function = "none", function_owner = self, position = { 0, -0.1, -1.7 },