improved custom card support
This commit is contained in:
parent
6600610076
commit
c785baa4be
@ -64,51 +64,22 @@ end
|
||||
-- and creating the keyed lookup tables for the cards. This is a coroutine which will
|
||||
-- spread the workload by processing 20 cards before yielding.
|
||||
function buildIndex()
|
||||
local cardCount = 0
|
||||
cardCount = 0
|
||||
indexingDone = false
|
||||
otherCardsDetected = false
|
||||
|
||||
-- process the allcardsbag itself
|
||||
for _, cardData in ipairs(self.getData().ContainedObjects) do
|
||||
addCardToIndex(cardData)
|
||||
cardCount = cardCount + 1
|
||||
if cardCount > 19 then
|
||||
cardCount = 0
|
||||
coroutine.yield(0)
|
||||
end
|
||||
local selfData = self.getData()
|
||||
if selfData.ContainedObjects then
|
||||
processContainedObjects(selfData.ContainedObjects)
|
||||
end
|
||||
|
||||
-- process hotfix bags (and the additional playercards bag)
|
||||
for _, hotfixBag in ipairs(getObjectsWithTag("AllCardsHotfix")) do
|
||||
local hotfixData = hotfixBag.getData()
|
||||
|
||||
-- if the bag is empty, continue with the next bag
|
||||
if not hotfixData.ContainedObjects then
|
||||
goto nextBag
|
||||
if hotfixData.ContainedObjects then
|
||||
processContainedObjects(hotfixData.ContainedObjects, hotfixData.CustomDeck)
|
||||
end
|
||||
|
||||
for _, cardData in ipairs(hotfixData.ContainedObjects) do
|
||||
if cardData.ContainedObjects then
|
||||
-- process containers
|
||||
for _, deepCardData in ipairs(cardData.ContainedObjects) do
|
||||
addCardToIndex(deepCardData)
|
||||
cardCount = cardCount + 1
|
||||
if cardCount > 19 then
|
||||
cardCount = 0
|
||||
coroutine.yield(0)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- process single cards
|
||||
addCardToIndex(cardData)
|
||||
cardCount = cardCount + 1
|
||||
if cardCount > 19 then
|
||||
cardCount = 0
|
||||
coroutine.yield(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
::nextBag::
|
||||
end
|
||||
|
||||
buildSupplementalIndexes()
|
||||
@ -117,6 +88,43 @@ function buildIndex()
|
||||
return 1
|
||||
end
|
||||
|
||||
-- Processes the contained objects for cards to add to the index
|
||||
function processContainedObjects(containedObjects, customDeck)
|
||||
for _, objData in ipairs(containedObjects) do
|
||||
if objData.ContainedObjects then
|
||||
-- recursively process nested containers
|
||||
processContainedObjects(objData.ContainedObjects, objData.CustomDeck)
|
||||
else
|
||||
-- we might need to fix the "CustomDeck" entry for cards inside decks since TTS doesn't update it while they are in bags
|
||||
if customDeck then
|
||||
local wantedCustomDeckIdStr = tostring(objData.CardID):sub(1, -3)
|
||||
local presentCustomDeckIdNum = next(objData.CustomDeck)
|
||||
|
||||
-- type conversion (TTS seems to store these as strings, but reads them as numbers)
|
||||
local wantedCustomDeckIdNum = tonumber(wantedCustomDeckIdStr)
|
||||
|
||||
if wantedCustomDeckIdNum ~= presentCustomDeckIdNum then
|
||||
if customDeck[wantedCustomDeckIdNum] then
|
||||
objData.CustomDeck = {}
|
||||
objData.CustomDeck[wantedCustomDeckIdStr] = customDeck[wantedCustomDeckIdNum]
|
||||
log("Correct CustomDeckData for " .. objData.Nickname)
|
||||
else
|
||||
log("Could not correct CustomDeckData for " .. objData.Nickname)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
addCardToIndex(objData)
|
||||
cardCount = cardCount + 1
|
||||
if cardCount > 19 then
|
||||
cardCount = 0
|
||||
coroutine.yield(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Adds a card to any indexes it should be a part of, based on its metadata
|
||||
---@param cardData table TTS object data for the card
|
||||
function addCardToIndex(cardData)
|
||||
@ -178,6 +186,17 @@ function buildSupplementalIndexes()
|
||||
|
||||
-- add to cycle index
|
||||
local cycleName = card.metadata.cycle
|
||||
|
||||
-- if this is a minicard without cycle, check the parent card for cycle data
|
||||
if not cycleName and card.metadata.type == "Minicard" then
|
||||
-- TO-DO: use a more robust detection instead of 5 characters
|
||||
local parentId = string.match(card.metadata.id, ".....")
|
||||
local parent = cardIdIndex[parentId]
|
||||
if parent and parent.metadata.cycle then
|
||||
cycleName = parent.metadata.cycle
|
||||
end
|
||||
end
|
||||
|
||||
if cycleName then
|
||||
cycleName = string.lower(cycleName)
|
||||
|
||||
@ -189,12 +208,9 @@ function buildSupplementalIndexes()
|
||||
else
|
||||
-- track cards without defined cycle (should only be fan-made cards)
|
||||
cycleName = "other"
|
||||
log(card.metadata.id)
|
||||
otherCardsDetected = true
|
||||
end
|
||||
|
||||
-- only add official cards with level to cycle index, but all fan-made cards
|
||||
if card.metadata.level or cycleName == "other" then
|
||||
-- maybe initialize table
|
||||
if cycleIndex[cycleName] == nil then
|
||||
cycleIndex[cycleName] = {}
|
||||
@ -202,7 +218,6 @@ function buildSupplementalIndexes()
|
||||
table.insert(cycleIndex[cycleName], card.metadata.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- sort class and level indices
|
||||
for _, indexTable in pairs(classAndLevelIndex) do
|
||||
@ -278,8 +293,9 @@ end
|
||||
|
||||
-- Returns a list of cards from the bag matching a cycle
|
||||
---@param params table
|
||||
-- cycle: String cycle to retrieve ("The Scarlet Keys" etc.)
|
||||
-- sortByMetadata: true to sort the table by metadata instead of ID
|
||||
-- cycle: string Name of the cycle to retrieve ("The Scarlet Keys" etc.)
|
||||
-- sortByMetadata: boolean If true, sorts the table by metadata instead of ID
|
||||
-- includeNoLevelCards: boolean If true, includes cards without level
|
||||
---@return table: If the indexes are still being constructed, returns an empty table.
|
||||
-- Otherwise, a list of tables, each with the following fields
|
||||
-- data: TTS object data, suitable for spawning the card
|
||||
@ -288,17 +304,18 @@ function getCardsByCycle(params)
|
||||
if not isIndexReady() then return {} end
|
||||
|
||||
local cycleData = cycleIndex[string.lower(params.cycle)] or {}
|
||||
if not params.sortByMetadata then
|
||||
return cycleData
|
||||
|
||||
-- create a copy of the data to not change the source
|
||||
local cardList = {}
|
||||
for _, id in ipairs(cycleData) do
|
||||
-- only include cards without level if requested
|
||||
if cardIdIndex[id].metadata.level or params.includeNoLevelCards then
|
||||
table.insert(cardList, id)
|
||||
end
|
||||
end
|
||||
|
||||
-- sort list by metadata (useful for custom cards without proper IDs)
|
||||
local cardList = {}
|
||||
for _, id in ipairs(cycleData) do
|
||||
table.insert(cardList, id)
|
||||
end
|
||||
|
||||
if #cardList > 0 then
|
||||
if params.sortByMetadata and #cardList > 0 then
|
||||
table.sort(cardList, metadataSortFunction)
|
||||
end
|
||||
return cardList
|
||||
@ -340,13 +357,15 @@ end
|
||||
|
||||
-- helper function to calculate the class value for sorting from the "|" separated string
|
||||
function getClassValueFromString(s)
|
||||
s = s or "NoClass"
|
||||
local classValueList = {
|
||||
Guardian = 1,
|
||||
Seeker = 2,
|
||||
Rogue = 3,
|
||||
Mystic = 4,
|
||||
Survivor = 5,
|
||||
Neutral = 6
|
||||
Neutral = 6,
|
||||
NoClass = 7
|
||||
}
|
||||
local classValue = 0
|
||||
for str in s:gmatch("([^|]+)") do
|
||||
|
@ -77,12 +77,17 @@ do
|
||||
-- Returns a list of cards from the bag matching a cycle
|
||||
---@param cycle string Cycle to retrieve ("The Scarlet Keys" etc.)
|
||||
---@param sortByMetadata boolean If true, sorts the table by metadata instead of ID
|
||||
---@param includeNoLevelCards boolean If true, includes cards without level
|
||||
---@return table: If the indexes are still being constructed, returns an empty table.
|
||||
-- Otherwise, a list of tables, each with the following fields
|
||||
-- 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 }))
|
||||
AllCardsBagApi.getCardsByCycle = function(cycle, sortByMetadata, includeNoLevelCards)
|
||||
return returnCopyOfList(getAllCardsBag().call("getCardsByCycle", {
|
||||
cycle = cycle,
|
||||
sortByMetadata = sortByMetadata,
|
||||
includeNoLevelCards = includeNoLevelCards
|
||||
}))
|
||||
end
|
||||
|
||||
-- Constructs a list of available basic weaknesses by starting with the full pool of basic
|
||||
|
@ -493,7 +493,9 @@ end
|
||||
---@param groupName string Name of the group to spawn, matching a key in InvestigatorPanelData
|
||||
function spawnInvestigators(groupName)
|
||||
if INVESTIGATOR_GROUPS[groupName] == nil then
|
||||
printToAll("No investigator data for " .. groupName .. " yet")
|
||||
if groupName ~= "Other" then
|
||||
printToAll("No investigator data for '" .. groupName .. "' yet")
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
@ -693,15 +695,17 @@ function spawnCycle(cycle)
|
||||
prepareToPlaceCards()
|
||||
spawnInvestigators(cycle)
|
||||
|
||||
-- sort custom cards
|
||||
-- sort custom cards and include cards without level
|
||||
local sortByMetadata = false
|
||||
local includeNoLevelCards = false
|
||||
if cycle == "Other" then
|
||||
sortByMetadata = true
|
||||
includeNoLevelCards = true
|
||||
end
|
||||
|
||||
spawnBag.spawn({
|
||||
name = "cycle" .. cycle,
|
||||
cards = allCardsBagApi.getCardsByCycle(cycle, sortByMetadata),
|
||||
cards = allCardsBagApi.getCardsByCycle(cycle, sortByMetadata, includeNoLevelCards),
|
||||
globalPos = self.positionToWorld(startPositions.cycle),
|
||||
rotation = FACE_UP_ROTATION,
|
||||
spread = true,
|
||||
|
Loading…
Reference in New Issue
Block a user