Update Unified Player Card panel to use relative positioning

Because of the mix of global and relative positioning this ended up being very complex.  Tried to make sure the comments were thorough, but open to any improvement suggestions.
This commit is contained in:
Buhallin 2023-01-06 16:20:09 -08:00
parent ca63ab14c2
commit c33d0386b7
No known key found for this signature in database
GPG Key ID: DB3C362823852294
2 changed files with 133 additions and 60 deletions

View File

@ -31,14 +31,26 @@ local STARTER_DECK_MODE_CARDS_ONLY = "cards"
local FACE_UP_ROTATION = { x = 0, y = 270, z = 0} local FACE_UP_ROTATION = { x = 0, y = 270, z = 0}
local FACE_DOWN_ROTATION = { x = 0, y = 270, z = 180} local FACE_DOWN_ROTATION = { x = 0, y = 270, z = 180}
-- Coordinates to begin laying out cards. These vary based on the cards that are being placed -- ---------- IMPORTANT ----------
-- Coordinates defined below are in global dimensions relative to the panel - DO NOT USE THESE
-- DIRECTLY. Call scalePositions() before use, and reference the variables below
-- Layout width for a single card, in global coordinate space
local CARD_WIDTH = 2.3
-- Coordinates to begin laying out cards. These vary based on the cards that are being placed by
-- considering the width of the cards, number of cards, and desired spread intervals.
-- IMPORTANT! Because of the mix of global card sizes and relative-to-scale positions, the X and Y
-- coordinates on these provide global disances while the Z is local.
local START_POSITIONS = { local START_POSITIONS = {
classCards = Vector(58.384, 1.36, 92.4), classCards = Vector(CARD_WIDTH * 9.5, 2, 1.4),
investigator = Vector(60, 1.36, 86), investigator = Vector(6 * 2.5, 2, 1.3),
cycle = Vector(48, 1.36, 92.4), cycle = Vector(CARD_WIDTH * 9.5, 2, 2.4),
other = Vector(56, 1.36, 86), other = Vector(CARD_WIDTH * 9.5, 2, 1.4),
summonedServitor = Vector(55.5, 1.36, 60.2), randomWeakness = Vector(0, 2, 1.4),
randomWeakness = Vector(55, 1.36, 75) -- Because the card spread is handled by the SpawnBag, we don't know (programatically) where this
-- should be placed. If more customizable cards are added it will need to be moved.
summonedServitor = Vector(CARD_WIDTH * -6.5, 2, 1.7),
} }
-- Shifts to move rows of cards, and groups of rows, as different groupings are laid out -- Shifts to move rows of cards, and groups of rows, as different groupings are laid out
@ -47,14 +59,23 @@ local CARD_GROUP_OFFSET = 2
-- Position offsets for investigator decks in investigator mode, defines the spacing for how the -- Position offsets for investigator decks in investigator mode, defines the spacing for how the
-- rows and columns are laid out -- rows and columns are laid out
local INVESTIGATOR_POSITION_SHIFT_ROW = Vector(-11, 0, 0) local INVESTIGATOR_POSITION_SHIFT_ROW = Vector(0, 0, 11)
local INVESTIGATOR_POSITION_SHIFT_COL = Vector(0, 0, -6) local INVESTIGATOR_POSITION_SHIFT_COL = Vector(-6, 0, 0)
local INVESTIGATOR_MAX_COLS = 6 local INVESTIGATOR_MAX_COLS = 6
-- Positions relative to the minicard to place other stacks. Both signature card piles and starter -- Positions relative to the minicard to place other stacks. Both signature card piles and starter
-- decks use SIGNATURE_OFFSET -- decks use SIGNATURE_OFFSET
local INVESTIGATOR_CARD_OFFSET = Vector(-2.55, 0, 0) local INVESTIGATOR_CARD_OFFSET = Vector(0, 0, 2.55)
local INVESTIGATOR_SIGNATURE_OFFSET = Vector(-5.75, 0, 0) local INVESTIGATOR_SIGNATURE_OFFSET = Vector(0, 0, 5.75)
-- USE THESE! Positions and offset shifts accounting for the scale of the panel
local startPositions
local cardRowOffset
local cardGroupOffset
local investigatorPositionShiftRow
local investigatorPositionShiftCol
local investigatorCardOffset
local investigatorSignatureOffset
local CLASS_LIST = { "Guardian", "Seeker", "Rogue", "Mystic", "Survivor", "Neutral" } local CLASS_LIST = { "Guardian", "Seeker", "Rogue", "Mystic", "Survivor", "Neutral" }
local CYCLE_LIST = { local CYCLE_LIST = {
@ -361,6 +382,35 @@ function updateStarterModeButtons()
createInvestigatorModeButtons() createInvestigatorModeButtons()
end end
-- Clears the table and updates positions based on scale. Should be called before ANY card
-- placement
function prepareToPlaceCards()
deleteAll()
scalePositions()
end
-- Updates the positions based on the current object scale to ensure the relative layout functions
-- properly at different scales.
function scalePositions()
-- Assume scaling is consistent in X and Z dimensions
local scale = 1 / self.getScale().x
startPositions = { }
for key, pos in pairs(START_POSITIONS) do
-- Because a scaled object means a different global size, using global distance for Z results in
-- the cards being closer or farther depending on the scale. Leave the Z values and only scale
-- X and Y
startPositions[key] = Vector(pos)
startPositions[key].x = startPositions[key].x * scale
startPositions[key].y = startPositions[key].y * scale
end
cardRowOffset = CARD_ROW_OFFSET * scale
cardGroupOffset = CARD_GROUP_OFFSET * scale
investigatorPositionShiftRow = Vector(INVESTIGATOR_POSITION_SHIFT_ROW):scale(scale)
investigatorPositionShiftCol = Vector(INVESTIGATOR_POSITION_SHIFT_COL):scale(scale)
investigatorCardOffset = Vector(INVESTIGATOR_CARD_OFFSET):scale(scale)
investigatorSignatureOffset = Vector(INVESTIGATOR_SIGNATURE_OFFSET):scale(scale)
end
-- Deletes all cards currently placed on the table -- Deletes all cards currently placed on the table
function deleteAll() function deleteAll()
spawnBag.recall(true) spawnBag.recall(true)
@ -371,7 +421,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 spawnInvestigatorGroup(groupName) function spawnInvestigatorGroup(groupName)
local starterMode = starterDeckMode == STARTER_DECK_MODE_STARTERS local starterMode = starterDeckMode == STARTER_DECK_MODE_STARTERS
spawnBag.recall(true) prepareToPlaceCards()
Wait.frames(function() Wait.frames(function()
if starterMode then if starterMode then
spawnStarters(groupName) spawnStarters(groupName)
@ -385,32 +435,47 @@ end
-- investigator cards and minicards as well as the signature cards. -- investigator cards and minicards as well as the signature cards.
---@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)
local position = Vector(START_POSITIONS.investigator)
local col = 1
local row = 1
if INVESTIGATOR_GROUPS[groupName] == nil then if INVESTIGATOR_GROUPS[groupName] == nil then
printToAll("No " .. groupName .. " data yet") printToAll("No " .. groupName .. " data yet")
return return
end end
for _, investigatorName in ipairs(INVESTIGATOR_GROUPS[groupName]) do
local col = 1
local row = 1
local investigatorCount = #INVESTIGATOR_GROUPS[groupName]
local position = getInvestigatorRowStartPos(investigatorCount, row)
for i, investigatorName in ipairs(INVESTIGATOR_GROUPS[groupName]) do
for _, spawnSpec in ipairs(buildInvestigatorSpawnSpec( for _, spawnSpec in ipairs(buildInvestigatorSpawnSpec(
investigatorName, INVESTIGATORS[investigatorName], position, false)) do investigatorName, INVESTIGATORS[investigatorName], position, false)) do
spawnBag.spawn(spawnSpec) spawnBag.spawn(spawnSpec)
end end
position:add(INVESTIGATOR_POSITION_SHIFT_COL) position:add(investigatorPositionShiftCol)
col = col + 1 col = col + 1
if col > INVESTIGATOR_MAX_COLS then if col > INVESTIGATOR_MAX_COLS then
col = 1 col = 1
position = Vector(START_POSITIONS.investigator)
position:add(Vector(
INVESTIGATOR_POSITION_SHIFT_ROW.x * row,
INVESTIGATOR_POSITION_SHIFT_ROW.z * row,
INVESTIGATOR_POSITION_SHIFT_ROW.z * row))
row = row + 1 row = row + 1
position = getInvestigatorRowStartPos(investigatorCount, row)
end end
end end
end end
function getInvestigatorRowStartPos(investigatorCount, row)
local rowStart = Vector(startPositions.investigator)
rowStart:add(Vector(
investigatorPositionShiftRow.x * (row - 1),
investigatorPositionShiftRow.y * (row - 1),
investigatorPositionShiftRow.z * (row - 1)))
local investigatorsInRow =
math.min(investigatorCount - INVESTIGATOR_MAX_COLS * (row - 1), INVESTIGATOR_MAX_COLS)
rowStart:add(Vector(
investigatorPositionShiftCol.x * (INVESTIGATOR_MAX_COLS - investigatorsInRow) / 2,
investigatorPositionShiftCol.y * (INVESTIGATOR_MAX_COLS - investigatorsInRow) / 2,
investigatorPositionShiftCol.z * (INVESTIGATOR_MAX_COLS - investigatorsInRow) / 2))
return rowStart
end
-- Creates the spawn spec for the investigator's signature cards. -- Creates the spawn spec for the investigator's signature cards.
---@param investigatorName String. Name of the investigator, matching a key in ---@param investigatorName String. Name of the investigator, matching a key in
--- InvestigatorPanelData --- InvestigatorPanelData
@ -418,12 +483,12 @@ end
--- INVESTIGATORS --- INVESTIGATORS
---@param position Vector. Where to spawn the minicard; investigagor cards will be placed below ---@param position Vector. Where to spawn the minicard; investigagor cards will be placed below
function buildInvestigatorSpawnSpec(investigatorName, investigatorData, position) function buildInvestigatorSpawnSpec(investigatorName, investigatorData, position)
local sigPos = Vector(position):add(INVESTIGATOR_SIGNATURE_OFFSET) local sigPos = Vector(position):add(investigatorSignatureOffset)
local spawns = buildCommonSpawnSpec(investigatorName, investigatorData, position) local spawns = buildCommonSpawnSpec(investigatorName, investigatorData, position)
table.insert(spawns, { table.insert(spawns, {
name = investigatorName.."signatures", name = investigatorName.."signatures",
cards = investigatorData.signatures, cards = investigatorData.signatures,
globalPos = sigPos, globalPos = self.positionToWorld(sigPos),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
}) })
@ -441,18 +506,18 @@ end
---@param oneCardOnly Boolean. If true, will spawn only the first card in the investigator card ---@param oneCardOnly Boolean. If true, will spawn only the first card in the investigator card
--- and minicard lists. Otherwise, spawn them all in a deck --- and minicard lists. Otherwise, spawn them all in a deck
function buildCommonSpawnSpec(investigatorName, investigatorData, position, oneCardOnly) function buildCommonSpawnSpec(investigatorName, investigatorData, position, oneCardOnly)
local cardPos = Vector(position):add(INVESTIGATOR_CARD_OFFSET) local cardPos = Vector(position):add(investigatorCardOffset)
return { return {
{ {
name = investigatorName.."minicards", name = investigatorName.."minicards",
cards = oneCardOnly and { investigatorData.minicards[1] } or investigatorData.minicards, cards = oneCardOnly and { investigatorData.minicards[1] } or investigatorData.minicards,
globalPos = position, globalPos = self.positionToWorld(position),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
}, },
{ {
name = investigatorName.."cards", name = investigatorName.."cards",
cards = oneCardOnly and { investigatorData.cards[1] } or investigatorData.cards, cards = oneCardOnly and { investigatorData.cards[1] } or investigatorData.cards,
globalPos = cardPos, globalPos = self.positionToWorld(cardPos),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
}, },
} }
@ -462,21 +527,18 @@ end
-- investigators in the given group. -- investigators in the given group.
---@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 spawnStarters(groupName) function spawnStarters(groupName)
local position = Vector(START_POSITIONS.investigator)
local col = 1 local col = 1
local row = 1 local row = 1
local investigatorCount = #INVESTIGATOR_GROUPS[groupName]
local position = getInvestigatorRowStartPos(investigatorCount, row)
for _, investigatorName in ipairs(INVESTIGATOR_GROUPS[groupName]) do for _, investigatorName in ipairs(INVESTIGATOR_GROUPS[groupName]) do
spawnStarterDeck(investigatorName, INVESTIGATORS[investigatorName], position) spawnStarterDeck(investigatorName, INVESTIGATORS[investigatorName], position)
position:add(INVESTIGATOR_POSITION_SHIFT_COL) position:add(investigatorPositionShiftCol)
col = col + 1 col = col + 1
if col > INVESTIGATOR_MAX_COLS then if col > INVESTIGATOR_MAX_COLS then
col = 1 col = 1
position = Vector(START_POSITIONS.investigator)
position:add(Vector(
INVESTIGATOR_POSITION_SHIFT_ROW.x * row,
INVESTIGATOR_POSITION_SHIFT_ROW.z * row,
INVESTIGATOR_POSITION_SHIFT_ROW.z * row))
row = row + 1 row = row + 1
position = getInvestigatorRowStartPos(investigatorCount, row)
end end
end end
end end
@ -489,7 +551,7 @@ function spawnStarterDeck(investigatorName, investigatorData, position)
buildCommonSpawnSpec(investigatorName, INVESTIGATORS[investigatorName], position, true)) do buildCommonSpawnSpec(investigatorName, INVESTIGATORS[investigatorName], position, true)) do
spawnBag.spawn(spawnSpec) spawnBag.spawn(spawnSpec)
end end
local deckPos = Vector(position):add(INVESTIGATOR_SIGNATURE_OFFSET) local deckPos = Vector(position):add(investigatorSignatureOffset)
arkhamDb.getDecklist("None", investigatorData.starterDeck, true, false, false, function(slots) arkhamDb.getDecklist("None", investigatorData.starterDeck, true, false, false, function(slots)
local cardIdList = { } local cardIdList = { }
for id, count in pairs(slots) do for id, count in pairs(slots) do
@ -500,7 +562,7 @@ function spawnStarterDeck(investigatorName, investigatorData, position)
spawnBag.spawn({ spawnBag.spawn({
name = investigatorName.."starter", name = investigatorName.."starter",
cards = cardIdList, cards = cardIdList,
globalPos = deckPos, globalPos = self.positionToWorld(deckPos),
rotation = FACE_DOWN_ROTATION rotation = FACE_DOWN_ROTATION
}) })
end) end)
@ -509,7 +571,7 @@ end
---@param cardClass String. Class to place ("Guardian", "Seeker", etc) ---@param cardClass String. Class to place ("Guardian", "Seeker", etc)
---@param isUpgraded Boolean. If true, spawn the Level 1-5 cards. Otherwise, Level 0. ---@param isUpgraded Boolean. If true, spawn the Level 1-5 cards. Otherwise, Level 0.
function spawnClassCards(cardClass, isUpgraded) function spawnClassCards(cardClass, isUpgraded)
spawnBag.recall(true) prepareToPlaceCards()
Wait.frames(function() placeClassCards(cardClass, isUpgraded) end, 2) Wait.frames(function() placeClassCards(cardClass, isUpgraded) end, 2)
end end
@ -538,34 +600,34 @@ function placeClassCards(cardClass, isUpgraded)
table.insert(assetList, cardId) table.insert(assetList, cardId)
end end
end end
local groupPos = Vector(START_POSITIONS.classCards) local groupPos = Vector(startPositions.classCards)
if #skillList > 0 then if #skillList > 0 then
spawnBag.spawn({ spawnBag.spawn({
name = cardClass .. (isUpgraded and "upgraded" or "basic"), name = cardClass .. (isUpgraded and "upgraded" or "basic"),
cards = skillList, cards = skillList,
globalPos = groupPos, globalPos = self.positionToWorld(groupPos),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
spread = true, spread = true,
spreadCols = 20 spreadCols = 20
}) })
groupPos.x = groupPos.x - math.ceil(#skillList / 20) * CARD_ROW_OFFSET - CARD_GROUP_OFFSET groupPos.z = groupPos.z + math.ceil(#skillList / 20) * cardRowOffset + cardGroupOffset
end end
if #eventList > 0 then if #eventList > 0 then
spawnBag.spawn({ spawnBag.spawn({
name = cardClass .. "event" .. (isUpgraded and "upgraded" or "basic"), name = cardClass .. "event" .. (isUpgraded and "upgraded" or "basic"),
cards = eventList, cards = eventList,
globalPos = groupPos, globalPos = self.positionToWorld(groupPos),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
spread = true, spread = true,
spreadCols = 20 spreadCols = 20
}) })
groupPos.x = groupPos.x - math.ceil(#eventList / 20) * CARD_ROW_OFFSET - CARD_GROUP_OFFSET groupPos.z = groupPos.z + math.ceil(#eventList / 20) * cardRowOffset + cardGroupOffset
end end
if #assetList > 0 then if #assetList > 0 then
spawnBag.spawn({ spawnBag.spawn({
name = cardClass .. "asset" .. (isUpgraded and "upgraded" or "basic"), name = cardClass .. "asset" .. (isUpgraded and "upgraded" or "basic"),
cards = assetList, cards = assetList,
globalPos = groupPos, globalPos = self.positionToWorld(groupPos),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
spread = true, spread = true,
spreadCols = 20 spreadCols = 20
@ -576,7 +638,7 @@ end
-- Spawns the investigator sets and all cards for the given cycle -- 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 ---@param cycle String Name of a cycle, should match the standard used in card metadata
function spawnCycle(cycle) function spawnCycle(cycle)
spawnBag.recall(true) prepareToPlaceCards()
spawnInvestigators(cycle) spawnInvestigators(cycle)
local allCardsBag = getObjectFromGUID(ALL_CARDS_BAG_GUID) local allCardsBag = getObjectFromGUID(ALL_CARDS_BAG_GUID)
local indexReady = allCardsBag.call("isIndexReady") local indexReady = allCardsBag.call("isIndexReady")
@ -592,7 +654,7 @@ function spawnCycle(cycle)
spawnBag.spawn({ spawnBag.spawn({
name = "cycle"..cycle, name = "cycle"..cycle,
cards = copiedList, cards = copiedList,
globalPos = START_POSITIONS.cycle, globalPos = self.positionToWorld(startPositions.cycle),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
spread = true, spread = true,
spreadCols = 20 spreadCols = 20
@ -600,11 +662,11 @@ function spawnCycle(cycle)
end end
function spawnBonded() function spawnBonded()
spawnBag.recall(true) prepareToPlaceCards()
spawnBag.spawn({ spawnBag.spawn({
name = "bonded", name = "bonded",
cards = BONDED_CARD_LIST, cards = BONDED_CARD_LIST,
globalPos = START_POSITIONS.classCards, globalPos = self.positionToWorld(startPositions.classCards),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
spread = true, spread = true,
spreadCols = 20 spreadCols = 20
@ -612,11 +674,11 @@ function spawnBonded()
end end
function spawnUpgradeSheets() function spawnUpgradeSheets()
spawnBag.recall(true) prepareToPlaceCards()
spawnBag.spawn({ spawnBag.spawn({
name = "upgradeSheets", name = "upgradeSheets",
cards = UPGRADE_SHEET_LIST, cards = UPGRADE_SHEET_LIST,
globalPos = START_POSITIONS.classCards, globalPos = self.positionToWorld(startPositions.classCards),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
spread = true, spread = true,
spreadCols = 20 spreadCols = 20
@ -624,14 +686,14 @@ function spawnUpgradeSheets()
spawnBag.spawn({ spawnBag.spawn({
name = "servitor", name = "servitor",
cards = { "09080-m" }, cards = { "09080-m" },
globalPos = START_POSITIONS.summonedServitor, globalPos = self.positionToWorld(startPositions.summonedServitor),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
}) })
end end
-- Clears the current cards, and places all basic weaknesses on the table. -- Clears the current cards, and places all basic weaknesses on the table.
function spawnWeaknesses() function spawnWeaknesses()
spawnBag.recall(true) prepareToPlaceCards()
local allCardsBag = getObjectFromGUID(ALL_CARDS_BAG_GUID) local allCardsBag = getObjectFromGUID(ALL_CARDS_BAG_GUID)
local indexReady = allCardsBag.call("isIndexReady") local indexReady = allCardsBag.call("isIndexReady")
if (not indexReady) then if (not indexReady) then
@ -649,29 +711,29 @@ function spawnWeaknesses()
table.insert(otherWeaknessList, id) table.insert(otherWeaknessList, id)
end end
end end
local groupPos = Vector(START_POSITIONS.classCards) local groupPos = Vector(startPositions.classCards)
spawnBag.spawn({ spawnBag.spawn({
name = "basicWeaknesses", name = "basicWeaknesses",
cards = basicWeaknessList, cards = basicWeaknessList,
globalPos = groupPos, globalPos = self.positionToWorld(groupPos),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
spread = true, spread = true,
spreadCols = 20 spreadCols = 20
}) })
groupPos.x = groupPos.x - math.ceil(#basicWeaknessList / 20) * CARD_ROW_OFFSET - CARD_GROUP_OFFSET groupPos.z = groupPos.z + math.ceil(#basicWeaknessList / 20) * cardRowOffset + cardGroupOffset
spawnBag.spawn({ spawnBag.spawn({
name = "evolvedWeaknesses", name = "evolvedWeaknesses",
cards = EVOLVED_WEAKNESSES, cards = EVOLVED_WEAKNESSES,
globalPos = groupPos, globalPos = self.positionToWorld(groupPos),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
spread = true, spread = true,
spreadCols = 20 spreadCols = 20
}) })
groupPos.x = groupPos.x - math.ceil(#EVOLVED_WEAKNESSES / 20) * CARD_ROW_OFFSET - CARD_GROUP_OFFSET groupPos.z = groupPos.z + math.ceil(#EVOLVED_WEAKNESSES / 20) * cardRowOffset + cardGroupOffset
spawnBag.spawn({ spawnBag.spawn({
name = "otherWeaknesses", name = "otherWeaknesses",
cards = otherWeaknessList, cards = otherWeaknessList,
globalPos = groupPos, globalPos = self.positionToWorld(groupPos),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
spread = true, spread = true,
spreadCols = 20 spreadCols = 20
@ -679,7 +741,7 @@ function spawnWeaknesses()
end end
function spawnRandomWeakness() function spawnRandomWeakness()
spawnBag.recall(true) prepareToPlaceCards()
local allCardsBag = getObjectFromGUID(ALL_CARDS_BAG_GUID) local allCardsBag = getObjectFromGUID(ALL_CARDS_BAG_GUID)
local weaknessId = allCardsBag.call("getRandomWeaknessId") local weaknessId = allCardsBag.call("getRandomWeaknessId")
if (weaknessId == nil) then if (weaknessId == nil) then
@ -689,7 +751,7 @@ function spawnRandomWeakness()
spawnBag.spawn({ spawnBag.spawn({
name = "randomWeakness", name = "randomWeakness",
cards = { weaknessId }, cards = { weaknessId },
globalPos = START_POSITIONS.randomWeakness, globalPos = self.positionToWorld(startPositions.randomWeakness),
rotation = FACE_UP_ROTATION, rotation = FACE_UP_ROTATION,
}) })
end end

View File

@ -52,13 +52,24 @@ Spawner.spawnCardSpread = function(cardList, startPos, maxCols, rot, sort, callb
end end
local position = { x = startPos.x, y = startPos.y, z = startPos.z } local position = { x = startPos.x, y = startPos.y, z = startPos.z }
-- Special handle the first row if we have less than a full single row, but only if there's a
-- reasonable max column count. Single-row spreads will send a large value for maxCols
if maxCols < 100 and #cardList < maxCols then
position.z = startPos.z + ((maxCols - #cardList) / 2 * SPREAD_Z_SHIFT)
end
local cardsInRow = 0 local cardsInRow = 0
local rows = 0
for _, card in ipairs(cardList) do for _, card in ipairs(cardList) do
Spawner.spawn({ card }, position, rot, callback) Spawner.spawn({ card }, position, rot, callback)
position.z = position.z + SPREAD_Z_SHIFT position.z = position.z + SPREAD_Z_SHIFT
cardsInRow = cardsInRow + 1 cardsInRow = cardsInRow + 1
if cardsInRow >= maxCols then if cardsInRow >= maxCols then
position.z = startPos.z rows = rows + 1
local cardsForRow = #cardList - rows * maxCols
if cardsForRow > maxCols then
cardsForRow = maxCols
end
position.z = startPos.z + ((maxCols - cardsForRow) / 2 * SPREAD_Z_SHIFT)
position.x = position.x + SPREAD_X_SHIFT position.x = position.x + SPREAD_X_SHIFT
cardsInRow = 0 cardsInRow = 0
end end