foundation for custom cards
This commit is contained in:
parent
831a4fd4c9
commit
afff593874
@ -150,11 +150,8 @@ end
|
||||
|
||||
-- Event handlers for deck ID change
|
||||
function redDeckChanged(_, _, inputValue) redDeckId = inputValue end
|
||||
|
||||
function orangeDeckChanged(_, _, inputValue) orangeDeckId = inputValue end
|
||||
|
||||
function whiteDeckChanged(_, _, inputValue) whiteDeckId = inputValue end
|
||||
|
||||
function greenDeckChanged(_, _, inputValue) greenDeckId = inputValue end
|
||||
|
||||
-- Event handlers for toggle buttons
|
||||
@ -174,14 +171,7 @@ function loadInvestigatorsChanged()
|
||||
end
|
||||
|
||||
function loadDecks()
|
||||
-- testLoadLotsOfDecks()
|
||||
-- Method in DeckImporterMain, visible due to inclusion
|
||||
|
||||
local indexReady = allCardsBagApi.isIndexReady()
|
||||
if (not indexReady) then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
return
|
||||
end
|
||||
if not allCardsBagApi.isIndexReady() then return end
|
||||
if (redDeckId ~= nil and redDeckId ~= "") then
|
||||
buildDeck("Red", redDeckId)
|
||||
end
|
||||
|
@ -18,7 +18,7 @@ end
|
||||
-- called once indexing is complete it means the hotfix bag has been added
|
||||
-- later, and we should rebuild the index to integrate the hotfix bag.
|
||||
function rebuildIndexForHotfix()
|
||||
if (indexingDone) then
|
||||
if indexingDone then
|
||||
startIndexBuild()
|
||||
end
|
||||
end
|
||||
@ -210,6 +210,9 @@ function cardComparator(id1, id2)
|
||||
end
|
||||
|
||||
function isIndexReady()
|
||||
if not indexingDone then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
end
|
||||
return indexingDone
|
||||
end
|
||||
|
||||
@ -221,10 +224,7 @@ end
|
||||
-- cardData: TTS object data, suitable for spawning the card
|
||||
-- cardMetadata: Table of parsed metadata
|
||||
function getCardById(params)
|
||||
if (not indexingDone) then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
return { }
|
||||
end
|
||||
if not isIndexReady() then return {} end
|
||||
return cardIdIndex[params.id]
|
||||
end
|
||||
|
||||
@ -237,10 +237,8 @@ end
|
||||
-- cardData: TTS object data, suitable for spawning the card
|
||||
-- cardMetadata: Table of parsed metadata
|
||||
function getCardsByClassAndLevel(params)
|
||||
if (not indexingDone) then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
return { }
|
||||
end
|
||||
if not isIndexReady() then return {} end
|
||||
|
||||
local upgradeKey
|
||||
if (params.upgraded) then
|
||||
upgradeKey = "-upgrade"
|
||||
@ -251,10 +249,7 @@ function getCardsByClassAndLevel(params)
|
||||
end
|
||||
|
||||
function getCardsByCycle(cycleName)
|
||||
if (not indexingDone) then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
return { }
|
||||
end
|
||||
if not isIndexReady() then return {} end
|
||||
return cycleIndex[string.lower(cycleName)]
|
||||
end
|
||||
|
||||
|
@ -6,6 +6,14 @@ do
|
||||
return guidReferenceApi.getObjectByOwnerAndType("Mythos", "AllCardsBag")
|
||||
end
|
||||
|
||||
local function returnCopyOfList(data)
|
||||
local copiedList = {}
|
||||
for _, id in ipairs(data) do
|
||||
table.insert(copiedList, id)
|
||||
end
|
||||
return copiedList
|
||||
end
|
||||
|
||||
-- Returns a specific card from the bag, based on ArkhamDB ID
|
||||
---@param id table String ID of the card to retrieve
|
||||
---@return table table
|
||||
@ -36,7 +44,7 @@ do
|
||||
-- called once indexing is complete it means the hotfix bag has been added
|
||||
-- later, and we should rebuild the index to integrate the hotfix bag.
|
||||
AllCardsBagApi.rebuildIndexForHotfix = function()
|
||||
return getAllCardsBag().call("rebuildIndexForHotfix")
|
||||
getAllCardsBag().call("rebuildIndexForHotfix")
|
||||
end
|
||||
|
||||
-- Searches the bag for cards which match the given name and returns a list. Note that this is
|
||||
@ -44,7 +52,7 @@ do
|
||||
---@param name string or string fragment to search for names
|
||||
---@param exact boolean Whether the name match should be exact
|
||||
AllCardsBagApi.getCardsByName = function(name, exact)
|
||||
return getAllCardsBag().call("getCardsByName", {name = name, exact = exact})
|
||||
return returnCopyOfList(getAllCardsBag().call("getCardsByName", { name = name, exact = exact }))
|
||||
end
|
||||
|
||||
AllCardsBagApi.isBagPresent = function()
|
||||
@ -59,15 +67,15 @@ do
|
||||
-- cardData: TTS object data, suitable for spawning the card
|
||||
-- cardMetadata: Table of parsed metadata
|
||||
AllCardsBagApi.getCardsByClassAndLevel = function(class, upgraded)
|
||||
return getAllCardsBag().call("getCardsByClassAndLevel", {class = class, upgraded = upgraded})
|
||||
return returnCopyOfList(getAllCardsBag().call("getCardsByClassAndLevel", { class = class, upgraded = upgraded }))
|
||||
end
|
||||
|
||||
AllCardsBagApi.getCardsByCycle = function(cycle)
|
||||
return getAllCardsBag().call("getCardsByCycle", cycle)
|
||||
return returnCopyOfList(getAllCardsBag().call("getCardsByCycle", cycle))
|
||||
end
|
||||
|
||||
AllCardsBagApi.getUniqueWeaknesses = function()
|
||||
return getAllCardsBag().call("getUniqueWeaknesses")
|
||||
return returnCopyOfList(getAllCardsBag().call("getUniqueWeaknesses"))
|
||||
end
|
||||
|
||||
return AllCardsBagApi
|
||||
|
@ -26,8 +26,6 @@ local CYCLE_BUTTONS_Z_OFFSET = 0.2665
|
||||
|
||||
local STARTER_DECK_MODE_SELECTED_COLOR = { 0.2, 0.2, 0.2, 0.8 }
|
||||
local TRANSPARENT = { 0, 0, 0, 0 }
|
||||
local STARTER_DECK_MODE_STARTERS = "starters"
|
||||
local STARTER_DECK_MODE_CARDS_ONLY = "cards"
|
||||
|
||||
local FACE_UP_ROTATION = { x = 0, y = 270, z = 0 }
|
||||
local FACE_DOWN_ROTATION = { x = 0, y = 270, z = 180 }
|
||||
@ -78,7 +76,14 @@ 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 = {
|
||||
"Core",
|
||||
"The Dunwich Legacy",
|
||||
@ -94,8 +99,7 @@ local CYCLE_LIST = {
|
||||
}
|
||||
|
||||
local excludedNonBasicWeaknesses
|
||||
|
||||
local starterDeckMode = STARTER_DECK_MODE_CARDS_ONLY
|
||||
local spawnStarterDecks = false
|
||||
local helpVisibleToPlayers = {}
|
||||
|
||||
function onSave()
|
||||
@ -274,9 +278,8 @@ function createCycleButtons()
|
||||
if rowCount == 3 then
|
||||
-- Account for two centered buttons on the final row
|
||||
buttonPos.x = buttonPos.x + CYCLE_BUTTONS_X_OFFSET / 2
|
||||
--[[ Account for centered button on the final row
|
||||
buttonPos.x = buttonPos.x + CYCLE_BUTTONS_X_OFFSET
|
||||
]]
|
||||
-- Account for centered button on the final row
|
||||
-- buttonPos.x = buttonPos.x + CYCLE_BUTTONS_X_OFFSET
|
||||
end
|
||||
else
|
||||
buttonPos.x = buttonPos.x + CYCLE_BUTTONS_X_OFFSET
|
||||
@ -297,8 +300,6 @@ function createClearButton()
|
||||
end
|
||||
|
||||
function createInvestigatorModeButtons()
|
||||
local starterMode = starterDeckMode == STARTER_DECK_MODE_STARTERS
|
||||
|
||||
self.createButton({
|
||||
function_owner = self,
|
||||
click_function = "setCardsOnlyMode",
|
||||
@ -306,18 +307,18 @@ function createInvestigatorModeButtons()
|
||||
height = 170,
|
||||
width = 760,
|
||||
scale = Vector(0.25, 1, 0.25),
|
||||
color = starterMode and TRANSPARENT or STARTER_DECK_MODE_SELECTED_COLOR
|
||||
color = spawnStarterDecks and TRANSPARENT or STARTER_DECK_MODE_SELECTED_COLOR
|
||||
})
|
||||
self.createButton({
|
||||
function_owner = self,
|
||||
click_function = "setStarterDeckMode",
|
||||
click_function = "setspawnStarterDecks",
|
||||
position = Vector(0.66, 0.1, -0.322),
|
||||
height = 170,
|
||||
width = 760,
|
||||
scale = Vector(0.25, 1, 0.25),
|
||||
color = starterMode and STARTER_DECK_MODE_SELECTED_COLOR or TRANSPARENT
|
||||
color = spawnStarterDecks and STARTER_DECK_MODE_SELECTED_COLOR or TRANSPARENT
|
||||
})
|
||||
local checkX = starterMode and 0.52 or 0.11
|
||||
local checkX = spawnStarterDecks and 0.52 or 0.11
|
||||
self.createButton({
|
||||
function_owner = self,
|
||||
label = "✓",
|
||||
@ -325,7 +326,8 @@ function createInvestigatorModeButtons()
|
||||
position = Vector(checkX, 0.11, -0.317),
|
||||
height = 0,
|
||||
width = 0,
|
||||
scale = Vector(0.3, 1, 0.3),
|
||||
font_size = 300,
|
||||
scale = Vector(0.1, 1, 0.1),
|
||||
font_color = { 0, 0, 0 },
|
||||
color = { 1, 1, 1 }
|
||||
})
|
||||
@ -354,13 +356,13 @@ function updateHelpVisibility()
|
||||
self.UI.setAttribute("helpPanel", "active", string.len(visibility) > 0)
|
||||
end
|
||||
|
||||
function setStarterDeckMode()
|
||||
starterDeckMode = STARTER_DECK_MODE_STARTERS
|
||||
function setspawnStarterDecks()
|
||||
spawnStarterDecks = true
|
||||
updateStarterModeButtons()
|
||||
end
|
||||
|
||||
function setCardsOnlyMode()
|
||||
starterDeckMode = STARTER_DECK_MODE_CARDS_ONLY
|
||||
spawnStarterDecks = false
|
||||
updateStarterModeButtons()
|
||||
end
|
||||
|
||||
@ -405,14 +407,12 @@ function deleteAll()
|
||||
spawnBag.recall(true)
|
||||
end
|
||||
|
||||
-- Spawn an investigator group, based on the current UI setting for either investigators or starter
|
||||
-- decks.
|
||||
-- Spawn an investigator group, based on the current UI setting for either investigators or starter decks
|
||||
---@param groupName string Name of the group to spawn, matching a key in InvestigatorPanelData
|
||||
function spawnInvestigatorGroup(groupName)
|
||||
local starterMode = starterDeckMode == STARTER_DECK_MODE_STARTERS
|
||||
prepareToPlaceCards()
|
||||
Wait.frames(function()
|
||||
if starterMode then
|
||||
if spawnStarterDecks then
|
||||
spawnStarters(groupName)
|
||||
else
|
||||
spawnInvestigators(groupName)
|
||||
@ -547,6 +547,7 @@ function spawnStarterDeck(investigatorName, investigatorData, position)
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
-- Clears the currently placed cards, then places cards for the given class and level spread
|
||||
---@param cardClass string Class to place ("Guardian", "Seeker", etc)
|
||||
---@param isUpgraded boolean If true, spawn the Level 1-5 cards. Otherwise, Level 0.
|
||||
@ -559,11 +560,8 @@ end
|
||||
---@param cardClass string Class to place ("Guardian", "Seeker", etc)
|
||||
---@param isUpgraded boolean If true, spawn the Level 1-5 cards. Otherwise, Level 0.
|
||||
function placeClassCards(cardClass, isUpgraded)
|
||||
local indexReady = allCardsBagApi.isIndexReady()
|
||||
if (not indexReady) then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
return
|
||||
end
|
||||
if not allCardsBagApi.isIndexReady() then return end
|
||||
|
||||
local cardIdList = allCardsBagApi.getCardsByClassAndLevel(cardClass, isUpgraded)
|
||||
|
||||
local skillList = {}
|
||||
@ -614,24 +612,22 @@ 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)
|
||||
if not allCardsBagApi.isIndexReady() then return end
|
||||
|
||||
prepareToPlaceCards()
|
||||
spawnInvestigators(cycle)
|
||||
local indexReady = allCardsBagApi.isIndexReady()
|
||||
if (not indexReady) then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
return
|
||||
end
|
||||
local cycleCardList = allCardsBagApi.getCardsByCycle(cycle)
|
||||
local copiedList = { }
|
||||
for i, id in ipairs(cycleCardList) do
|
||||
copiedList[i] = id
|
||||
end
|
||||
|
||||
spawnBag.spawn({
|
||||
name = "cycle" .. cycle,
|
||||
cards = copiedList,
|
||||
cards = allCardsBagApi.getCardsByCycle(cycle),
|
||||
globalPos = self.positionToWorld(startPositions.cycle),
|
||||
rotation = FACE_UP_ROTATION,
|
||||
spread = true,
|
||||
@ -671,16 +667,13 @@ end
|
||||
|
||||
-- Clears the current cards, and places all basic weaknesses on the table.
|
||||
function spawnWeaknesses()
|
||||
if not allCardsBagApi.isIndexReady() then return end
|
||||
|
||||
prepareToPlaceCards()
|
||||
local indexReady = allCardsBagApi.isIndexReady()
|
||||
if (not indexReady) then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
return
|
||||
end
|
||||
local weaknessIdList = allCardsBagApi.getUniqueWeaknesses()
|
||||
|
||||
local basicWeaknessList = {}
|
||||
local otherWeaknessList = {}
|
||||
for i, id in ipairs(weaknessIdList) do
|
||||
for _, id in ipairs(allCardsBagApi.getUniqueWeaknesses()) do
|
||||
local cardMetadata = allCardsBagApi.getCardById(id).metadata
|
||||
if cardMetadata.basicWeaknessCount ~= nil and cardMetadata.basicWeaknessCount > 0 then
|
||||
table.insert(basicWeaknessList, id)
|
||||
|
@ -81,21 +81,13 @@ do
|
||||
-- Places the given spawnSpec on the table. See comment at the start of the file for spawnSpec table data and examples
|
||||
SpawnBag.spawn = function(spawnSpec)
|
||||
-- Limit to one placement at a time
|
||||
if (placedSpecs[spawnSpec.name]) then
|
||||
return
|
||||
end
|
||||
if (spawnSpec == nil) then
|
||||
-- TODO: error here
|
||||
return
|
||||
end
|
||||
if placedSpecs[spawnSpec.name] or spawnSpec == nil then return end
|
||||
|
||||
local cardsToSpawn = {}
|
||||
local cardList = spawnSpec.cards
|
||||
for _, cardId in ipairs(cardList) do
|
||||
for _, cardId in ipairs(spawnSpec.cards) do
|
||||
local cardData = allCardsBagApi.getCardById(cardId)
|
||||
if (cardData ~= nil) then
|
||||
if cardData ~= nil then
|
||||
table.insert(cardsToSpawn, cardData)
|
||||
else
|
||||
-- TODO: error here
|
||||
end
|
||||
end
|
||||
if (spawnSpec.spread) then
|
||||
@ -120,14 +112,13 @@ do
|
||||
internal.recallSpawned()
|
||||
end
|
||||
|
||||
-- We've recalled everything we can, some cards may have been moved out of the
|
||||
-- card area. Just reset at this point.
|
||||
-- We've recalled everything we can, some cards may have been moved out of the card area. Just reset at this point.
|
||||
placedSpecs = {}
|
||||
placedObjectGuids = {}
|
||||
recallZone = nil
|
||||
end
|
||||
|
||||
-- Deleted all spawned cards.
|
||||
-- Delete all spawned cards
|
||||
internal.deleteSpawned = function()
|
||||
for guid, _ in pairs(placedObjectGuids) do
|
||||
local obj = getObjectFromGUID(guid)
|
||||
@ -140,7 +131,7 @@ do
|
||||
end
|
||||
end
|
||||
|
||||
-- Recalls spawned cards with a fake bag that replicates the memory bag recall style.
|
||||
-- Recalls spawned cards with a fake bag that replicates the memory bag recall style
|
||||
internal.recallSpawned = function()
|
||||
local trash = spawnObjectData({ data = RECALL_BAG, position = self.getPosition() })
|
||||
for guid, _ in pairs(placedObjectGuids) do
|
||||
@ -156,9 +147,7 @@ do
|
||||
trash.destruct()
|
||||
end
|
||||
|
||||
|
||||
-- Callback for when an object has been spawned. Tracks the object for later recall and updates the
|
||||
-- recall zone.
|
||||
-- Callback for when an object has been spawned. Tracks the object for later recall and updates the recall zone.
|
||||
internal.recordPlacedObject = function(spawned)
|
||||
placedObjectGuids[spawned.getGUID()] = true
|
||||
internal.expandRecallZone(spawned)
|
||||
@ -174,21 +163,22 @@ do
|
||||
recallZone.upperLeft = { x = pos.x + RECALL_BUFFER_X, z = pos.z + RECALL_BUFFER_Z }
|
||||
recallZone.lowerRight = { x = pos.x - RECALL_BUFFER_X, z = pos.z - RECALL_BUFFER_Z }
|
||||
return
|
||||
else
|
||||
if (pos.x > recallZone.upperLeft.x) then
|
||||
end
|
||||
|
||||
if pos.x > recallZone.upperLeft.x then
|
||||
recallZone.upperLeft.x = pos.x + RECALL_BUFFER_X
|
||||
end
|
||||
if (pos.x < recallZone.lowerRight.x) then
|
||||
if pos.x < recallZone.lowerRight.x then
|
||||
recallZone.lowerRight.x = pos.x - RECALL_BUFFER_X
|
||||
end
|
||||
if (pos.z > recallZone.upperLeft.z) then
|
||||
if pos.z > recallZone.upperLeft.z then
|
||||
recallZone.upperLeft.z = pos.z + RECALL_BUFFER_Z
|
||||
end
|
||||
if (pos.z < recallZone.lowerRight.z) then
|
||||
if pos.z < recallZone.lowerRight.z then
|
||||
recallZone.lowerRight.z = pos.z - RECALL_BUFFER_Z
|
||||
end
|
||||
end
|
||||
if (SHOW_RECALL_ZONE) then
|
||||
|
||||
if SHOW_RECALL_ZONE then
|
||||
local y = 1.5
|
||||
local thick = 0.05
|
||||
Global.setVectorLines({
|
||||
|
@ -1,24 +1,31 @@
|
||||
<Panel
|
||||
active="false"
|
||||
<Panel active="false"
|
||||
id="helpPanel"
|
||||
position="-165 -60 -2"
|
||||
position="-165 -70 -2"
|
||||
rotation="0 0 180"
|
||||
height="55"
|
||||
height="50"
|
||||
width="107"
|
||||
color="#00000099">
|
||||
<Text
|
||||
id="helpText"
|
||||
<Text id="helpText"
|
||||
rectAlignment="MiddleCenter"
|
||||
height="490"
|
||||
height="480"
|
||||
width="1000"
|
||||
scale="0.1 0.1 1"
|
||||
fontSize="66"
|
||||
color="#F5F5F5"
|
||||
backgroundColor="#FF0000"
|
||||
alignment="UpperLeft"
|
||||
alignment="MiddleLeft"
|
||||
horizontalOverflow="wrap">
|
||||
• 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</Text>
|
||||
</Panel>
|
||||
|
||||
<Panel position="45 65 -11"
|
||||
rotation="0 0 180"
|
||||
height="200"
|
||||
width="200"
|
||||
scale="0.1 0.1 1"
|
||||
color="#FFFFFF"
|
||||
onClick="spawnOtherCards">
|
||||
</Panel>
|
Loading…
Reference in New Issue
Block a user