Merge branch 'main' into global-api

This commit is contained in:
Chr1Z93 2024-08-04 15:59:45 +02:00
commit 2cb7bf7781
6 changed files with 217 additions and 49 deletions

View File

@ -157,7 +157,7 @@
"TokenSource.124381",
"GameData.3dbe47",
"SCEDTour.0e5aa8",
"InstructionGenerator.240522",
"DeckInstructionGenerator.240522",
"PlayerCards.2d30ee",
"TokenRemover.39b175",
"TokenRemover.2ba7a5",
@ -218,7 +218,8 @@
"Neutral.06ee01",
"Neutral.88d9ff",
"Neutral.42ec66",
"Neutral.f94579"
"Neutral.f94579",
"CardBackEnhancer.87450c"
],
"PlayArea": 1,
"PlayerCounts": [

View File

@ -0,0 +1,70 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"AttachedSnapPoints": [
{
"Position": {
"x": 0,
"y": 0.1,
"z": 0.2
}
}
],
"Autoraise": true,
"ColorDiffuse": {
"b": 0,
"g": 0,
"r": 0
},
"CustomImage": {
"CustomTile": {
"Stackable": false,
"Stretch": true,
"Thickness": 0.1,
"Type": 3
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://steamusercontent-a.akamaihd.net/ugc/2466368617700253137/69CF42FB33A6CDDD8A84191FBCB27637E1A7699D/",
"WidthScale": 0
},
"Description": "This tool applies the correct (high resolution) PlayerCard or ScenarioCard back to cards / decks that are dropped on it. It requires the respective tag on each card.\n\nWhy would you need this?\na) You're creating custom content and some cards have the wrong back for some reason.\nb) You're playing custom content and noticed that a card uses an old (low resolution) PlayerCard or ScenarioCard back.",
"DragSelectable": true,
"GMNotes": "",
"GUID": "87450c",
"Grid": true,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScriptState": "",
"LuaScript": "require(\"accessories/CardBackEnhancer\")",
"MeasureMovement": false,
"Name": "Custom_Tile",
"Nickname": "Card Back Enhancer",
"Snap": true,
"Sticky": true,
"Tags": [
"PlayerCard",
"ScenarioCard"
],
"Tooltip": true,
"Transform": {
"posX": -17.5,
"posY": 1.481,
"posZ": 89,
"rotX": 0,
"rotY": 270,
"rotZ": 0,
"scaleX": 2.667,
"scaleY": 1,
"scaleZ": 2.667
},
"Value": 0,
"XmlUI": ""
}

View File

@ -15,23 +15,23 @@
],
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
"b": 0,
"g": 0,
"r": 0
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 15,
"CustomTile": {
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
"Stretch": true,
"Thickness": 0.1,
"Type": 3
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://steamusercontent-a.akamaihd.net/ugc/2280574378890547614/63FE6CDF23322B6C4001514E2B8891BA998FAD71/",
"ImageURL": "https://steamusercontent-a.akamaihd.net/ugc/2466368617700119071/AB8294EEBA3A219CDCE287323B764D13E2A43822/",
"WidthScale": 0
},
"Description": "This tool can generate a description for your deck on ArkhamDB that will instruct the deck importer to add the specified cards.\nThe cards need to be available (either from the AllCardsBag or the 'Additional Playercards Bag'.",
"Description": "This tool can generate a description for your deck on ArkhamDB that will instruct the Deck Importer to add the specified cards.\nThe cards need to be available (either from the AllCardsBag or the 'Additional Playercards Bag'.",
"DragSelectable": true,
"GMNotes": "",
"GUID": "240522",
@ -42,25 +42,25 @@
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"arkhamdb/InstructionGenerator\")",
"LuaScript": "require(\"arkhamdb/DeckInstructionGenerator\")",
"LuaScriptState": "",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Instruction Generator",
"Name": "Custom_Tile",
"Nickname": "Deck Instruction Generator",
"Snap": true,
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": -17.5,
"posY": 1.531,
"posY": 1.481,
"posZ": 83,
"rotX": 0,
"rotY": 270,
"rotZ": 0,
"scaleX": 1.25,
"scaleX": 3,
"scaleY": 1,
"scaleZ": 1.35
"scaleZ": 3
},
"Value": 0,
"XmlUI": ""
}
}

View File

@ -0,0 +1,80 @@
local backUrl = {
ScenarioCard =
"https://steamusercontent-a.akamaihd.net/ugc/2342503777940351785/F64D8EFB75A9E15446D24343DA0A6EEF5B3E43DB/",
PlayerCard =
"https://steamusercontent-a.akamaihd.net/ugc/2342503777940352139/A2D42E7E5C43D045D72CE5CFC907E4F886C8C690/"
}
local deckChanges = {}
local lastObjGuid
function onCollisionEnter(collisionInfo)
local obj = collisionInfo.collision_object
if obj.guid == lastObjGuid then return end
lastObjGuid = obj.guid
Wait.time(function() lastObjGuid = nil end, 0.5)
if obj.type ~= "Card" and obj.type ~= "Deck" then return end
local data = obj.getData()
local count = 0
if obj.type == "Card" then
local result = processCard(data)
if result then count = count + 1 end
elseif obj.type == "Deck" then
for _, cardData in ipairs(data["ContainedObjects"]) do
local result = processCard(cardData)
if result then count = count + 1 end
end
-- update top-level custom deck data
for customDeckId, customDeckData in pairs(data["CustomDeck"]) do
if deckChanges[customDeckId] then
customDeckData["BackURL"] = deckChanges[customDeckId]
end
end
end
if count == 1 then
broadcastToAll("Enhanced the back of 1 card.")
else
broadcastToAll("Enhanced the back of " .. count .. " cards.")
end
obj.destruct()
spawnObjectData({ data = data })
end
function processCard(cardData)
-- determine card type
local tags = {}
for _, tag in ipairs(cardData["Tags"] or {}) do
tags[tag] = true
end
-- has both or neither tag, can't work out back
if tags.PlayerCard == tags.ScenarioCard then
printToAll("Missing or double tag for '" .. cardData["Nickname"] .. "'.")
return false
end
local newBack
if tags.PlayerCard then
newBack = backUrl.PlayerCard
elseif tags.ScenarioCard then
newBack = backUrl.ScenarioCard
end
local customDeckId, customDeckData = next(cardData["CustomDeck"])
-- if this card already has the correct back
if customDeckData["BackURL"] == newBack then return false end
-- skip cards with decksheets as back
if (customDeckData["NumHeight"] == 1 and customDeckData["NumWidth"] == 1)
or customDeckData["UniqueBack"] == false then
customDeckData["BackURL"] = newBack
deckChanges[customDeckId] = newBack
end
return true
end

View File

@ -7,11 +7,11 @@ function onLoad()
local buttonParameters = {}
buttonParameters.function_owner = self
buttonParameters.height = 200
buttonParameters.width = 1200
buttonParameters.font_size = 75
buttonParameters.width = 800
buttonParameters.click_function = "generate"
buttonParameters.label = "Generate instructions!"
buttonParameters.position = { 0, 0.06, 1.55 }
buttonParameters.color = { 0, 0, 0, 0 }
buttonParameters.position = { 0, 0.11, 0.74 }
buttonParameters.scale = { 0.5, 1, 0.5 }
self.createButton(buttonParameters)
-- "output" text field
@ -19,14 +19,15 @@ function onLoad()
inputParameters.label = "Click button above"
inputParameters.input_function = "none"
inputParameters.function_owner = self
inputParameters.position = { 0, 0.05, 1.95 }
inputParameters.position = { 0, 0.11, 1.1 }
inputParameters.width = 1200
inputParameters.height = 130
inputParameters.font_size = 107
inputParameters.scale = { 0.4, 1, 0.4 }
self.createInput(inputParameters)
end
-- generates a string for the ArkhamDB deck notes that will instruct the deck import to add the specified cards
-- generates a string for the deck notes that will instruct the Deck Importer to add the specified cards
function generate(_, playerColor)
idList = {}
for _, obj in ipairs(searchLib.onObject(self, "isCardOrDeck")) do
@ -43,7 +44,8 @@ function generate(_, playerColor)
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")
broadcastToColor("Created deck instruction for " .. #idList .. " card(s). Copy it from the input field.", playerColor,
"Green")
end
-- sort the idList
@ -55,7 +57,7 @@ function generate(_, playerColor)
description = description .. "\n- add: " .. entry.id .. " (**" .. entry.name .. "**)"
end
self.editInput({index = 0, value = description})
self.editInput({ index = 0, value = description })
end
-- use the ZoopGuid as fallback if no id present
@ -70,7 +72,7 @@ end
function processCard(notes, name, playerColor)
local id = getIdFromData(JSON.decode(notes) or {})
if id then
table.insert(idList, {id = id, name = name})
table.insert(idList, { id = id, name = name })
else
broadcastToColor("Couldn't get ID for " .. name .. ".", playerColor, "Red")
end

View File

@ -55,33 +55,48 @@ function onCollisionEnter(collisionInfo)
-- 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()
-- detect if a new scenario card is placed down
if currentScenario ~= description then
currentScenario = description
fireScenarioChangedEvent()
end
local metadata = JSON.decode(object.getGMNotes()) or {}
if not metadata["tokens"] then
tokenData = {}
return
end
-- detect orientation of scenario card (for difficulty)
useFrontData = not object.is_face_down
tokenData = metadata["tokens"][(useFrontData and "front" or "back")]
fireTokenDataChangedEvent()
end
-- reset spawned tokens and remove tokens from cards in encounter deck / discard area
local localPos = self.positionToLocal(object.getPosition())
if inArea(localPos, ENCOUNTER_DECK_AREA) or inArea(localPos, ENCOUNTER_DISCARD_AREA) then
Wait.frames(function() tokenSpawnTrackerApi.resetTokensSpawned(object) end, 1)
removeTokensFromObject(object)
return
end
-- get metadata
local md = JSON.decode(object.getGMNotes()) or {}
-- get scenario name and maybe fire followup event
local cardName = object.getName()
if object.getName() == "Scenario" or md.type == "ScenarioReference" then
getDataFromReferenceCard(object, cardName, md)
end
end
-- maybe load data from reference card
function getDataFromReferenceCard(card, cardName, md)
local newScenarioName
if cardName == "Scenario" then
newScenarioName = card.getDescription()
else
newScenarioName = cardName
end
-- detect if a new scenario card is placed down
if currentScenario ~= newScenarioName then
currentScenario = newScenarioName
fireScenarioChangedEvent()
end
if not md["tokens"] then
tokenData = {}
return
end
-- detect orientation of scenario card (for difficulty)
useFrontData = not card.is_face_down
tokenData = md["tokens"][(useFrontData and "front" or "back")]
fireTokenDataChangedEvent()
end
-- TTS event handler. Handles scenario name event triggering