Merge pull request #509 from argonui/custom-card-importing

Added custom card importing support to Deck Importer
This commit is contained in:
BootleggerFinn 2023-12-18 21:35:41 -06:00 committed by GitHub
commit d8412de83d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 262 additions and 8 deletions

View File

@ -103,6 +103,7 @@
"MasterClueCounter.4a3aa4", "MasterClueCounter.4a3aa4",
"LegacyAssets.7165a9", "LegacyAssets.7165a9",
"PlayArea.721ba2", "PlayArea.721ba2",
"AdditionalPlayerCards.2cba6b",
"BarkhamHorror.308439", "BarkhamHorror.308439",
"ChaosBagStatTracker.766620", "ChaosBagStatTracker.766620",
"Blesstokens.afa06b", "Blesstokens.afa06b",
@ -173,6 +174,7 @@
"GameData.3dbe47", "GameData.3dbe47",
"PlayermatClickInterceptor.3dbe55", "PlayermatClickInterceptor.3dbe55",
"SCEDTour.0e5aa8", "SCEDTour.0e5aa8",
"InstructionGenerator.240522",
"PlayerCards.2d30ee", "PlayerCards.2d30ee",
"TokenRemover.39b175", "TokenRemover.39b175",
"TokenRemover.2ba7a5", "TokenRemover.2ba7a5",

View File

@ -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\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",
"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": ""
}

View File

@ -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": ""
}

View File

@ -145,6 +145,7 @@ do
loadAltInvestigator = internal.addInvestigatorCards(deck, slots) loadAltInvestigator = internal.addInvestigatorCards(deck, slots)
end end
internal.maybeModifyDeckFromDescription(slots, deck.description_md)
internal.maybeAddSummonedServitor(slots) internal.maybeAddSummonedServitor(slots)
internal.maybeAddOnTheMend(slots, playerColor) internal.maybeAddOnTheMend(slots, playerColor)
internal.maybeAddRealityAcidReference(slots) internal.maybeAddRealityAcidReference(slots)
@ -285,6 +286,49 @@ do
end end
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. -- 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 ---@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) internal.extractBondedCards = function(slots)

View File

@ -11,4 +11,5 @@ local allCardsBagApi = require("playercards/AllCardsBagApi")
function onLoad() function onLoad()
allCardsBagApi.rebuildIndexForHotfix() allCardsBagApi.rebuildIndexForHotfix()
self.addContextMenuItem("Update card index", function() allCardsBagApi.rebuildIndexForHotfix() end)
end end

View File

@ -0,0 +1,77 @@
local searchLib = require("util/SearchLib")
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 = "none"
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(_, 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
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

View File

@ -81,30 +81,40 @@ function buildIndex()
if (cardMetadata ~= nil) then if (cardMetadata ~= nil) then
addCardToIndex(cardData, cardMetadata) addCardToIndex(cardData, cardMetadata)
end end
if (i % 20 == 0) then
coroutine.yield(0)
end
end end
local hotfixBags = getObjectsWithTag("AllCardsHotfix") local hotfixBags = getObjectsWithTag("AllCardsHotfix")
for _, hotfixBag in ipairs(hotfixBags) do for _, hotfixBag in ipairs(hotfixBags) do
if (#hotfixBag.getObjects() > 0) then if (#hotfixBag.getObjects() > 0) then
for i, cardData in ipairs(hotfixBag.getData().ContainedObjects) do for i, cardData in ipairs(hotfixBag.getData().ContainedObjects) do
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) local cardMetadata = JSON.decode(cardData.GMNotes)
if (cardMetadata ~= nil) then if cardMetadata ~= nil then
addCardToIndex(cardData, cardMetadata) addCardToIndex(cardData, cardMetadata)
end end
end end
end end
end end
end
buildSupplementalIndexes() buildSupplementalIndexes()
indexingDone = true indexingDone = true
return 1 return 1
end end
-- Adds a card to any indexes it should be a part of, based on its metadata. -- 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 cardData: TTS object data for the card
-- Param cardMetadata: SCED metadata for the card ---@param cardMetadata: SCED metadata for the card
function addCardToIndex(cardData, cardMetadata) 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 } cardIdIndex[cardMetadata.id] = { data = cardData, metadata = cardMetadata }
if (cardMetadata.alternate_ids ~= nil) then if (cardMetadata.alternate_ids ~= nil) then
for _, alternateId in ipairs(cardMetadata.alternate_ids) do for _, alternateId in ipairs(cardMetadata.alternate_ids) do