added sorting for custom cards

This commit is contained in:
Chr1Z93 2024-05-25 00:40:18 +02:00
parent afff593874
commit 5b38ea1c02
3 changed files with 111 additions and 30 deletions

View File

@ -170,7 +170,12 @@ function buildSupplementalIndexes()
-- override cycle name for night of the zealot -- override cycle name for night of the zealot
cycleName = cycleName:gsub("the night of the zealot", "core") cycleName = cycleName:gsub("the night of the zealot", "core")
else
-- track cards without defined cycle (should only be fan-made cards)
cycleName = "other"
end
-- maybe initialize table
if cycleIndex[cycleName] == nil then if cycleIndex[cycleName] == nil then
cycleIndex[cycleName] = { } cycleIndex[cycleName] = { }
end end
@ -178,7 +183,6 @@ function buildSupplementalIndexes()
end end
end end
end end
end
-- sort class and level indices -- sort class and level indices
for _, indexTable in pairs(classAndLevelIndex) do for _, indexTable in pairs(classAndLevelIndex) do
@ -240,17 +244,76 @@ function getCardsByClassAndLevel(params)
if not isIndexReady() then return {} end if not isIndexReady() then return {} end
local upgradeKey local upgradeKey
if (params.upgraded) then if params.upgraded then
upgradeKey = "-upgrade" upgradeKey = "-upgrade"
else else
upgradeKey = "-level0" upgradeKey = "-level0"
end end
return classAndLevelIndex[params.class..upgradeKey]; return classAndLevelIndex[params.class..upgradeKey]
end end
function getCardsByCycle(cycleName) function getCardsByCycle(params)
if not isIndexReady() then return {} end if not isIndexReady() then return {} end
return cycleIndex[string.lower(cycleName)]
if not params.sortByMetadata then
return cycleIndex[string.lower(params.cycle)]
end
-- sort list by metadata (useful for custom cards without proper IDs)
local cardList = {}
for _, id in ipairs(cycleIndex[string.lower(params.cycle)]) do
table.insert(cardList, id)
end
table.sort(cardList, metadataSortFunction)
return cardList
end
-- sorts cards by metadata: class, type, level, name and then description
function metadataSortFunction(id1, id2)
local card1 = cardIdIndex[id1]
local card2 = cardIdIndex[id2]
-- extract class per card
local classValue1 = getClassValueFromString(card1.metadata.class)
local classValue2 = getClassValueFromString(card2.metadata.class)
-- conversion tables to simplify type sorting
local typeConversion = {
Asset = 1,
Event = 2,
Skill = 3
}
if classValue1 ~= classValue2 then
return classValue1 < classValue2
elseif typeConversion[card1.metadata.type] ~= typeConversion[card2.metadata.type] then
return typeConversion[card1.metadata.type] < typeConversion[card2.metadata.type]
elseif 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
-- helper function to calculate the class value for sorting from the "|" separated string
function getClassValueFromString(s)
local classValueList = {
Guardian = 1,
Seeker = 2,
Rogue = 3,
Mystic = 4,
Survivor = 5,
Neutral = 6
}
local classValue = 0
for str in s:gmatch("([^|]+)") do
-- this sorts multiclass cards
classValue = classValue * 10 + classValueList[str]
end
return classValue
end end
-- Searches the bag for cards which match the given name and returns a list. Note that this is -- Searches the bag for cards which match the given name and returns a list. Note that this is
@ -283,7 +346,7 @@ end
-- Return: String ID of the selected weakness. -- Return: String ID of the selected weakness.
function getRandomWeaknessId() function getRandomWeaknessId()
local availableWeaknesses = buildAvailableWeaknesses() local availableWeaknesses = buildAvailableWeaknesses()
if (#availableWeaknesses > 0) then if #availableWeaknesses > 0 then
return availableWeaknesses[math.random(#availableWeaknesses)] return availableWeaknesses[math.random(#availableWeaknesses)]
end end
end end
@ -295,14 +358,12 @@ function buildAvailableWeaknesses()
local weaknessesInPlay = { } local weaknessesInPlay = { }
local allObjects = getAllObjects() local allObjects = getAllObjects()
for _, object in ipairs(allObjects) do for _, object in ipairs(allObjects) do
if (object.name == "Deck") then if object.type == "Deck" then
for _, cardData in ipairs(object.getData().ContainedObjects) do for _, cardData in ipairs(object.getData().ContainedObjects) do
local cardMetadata = JSON.decode(cardData.GMNotes) incrementWeaknessCount(weaknessesInPlay, JSON.decode(cardData.GMNotes))
incrementWeaknessCount(weaknessesInPlay, cardMetadata)
end end
elseif (object.name == "Card") then elseif object.type == "Card" then
local cardMetadata = JSON.decode(object.getGMNotes()) incrementWeaknessCount(weaknessesInPlay, JSON.decode(object.getGMNotes()))
incrementWeaknessCount(weaknessesInPlay, cardMetadata)
end end
end end
@ -327,8 +388,8 @@ end
-- Helper function that adds one to the table entry for the number of weaknesses in play -- Helper function that adds one to the table entry for the number of weaknesses in play
function incrementWeaknessCount(table, cardMetadata) function incrementWeaknessCount(table, cardMetadata)
if (isBasicWeakness(cardMetadata)) then if isBasicWeakness(cardMetadata) then
if (table[cardMetadata.id] == nil) then if table[cardMetadata.id] == nil then
table[cardMetadata.id] = 1 table[cardMetadata.id] = 1
else else
table[cardMetadata.id] = table[cardMetadata.id] + 1 table[cardMetadata.id] = table[cardMetadata.id] + 1

View File

@ -70,8 +70,8 @@ do
return returnCopyOfList(getAllCardsBag().call("getCardsByClassAndLevel", { class = class, upgraded = upgraded })) return returnCopyOfList(getAllCardsBag().call("getCardsByClassAndLevel", { class = class, upgraded = upgraded }))
end end
AllCardsBagApi.getCardsByCycle = function(cycle) AllCardsBagApi.getCardsByCycle = function(cycle, sortByMetadata)
return returnCopyOfList(getAllCardsBag().call("getCardsByCycle", cycle)) return returnCopyOfList(getAllCardsBag().call("getCardsByCycle", { cycle = cycle, sortByMetadata = sortByMetadata }))
end end
AllCardsBagApi.getUniqueWeaknesses = function() AllCardsBagApi.getUniqueWeaknesses = function()

View File

@ -425,7 +425,7 @@ end
---@param groupName string Name of the group to spawn, matching a key in InvestigatorPanelData ---@param groupName string Name of the group to spawn, matching a key in InvestigatorPanelData
function spawnInvestigators(groupName) function spawnInvestigators(groupName)
if INVESTIGATOR_GROUPS[groupName] == nil then if INVESTIGATOR_GROUPS[groupName] == nil then
printToAll("No " .. groupName .. " data yet") printToAll("No investigator data for " .. groupName .. " yet")
return return
end end
@ -434,7 +434,7 @@ function spawnInvestigators(groupName)
local investigatorCount = #INVESTIGATOR_GROUPS[groupName] local investigatorCount = #INVESTIGATOR_GROUPS[groupName]
local position = getInvestigatorRowStartPos(investigatorCount, row) local position = getInvestigatorRowStartPos(investigatorCount, row)
for i, investigatorName in ipairs(INVESTIGATOR_GROUPS[groupName]) do for _, investigatorName in ipairs(INVESTIGATOR_GROUPS[groupName]) do
for _, spawnSpec in ipairs(buildInvestigatorSpawnSpec(investigatorName, INVESTIGATORS[investigatorName], position)) do for _, spawnSpec in ipairs(buildInvestigatorSpawnSpec(investigatorName, INVESTIGATORS[investigatorName], position)) do
spawnBag.spawn(spawnSpec) spawnBag.spawn(spawnSpec)
end end
@ -625,9 +625,15 @@ function spawnCycle(cycle)
prepareToPlaceCards() prepareToPlaceCards()
spawnInvestigators(cycle) spawnInvestigators(cycle)
-- sort custom cards
local sortByMetadata = false
if cycle == "Other" then
sortByMetadata = true
end
spawnBag.spawn({ spawnBag.spawn({
name = "cycle" .. cycle, name = "cycle" .. cycle,
cards = allCardsBagApi.getCardsByCycle(cycle), cards = allCardsBagApi.getCardsByCycle(cycle, sortByMetadata),
globalPos = self.positionToWorld(startPositions.cycle), globalPos = self.positionToWorld(startPositions.cycle),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
spread = true, spread = true,
@ -635,6 +641,20 @@ function spawnCycle(cycle)
}) })
end 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() function spawnBonded()
prepareToPlaceCards() prepareToPlaceCards()
spawnBag.spawn({ spawnBag.spawn({