diff --git a/objects/PlayerCards.2d30ee.json b/objects/PlayerCards.2d30ee.json
index a623b186..606c796d 100644
--- a/objects/PlayerCards.2d30ee.json
+++ b/objects/PlayerCards.2d30ee.json
@@ -60,5 +60,5 @@
"scaleZ": 10
},
"Value": 0,
- "XmlUI": "\u003cInclude src=\"playercards/PlayerCardPanel.xml\"/\u003e"
+ "XmlUI": ""
}
diff --git a/src/playercards/AllCardsBag.ttslua b/src/playercards/AllCardsBag.ttslua
index e555848d..bbfed2c2 100644
--- a/src/playercards/AllCardsBag.ttslua
+++ b/src/playercards/AllCardsBag.ttslua
@@ -1,3 +1,5 @@
+local guidReferenceApi = require("core/GUIDReferenceApi")
+
local cardIdIndex = { }
local classAndLevelIndex = { }
local basicWeaknessList = { }
@@ -5,6 +7,7 @@ local uniqueWeaknessList = { }
local cycleIndex = { }
local indexingDone = false
+local otherCardsDetected = false
function onLoad()
self.addContextMenuItem("Rebuild Index", startIndexBuild)
@@ -63,6 +66,7 @@ end
function buildIndex()
local cardCount = 0
indexingDone = false
+ otherCardsDetected = false
-- process the allcardsbag itself
for _, cardData in ipairs(self.getData().ContainedObjects) do
@@ -108,6 +112,7 @@ function buildIndex()
end
buildSupplementalIndexes()
+ updatePlayerCardPanel()
indexingDone = true
return 1
end
@@ -174,6 +179,7 @@ function buildSupplementalIndexes()
else
-- track cards without defined cycle (should only be fan-made cards)
cycleName = "other"
+ otherCardsDetected = true
end
-- maybe initialize table
@@ -214,6 +220,12 @@ function cardComparator(id1, id2)
end
end
+-- inform the player card panel about the presence of other cards (no cycle -> fan-made)
+function updatePlayerCardPanel()
+ local panel = guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayerCardPanel")
+ panel.call("createXML", otherCardsDetected)
+end
+
---@return boolean: If true, the bag is currently not indexing and ready to be accessed
function isIndexReady()
if not indexingDone then
@@ -223,14 +235,14 @@ function isIndexReady()
end
-- Returns a specific card from the bag, based on ArkhamDB ID
----@param id string ID of the card to retrieve
+---@param params table ID of the card to retrieve
---@return table: If the indexes are still being constructed, returns an empty table.
-- Otherwise, a single table with the following fields
--- cardData: TTS object data, suitable for spawning the card
--- cardMetadata: Table of parsed metadata
-function getCardById(id)
+-- data: TTS object data, suitable for spawning the card
+-- metadata: Table of parsed metadata
+function getCardById(params)
if not isIndexReady() then return {} end
- return cardIdIndex[id]
+ return cardIdIndex[params.id]
end
-- Returns a list of cards from the bag matching a class and level (0 or upgraded)
@@ -239,8 +251,8 @@ end
-- isUpgraded: true for upgraded cards (Level 1-5), false for Level 0
---@return table: If the indexes are still being constructed, returns an empty table.
-- Otherwise, a list of tables, each with the following fields
--- cardData: TTS object data, suitable for spawning the card
--- cardMetadata: Table of parsed metadata
+-- data: TTS object data, suitable for spawning the card
+-- metadata: Table of parsed metadata
function getCardsByClassAndLevel(params)
if not isIndexReady() then return {} end
@@ -250,7 +262,7 @@ function getCardsByClassAndLevel(params)
else
upgradeKey = "-level0"
end
- return classAndLevelIndex[params.class..upgradeKey]
+ return classAndLevelIndex[params.class .. upgradeKey]
end
-- Returns a list of cards from the bag matching a cycle
@@ -259,8 +271,8 @@ end
-- sortByMetadata: true to sort the table by metadata instead of ID
---@return table: If the indexes are still being constructed, returns an empty table.
-- Otherwise, a list of tables, each with the following fields
--- cardData: TTS object data, suitable for spawning the card
--- cardMetadata: Table of parsed metadata
+-- data: TTS object data, suitable for spawning the card
+-- metadata: Table of parsed metadata
function getCardsByCycle(params)
if not isIndexReady() then return {} end
diff --git a/src/playercards/AllCardsBagApi.ttslua b/src/playercards/AllCardsBagApi.ttslua
index 03bfabe3..e43e693a 100644
--- a/src/playercards/AllCardsBagApi.ttslua
+++ b/src/playercards/AllCardsBagApi.ttslua
@@ -19,16 +19,15 @@ do
---@param id string ID of the card to retrieve
---@return table: If the indexes are still being constructed, returns an empty table.
-- Otherwise, a single table with the following fields
- -- cardData: TTS object data, suitable for spawning the card
- -- cardMetadata: Table of parsed metadata
+ -- data: TTS object data, suitable for spawning the card
+ -- metadata: Table of parsed metadata
AllCardsBagApi.getCardById = function(id)
- return getAllCardsBag().call("getCardById", id)
+ return getAllCardsBag().call("getCardById", { id = id })
end
- -- Gets a random basic weakness from the bag. Once a given ID has been returned
- -- it will be removed from the list and cannot be selected again until a reload
- -- occurs or the indexes are rebuilt, which will refresh the list to include all
- -- weaknesses.
+ -- Gets a random basic weakness from the bag. Once a given ID has been returned it
+ -- will be removed from the list and cannot be selected again until a reload occurs
+ -- or the indexes are rebuilt, which will refresh the list to include all weaknesses.
---@return string: ID of the selected weakness.
AllCardsBagApi.getRandomWeaknessId = function()
return getAllCardsBag().call("getRandomWeaknessId")
@@ -64,8 +63,8 @@ do
---@param upgraded boolean True for upgraded cards (Level 1-5), false for Level 0
---@return table: If the indexes are still being constructed, returns an empty table.
-- Otherwise, a list of tables, each with the following fields
- -- cardData: TTS object data, suitable for spawning the card
- -- cardMetadata: Table of parsed metadata
+ -- data: TTS object data, suitable for spawning the card
+ -- metadata: Table of parsed metadata
AllCardsBagApi.getCardsByClassAndLevel = function(class, upgraded)
return returnCopyOfList(getAllCardsBag().call("getCardsByClassAndLevel", { class = class, upgraded = upgraded }))
end
@@ -75,8 +74,8 @@ do
---@param sortByMetadata boolean If true, sorts the table by metadata instead of ID
---@return table: If the indexes are still being constructed, returns an empty table.
-- Otherwise, a list of tables, each with the following fields
- -- cardData: TTS object data, suitable for spawning the card
- -- cardMetadata: Table of parsed metadata
+ -- data: TTS object data, suitable for spawning the card
+ -- metadata: Table of parsed metadata
AllCardsBagApi.getCardsByCycle = function(cycle, sortByMetadata)
return returnCopyOfList(getAllCardsBag().call("getCardsByCycle", { cycle = cycle, sortByMetadata = sortByMetadata }))
end
diff --git a/src/playercards/PlayerCardPanel.ttslua b/src/playercards/PlayerCardPanel.ttslua
index 90b2e1b6..dcefb509 100644
--- a/src/playercards/PlayerCardPanel.ttslua
+++ b/src/playercards/PlayerCardPanel.ttslua
@@ -333,6 +333,70 @@ function createInvestigatorModeButtons()
})
end
+function createXML(showOtherCardsButton)
+ -- basic XML for the help button
+ local xmlTable = {
+ {
+ tag = "Panel",
+ attributes = {
+ active = "false",
+ id = "helpPanel",
+ position = "-165 -70 -2",
+ rotation = "0 0 180",
+ height = "50",
+ width = "107",
+ color = "#00000099"
+ },
+ children = {
+ tag = "Text",
+ attributes = {
+ id = "helpText",
+ rectAlignment = "MiddleCenter",
+ height = "480",
+ width = "1000",
+ scale = "0.1 0.1 1",
+ fontSize = "66",
+ color = "#F5F5F5",
+ backgroundColor = "#FF0000",
+ alignment = "MiddleLeft",
+ horizontalOverflow = "wrap",
+ text = "• Select a group to place cards\n" ..
+ "• Copy the cards you want for your deck\n" ..
+ "• Select a new group to clear the placed cards and see new ones\n" ..
+ "• Clear to remove all cards"
+ }
+ }
+ }
+ }
+
+ -- add the "Additional Cards" button if cards without cycle were detected
+ if showOtherCardsButton then
+ local otherCardsButtonXml = {
+ tag = "Panel",
+ attributes = {
+ position = "44.25 65.75 -11",
+ rotation = "0 0 180",
+ height = "225",
+ width = "225",
+ scale = "0.1 0.1 1",
+ onClick = "spawnOtherCards"
+ },
+ children = {
+ tag = "Image",
+ attributes = { image = "OtherCards" }
+ }
+ }
+ table.insert(xmlTable, otherCardsButtonXml)
+ end
+ helpVisibleToPlayers = {}
+ self.UI.setXmlTable(xmlTable)
+end
+
+-- click function for the XML button for the additional player cards
+function spawnOtherCards()
+ spawnCycle("Other")
+end
+
function toggleHelp(_, playerColor, _)
if helpVisibleToPlayers[playerColor] then
helpVisibleToPlayers[playerColor] = nil
@@ -612,11 +676,6 @@ function placeClassCards(cardClass, isUpgraded)
end
end
--- called by the XML UI to spawn cards from fan-made camnpaigns
-function spawnOtherCards()
- spawnCycle("Other")
-end
-
-- Spawns the investigator sets and all cards for the given cycle
---@param cycle string Name of a cycle, should match the standard used in card metadata
function spawnCycle(cycle)
@@ -641,20 +700,6 @@ function spawnCycle(cycle)
})
end
--- Comparison function used to sort the class card bag indexes. Sorts by card level, then name, then subname.
-function cardComparator(id1, id2)
- local card1 = cardIdIndex[id1]
- local card2 = cardIdIndex[id2]
-
- if card1.metadata.level ~= card2.metadata.level then
- return card1.metadata.level < card2.metadata.level
- elseif card1.data.Nickname ~= card2.data.Nickname then
- return card1.data.Nickname < card2.data.Nickname
- else
- return card1.data.Description < card2.data.Description
- end
-end
-
function spawnBonded()
prepareToPlaceCards()
spawnBag.spawn({
diff --git a/src/playercards/PlayerCardSpawner.ttslua b/src/playercards/PlayerCardSpawner.ttslua
index 1fbfdc0e..e0501619 100644
--- a/src/playercards/PlayerCardSpawner.ttslua
+++ b/src/playercards/PlayerCardSpawner.ttslua
@@ -16,7 +16,7 @@ Spawner = { }
---@param sort boolean True if this list of cards should be sorted before spawning
---@param callback? function Callback to be called after the card/deck spawns.
Spawner.spawnCards = function(cardList, pos, rot, sort, callback)
- if (sort) then
+ if sort then
table.sort(cardList, Spawner.cardComparator)
end
@@ -25,9 +25,9 @@ Spawner.spawnCards = function(cardList, pos, rot, sort, callback)
local investigatorCards = { }
for _, card in ipairs(cardList) do
- if (card.metadata.type == "Investigator") then
+ if card.metadata.type == "Investigator" then
table.insert(investigatorCards, card)
- elseif (card.metadata.type == "Minicard") then
+ elseif card.metadata.type == "Minicard" then
table.insert(miniCards, card)
else
table.insert(standardCards, card)
@@ -46,7 +46,7 @@ Spawner.spawnCards = function(cardList, pos, rot, sort, callback)
end
Spawner.spawnCardSpread = function(cardList, startPos, maxCols, rot, sort, callback)
- if (sort) then
+ if sort then
table.sort(cardList, Spawner.cardComparator)
end
@@ -201,7 +201,7 @@ end
---@return string id >= startId
Spawner.findNextAvailableId = function(objectTable, startId)
local id = startId
- while (objectTable[id] ~= nil) do
+ while objectTable[id] ~= nil do
id = tostring(tonumber(id) + 1)
end
return id
diff --git a/src/playercards/SpawnBag.ttslua b/src/playercards/SpawnBag.ttslua
index 982d489c..31db3b9d 100644
--- a/src/playercards/SpawnBag.ttslua
+++ b/src/playercards/SpawnBag.ttslua
@@ -85,12 +85,12 @@ do
local cardsToSpawn = {}
for _, cardId in ipairs(spawnSpec.cards) do
- local cardData = allCardsBagApi.getCardById(cardId)
- if cardData ~= nil then
- table.insert(cardsToSpawn, cardData)
+ local card = allCardsBagApi.getCardById(cardId)
+ if card ~= nil then
+ table.insert(cardsToSpawn, card)
end
end
- if (spawnSpec.spread) then
+ if spawnSpec.spread then
Spawner.spawnCardSpread(cardsToSpawn, spawnSpec.globalPos, spawnSpec.spreadCols or 9999, spawnSpec.rotation, false, internal.recordPlacedObject)
else
-- TTS decks come out in reverse order of the cards, reverse the list so the input order stays
diff --git a/xml/playercards/PlayerCardPanel.xml b/xml/playercards/PlayerCardPanel.xml
deleted file mode 100644
index b1f900d1..00000000
--- a/xml/playercards/PlayerCardPanel.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-• Select a group to place cards
-• Copy the cards you want for your deck
-• Select a new group to clear the placed cards and see new ones
-• Clear to remove all cards
-
-
-
-
-
\ No newline at end of file