From 7e2a4d71d5369ed62a0bbe5cb0365d6d29413bde Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Mon, 18 Dec 2023 12:56:10 +0100 Subject: [PATCH 1/4] added arkhamdb deck description parsing --- src/arkhamdb/ArkhamDb.ttslua | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/arkhamdb/ArkhamDb.ttslua b/src/arkhamdb/ArkhamDb.ttslua index 6e766d2f..fc5882ba 100644 --- a/src/arkhamdb/ArkhamDb.ttslua +++ b/src/arkhamdb/ArkhamDb.ttslua @@ -145,6 +145,7 @@ do loadAltInvestigator = internal.addInvestigatorCards(deck, slots) end + internal.maybeModifyDeckFromDescription(slots, deck.description_md) internal.maybeAddSummonedServitor(slots) internal.maybeAddOnTheMend(slots, playerColor) internal.maybeAddRealityAcidReference(slots) @@ -285,6 +286,49 @@ do end end + -- Processes the deck description from ArkhamDB and modifies the slot list accordingly + ---@param slots Table The slot list for cards in this deck. Table key is the cardId, value is the number + ---@param description String The deck desription from ArkhamDB + internal.maybeModifyDeckFromDescription = function(slots, description) + -- check for import instructions + local pos = string.find(description, "++SCED import instructions++") + if not pos then return end + + -- remove everything before instructions (including newline) + local tempStr = string.sub(description, pos + 30) + + -- parse each line in instructions + for line in tempStr:gmatch("([^\n]+)") do + -- remove dashes at the start + line = line:gsub("%- ", "") + + -- remove spaces + line = line:gsub("%s", "") + + -- get instructor + local instructor = "" + for word in line:gmatch("%a+:") do + instructor = word + break + end + + if instructor == "" or (instructor ~= "add:" and instructor ~= "remove:") then return end + + -- remove instructor from line + line = line:gsub(instructor, "") + + -- evaluate instructions + local cardIds = {} + for str in line:gmatch("([^,]+)") do + if instructor == "add:" then + slots[str] = (slots[str] or 0) + 1 + elseif instructor == "remove:" then + slots[str] = math.max(slots[str] - 1, 0) + end + end + 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) From 402b3da06ddde4f489039f8275ce14cddded6bb9 Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Mon, 18 Dec 2023 13:34:49 +0100 Subject: [PATCH 2/4] added default hotfix bag --- config.json | 2 +- objects/AdditionalPlayerCards.2cba6b.json | 54 +++++++++++++++++++++++ src/arkhamdb/HotfixBag.ttslua | 14 ++++++ src/playercards/AllCardsBag.ttslua | 11 ++--- 4 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 objects/AdditionalPlayerCards.2cba6b.json diff --git a/config.json b/config.json index a1b831e1..ff3931be 100644 --- a/config.json +++ b/config.json @@ -3,7 +3,6 @@ "ComponentTags_path": "ComponentTags.json", "CustomUIAssets_path": "CustomUIAssets.json", "DecalPallet_path": "DecalPallet.json", - "Decals": [], "GameComplexity": "", "GameMode": "Arkham Horror LCG - Super Complete Edition", "GameType": "", @@ -104,6 +103,7 @@ "MasterClueCounter.4a3aa4", "LegacyAssets.7165a9", "PlayArea.721ba2", + "AdditionalPlayerCards.2cba6b", "BarkhamHorror.308439", "ChaosBagStatTracker.766620", "Blesstokens.afa06b", diff --git a/objects/AdditionalPlayerCards.2cba6b.json b/objects/AdditionalPlayerCards.2cba6b.json new file mode 100644 index 00000000..4b5ea75d --- /dev/null +++ b/objects/AdditionalPlayerCards.2cba6b.json @@ -0,0 +1,54 @@ +{ + "AltLookAngle": { + "x": 0, + "y": 0, + "z": 0 + }, + "Autoraise": true, + "Bag": { + "Order": 0 + }, + "ColorDiffuse": { + "b": 0, + "g": 0.36652, + "r": 0.70588 + }, + "Description": "Put any cards in here to add them to the indices for the player card panel and deck importer.\n\nThis can be used for custom cards too.", + "DragSelectable": true, + "GMNotes": "", + "GUID": "2cba6b", + "Grid": true, + "GridProjection": false, + "Hands": false, + "HideWhenFaceDown": false, + "IgnoreFoW": false, + "LayoutGroupSortIndex": 0, + "Locked": true, + "LuaScript": "require(\"arkhamdb/HotfixBag\")", + "LuaScriptState": "", + "MaterialIndex": -1, + "MeasureMovement": false, + "MeshIndex": -1, + "Name": "Bag", + "Nickname": "Additional Player Cards", + "Number": 0, + "Snap": true, + "Sticky": true, + "Tags": [ + "AllCardsHotfix" + ], + "Tooltip": true, + "Transform": { + "posX": 60, + "posY": 1.204, + "posZ": 48, + "rotX": 0, + "rotY": 0, + "rotZ": 0, + "scaleX": 1.5, + "scaleY": 1.5, + "scaleZ": 1.5 + }, + "Value": 0, + "XmlUI": "" +} \ No newline at end of file diff --git a/src/arkhamdb/HotfixBag.ttslua b/src/arkhamdb/HotfixBag.ttslua index cbbb9088..c4530c14 100644 --- a/src/arkhamdb/HotfixBag.ttslua +++ b/src/arkhamdb/HotfixBag.ttslua @@ -12,3 +12,17 @@ local allCardsBagApi = require("playercards/AllCardsBagApi") function onLoad() allCardsBagApi.rebuildIndexForHotfix() end + +-- update with small delay to allow multiple cards being added at once +function onObjectEnterContainer(container, object) + if container == self then + Wait.time(function() allCardsBagApi.rebuildIndexForHotfix() end, 1) + end +end + +-- update with small delay to allow multiple cards being removed at once +function onObjectLeaveContainer(container, object) + if container == self then + Wait.time(function() allCardsBagApi.rebuildIndexForHotfix() end, 1) + end +end diff --git a/src/playercards/AllCardsBag.ttslua b/src/playercards/AllCardsBag.ttslua index ef01de1c..8f23442d 100644 --- a/src/playercards/AllCardsBag.ttslua +++ b/src/playercards/AllCardsBag.ttslua @@ -81,9 +81,6 @@ function buildIndex() if (cardMetadata ~= nil) then addCardToIndex(cardData, cardMetadata) end - if (i % 20 == 0) then - coroutine.yield(0) - end end local hotfixBags = getObjectsWithTag("AllCardsHotfix") for _, hotfixBag in ipairs(hotfixBags) do @@ -102,9 +99,13 @@ function buildIndex() end -- Adds a card to any indexes it should be a part of, based on its metadata. --- Param cardData: TTS object data for the card --- Param cardMetadata: SCED metadata for the card +---@param cardData: TTS object data for the card +---@param cardMetadata: SCED metadata for the card function addCardToIndex(cardData, cardMetadata) + -- use the ZoopGuid as fallback if no id present + if cardMetadata.id == nil and cardMetadata.TtsZoopGuid then + cardMetadata.id = cardMetadata.TtsZoopGuid + end cardIdIndex[cardMetadata.id] = { data = cardData, metadata = cardMetadata } if (cardMetadata.alternate_ids ~= nil) then for _, alternateId in ipairs(cardMetadata.alternate_ids) do From 079c8747a4171b135147ee0b162b714703e300d4 Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Mon, 18 Dec 2023 15:26:08 +0100 Subject: [PATCH 3/4] added instruction generator --- config.json | 1 + objects/InstructionGenerator.240522.json | 66 ++++++++++++++++++++++++ src/arkhamdb/InstructionGenerator.ttslua | 27 ++++++++++ 3 files changed, 94 insertions(+) create mode 100644 objects/InstructionGenerator.240522.json create mode 100644 src/arkhamdb/InstructionGenerator.ttslua diff --git a/config.json b/config.json index ff3931be..cade7f1c 100644 --- a/config.json +++ b/config.json @@ -173,6 +173,7 @@ "TokenSource.124381", "GameData.3dbe47", "SCEDTour.0e5aa8", + "InstructionGenerator.240522", "PlayerCards.2d30ee", "TokenRemover.39b175", "TokenRemover.2ba7a5", diff --git a/objects/InstructionGenerator.240522.json b/objects/InstructionGenerator.240522.json new file mode 100644 index 00000000..9e287489 --- /dev/null +++ b/objects/InstructionGenerator.240522.json @@ -0,0 +1,66 @@ +{ + "AltLookAngle": { + "x": 0, + "y": 0, + "z": 0 + }, + "AttachedSnapPoints": [ + { + "Position": { + "x": 0, + "y": 0.1, + "z": 0.05 + } + } + ], + "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/2280574378890547614/63FE6CDF23322B6C4001514E2B8891BA998FAD71/", + "WidthScale": 0 + }, + "Description": "This tool can generate an description for you deck on ArkhamDB that will instruct the deck importer to add the specified cards.", + "DragSelectable": true, + "GMNotes": "", + "GUID": "240522", + "Grid": true, + "GridProjection": false, + "Hands": false, + "HideWhenFaceDown": false, + "IgnoreFoW": false, + "LayoutGroupSortIndex": 0, + "Locked": true, + "LuaScript": "require(\"arkhamdb/InstructionGenerator\")", + "LuaScriptState": "", + "MeasureMovement": false, + "Name": "Custom_Token", + "Nickname": "Instruction Generator", + "Snap": true, + "Sticky": true, + "Tooltip": true, + "Transform": { + "posX": -17.5, + "posY": 1.531, + "posZ": 83, + "rotX": 0, + "rotY": 270, + "rotZ": 0, + "scaleX": 1.25, + "scaleY": 1, + "scaleZ": 1.35 + }, + "Value": 0, + "XmlUI": "" +} \ No newline at end of file diff --git a/src/arkhamdb/InstructionGenerator.ttslua b/src/arkhamdb/InstructionGenerator.ttslua new file mode 100644 index 00000000..fdde0eba --- /dev/null +++ b/src/arkhamdb/InstructionGenerator.ttslua @@ -0,0 +1,27 @@ +local + +function onLoad() + local buttonParameters = {} + buttonParameters.function_owner = self + buttonParameters.height = 200 + buttonParameters.width = 1200 + buttonParameters.font_size = 75 + buttonParameters.click_function = "generate" + buttonParameters.label = "Generate instructions!" + buttonParameters.position = { 0, 0.06, 1.55 } + self.createButton(buttonParameters) + + local inputParameters = {} + inputParameters.label = "Click button above" + inputParameters.input_function = "input_func" + inputParameters.function_owner = self + inputParameters.position = { 0, 0.05, 1.95 } + inputParameters.width = 1200 + inputParameters.height = 130 + inputParameters.font_size = 107 + self.createInput(inputParameters) +end + +function generate() + +end \ No newline at end of file From 7cd29deca11051cebb5e55d1437bcb653b2cb002 Mon Sep 17 00:00:00 2001 From: Chr1Z93 Date: Mon, 18 Dec 2023 16:19:51 +0100 Subject: [PATCH 4/4] added support for decks in hotfix bags --- objects/AdditionalPlayerCards.2cba6b.json | 2 +- src/arkhamdb/HotfixBag.ttslua | 15 +----- src/arkhamdb/InstructionGenerator.ttslua | 58 +++++++++++++++++++++-- src/playercards/AllCardsBag.ttslua | 15 ++++-- 4 files changed, 68 insertions(+), 22 deletions(-) diff --git a/objects/AdditionalPlayerCards.2cba6b.json b/objects/AdditionalPlayerCards.2cba6b.json index 4b5ea75d..ce719273 100644 --- a/objects/AdditionalPlayerCards.2cba6b.json +++ b/objects/AdditionalPlayerCards.2cba6b.json @@ -13,7 +13,7 @@ "g": 0.36652, "r": 0.70588 }, - "Description": "Put any cards in here to add them to the indices for the player card panel and deck importer.\n\nThis can be used for custom cards too.", + "Description": "Put any cards in here to add them to the indices for the player card panel and deck importer.\n\nSelect the 'update index' entry in the context menu of this bag once you've added all cards.\n\nThis can be used for custom cards too.", "DragSelectable": true, "GMNotes": "", "GUID": "2cba6b", diff --git a/src/arkhamdb/HotfixBag.ttslua b/src/arkhamdb/HotfixBag.ttslua index c4530c14..b8ced966 100644 --- a/src/arkhamdb/HotfixBag.ttslua +++ b/src/arkhamdb/HotfixBag.ttslua @@ -11,18 +11,5 @@ local allCardsBagApi = require("playercards/AllCardsBagApi") function onLoad() allCardsBagApi.rebuildIndexForHotfix() -end - --- update with small delay to allow multiple cards being added at once -function onObjectEnterContainer(container, object) - if container == self then - Wait.time(function() allCardsBagApi.rebuildIndexForHotfix() end, 1) - end -end - --- update with small delay to allow multiple cards being removed at once -function onObjectLeaveContainer(container, object) - if container == self then - Wait.time(function() allCardsBagApi.rebuildIndexForHotfix() end, 1) - end + self.addContextMenuItem("Update card index", function() allCardsBagApi.rebuildIndexForHotfix() end) end diff --git a/src/arkhamdb/InstructionGenerator.ttslua b/src/arkhamdb/InstructionGenerator.ttslua index fdde0eba..1b8d4c9e 100644 --- a/src/arkhamdb/InstructionGenerator.ttslua +++ b/src/arkhamdb/InstructionGenerator.ttslua @@ -1,4 +1,4 @@ -local +local searchLib = require("util/SearchLib") function onLoad() local buttonParameters = {} @@ -13,7 +13,7 @@ function onLoad() local inputParameters = {} inputParameters.label = "Click button above" - inputParameters.input_function = "input_func" + inputParameters.input_function = "none" inputParameters.function_owner = self inputParameters.position = { 0, 0.05, 1.95 } inputParameters.width = 1200 @@ -22,6 +22,56 @@ function onLoad() self.createInput(inputParameters) end -function generate() +function generate(_, playerColor) + local idList = {} + for _, obj in ipairs(searchLib.onObject(self, "isCardOrDeck")) do + if obj.type == "Card" then + local cardMetadata = JSON.decode(obj.getGMNotes()) + + if cardMetadata then + local id = getIdFromData(cardMetadata) + if id then + table.insert(idList, id) + end + end + elseif obj.type == "Deck" then + for _, deepObj in ipairs(obj.getData().ContainedObjects) do + local cardMetadata = JSON.decode(deepObj.GMNotes) + if cardMetadata then + local id = getIdFromData(cardMetadata) + if id then + table.insert(idList, id) + end + end + end + end + end -end \ No newline at end of file + if #idList == 0 then + broadcastToColor("Didn't find any valid cards.", playerColor, "Red") + return + else + broadcastToColor("Created deck instruction for " .. #idList .. " card(s). Copy it from the input field.", playerColor, "Green") + end + + -- construct the string + local description = "++SCED import instructions++\n- add: " + for _, id in ipairs(idList) do + description = description .. id .. ", " + end + + -- remove last delimiter (last two characters) + description = description:sub(1, -3) + self.editInput({index = 0, value = description}) +end + +-- use the ZoopGuid as fallback if no id present +function getIdFromData(metadata) + if metadata.id then + return metadata.id + elseif metadata.TtsZoopGuid then + return metadata.TtsZoopGuid + end +end + +function none() end diff --git a/src/playercards/AllCardsBag.ttslua b/src/playercards/AllCardsBag.ttslua index 8f23442d..a6a7bb9a 100644 --- a/src/playercards/AllCardsBag.ttslua +++ b/src/playercards/AllCardsBag.ttslua @@ -86,9 +86,18 @@ function buildIndex() for _, hotfixBag in ipairs(hotfixBags) do if (#hotfixBag.getObjects() > 0) then for i, cardData in ipairs(hotfixBag.getData().ContainedObjects) do - local cardMetadata = JSON.decode(cardData.GMNotes) - if (cardMetadata ~= nil) then - addCardToIndex(cardData, cardMetadata) + if cardData.ContainedObjects then + for j, deepCardData in ipairs(cardData.ContainedObjects) do + local deepCardMetadata = JSON.decode(deepCardData.GMNotes) + if deepCardMetadata ~= nil then + addCardToIndex(deepCardData, deepCardMetadata) + end + end + else + local cardMetadata = JSON.decode(cardData.GMNotes) + if cardMetadata ~= nil then + addCardToIndex(cardData, cardMetadata) + end end end end