Merge pull request #316 from argonui/replenish-bugfix
Upkeep: keep state for replenishing cards
This commit is contained in:
commit
bf45ea267c
@ -109,10 +109,11 @@ do
|
|||||||
|
|
||||||
-- stateIDs for the multi-stated resource tokens
|
-- stateIDs for the multi-stated resource tokens
|
||||||
local stateTable = {
|
local stateTable = {
|
||||||
["Ammo"] = 2,
|
["resource"] = 1,
|
||||||
["Charge"] = 3,
|
["ammo"] = 2,
|
||||||
["Secret"] = 4,
|
["charge"] = 3,
|
||||||
["Supply"] = 5
|
["secret"] = 4,
|
||||||
|
["supply"] = 5
|
||||||
}
|
}
|
||||||
|
|
||||||
-- Source for tokens
|
-- Source for tokens
|
||||||
@ -151,13 +152,13 @@ do
|
|||||||
|
|
||||||
-- Spawns a set of tokens on the given card.
|
-- Spawns a set of tokens on the given card.
|
||||||
---@param card Object Card to spawn tokens on
|
---@param card Object Card to spawn tokens on
|
||||||
---@param tokenType String type of token to spawn, valid values are "damage", "horror",
|
---@param tokenType String Type of token to spawn, valid values are "damage", "horror",
|
||||||
-- "resource", "doom", or "clue"
|
-- "resource", "doom", or "clue"
|
||||||
---@param tokenCount Number How many tokens to spawn. For damage or horror this value will be set to the
|
---@param tokenCount Number How many tokens to spawn. For damage or horror this value will be set to the
|
||||||
-- spawned state object rather than spawning multiple tokens
|
-- spawned state object rather than spawning multiple tokens
|
||||||
---@param shiftDown Number An offset for the z-value of this group of tokens
|
---@param shiftDown Number An offset for the z-value of this group of tokens
|
||||||
---@param stateID Number Index of the state to load for this token
|
---@param subType Number Subtype of token to spawn. This will only differ from the tokenName for resource tokens
|
||||||
TokenManager.spawnTokenGroup = function(card, tokenType, tokenCount, shiftDown, stateID)
|
TokenManager.spawnTokenGroup = function(card, tokenType, tokenCount, shiftDown, subType)
|
||||||
local optionPanel = Global.getTable("optionPanel")
|
local optionPanel = Global.getTable("optionPanel")
|
||||||
|
|
||||||
if tokenType == "damage" or tokenType == "horror" then
|
if tokenType == "damage" or tokenType == "horror" then
|
||||||
@ -165,7 +166,7 @@ do
|
|||||||
elseif tokenType == "resource" and optionPanel["useResourceCounters"] then
|
elseif tokenType == "resource" and optionPanel["useResourceCounters"] then
|
||||||
TokenManager.spawnResourceCounterToken(card, tokenCount)
|
TokenManager.spawnResourceCounterToken(card, tokenCount)
|
||||||
else
|
else
|
||||||
TokenManager.spawnMultipleTokens(card, tokenType, tokenCount, shiftDown, stateID)
|
TokenManager.spawnMultipleTokens(card, tokenType, tokenCount, shiftDown, subType)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -196,8 +197,8 @@ do
|
|||||||
-- Other types should use spawnCounterToken()
|
-- Other types should use spawnCounterToken()
|
||||||
---@param tokenCount Number How many tokens to spawn
|
---@param tokenCount Number How many tokens to spawn
|
||||||
---@param shiftDown Number An offset for the z-value of this group of tokens
|
---@param shiftDown Number An offset for the z-value of this group of tokens
|
||||||
---@param stateID Number Index of the state to load for this token
|
---@param subType Number Subtype of token to spawn. This will only differ from the tokenName for resource tokens
|
||||||
TokenManager.spawnMultipleTokens = function(card, tokenType, tokenCount, shiftDown, stateID)
|
TokenManager.spawnMultipleTokens = function(card, tokenType, tokenCount, shiftDown, subType)
|
||||||
if tokenCount < 1 or tokenCount > 12 then
|
if tokenCount < 1 or tokenCount > 12 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
@ -231,7 +232,8 @@ do
|
|||||||
|
|
||||||
-- this is used to load the correct state for additional resource tokens (e.g. "Ammo")
|
-- this is used to load the correct state for additional resource tokens (e.g. "Ammo")
|
||||||
local callback = nil
|
local callback = nil
|
||||||
if tokenType == "resource" and stateID ~= nil then
|
local stateID = stateTable[string.lower(subType)]
|
||||||
|
if tokenType == "resource" and stateID ~= nil and stateID ~= 1 then
|
||||||
callback = function(spawned) spawned.setState(stateID) end
|
callback = function(spawned) spawned.setState(stateID) end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -279,6 +281,17 @@ do
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Checks a card for metadata to maybe replenish it
|
||||||
|
---@param card Object Card object to be replenished
|
||||||
|
---@param uses Table The already decoded metadata.uses (to avoid decoding again)
|
||||||
|
---@param mat Object The playmat the card is placed on (for rotation and casting)
|
||||||
|
TokenManager.maybeReplenishCard = function(card, uses, mat)
|
||||||
|
-- TODO: support for cards with multiple uses AND replenish (as of yet, no official card needs that)
|
||||||
|
if uses[1].count and uses[1].replenish then
|
||||||
|
internal.replenishTokens(card, uses, mat)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Delegate function to the token spawn tracker. Exists to avoid circular dependencies in some
|
-- Delegate function to the token spawn tracker. Exists to avoid circular dependencies in some
|
||||||
-- callers.
|
-- callers.
|
||||||
---@param card Object Card object to reset the tokens for
|
---@param card Object Card object to reset the tokens for
|
||||||
@ -354,7 +367,7 @@ do
|
|||||||
tokenCount = tokenCount + extraUses[type]
|
tokenCount = tokenCount + extraUses[type]
|
||||||
end
|
end
|
||||||
-- Shift each spawned group after the first down so they don't pile on each other
|
-- Shift each spawned group after the first down so they don't pile on each other
|
||||||
TokenManager.spawnTokenGroup(card, token, tokenCount, (i - 1) * 0.8, stateTable[type])
|
TokenManager.spawnTokenGroup(card, token, tokenCount, (i - 1) * 0.8, type)
|
||||||
end
|
end
|
||||||
tokenSpawnTracker.markTokensSpawned(card.getGUID())
|
tokenSpawnTracker.markTokensSpawned(card.getGUID())
|
||||||
end
|
end
|
||||||
@ -460,5 +473,67 @@ do
|
|||||||
return cluePositions
|
return cluePositions
|
||||||
end
|
end
|
||||||
|
|
||||||
|
---@param card Object Card object to be replenished
|
||||||
|
---@param uses Table The already decoded metadata.uses (to avoid decoding again)
|
||||||
|
---@param mat Object The playmat the card is placed on (for rotation and casting)
|
||||||
|
internal.replenishTokens = function(card, uses, mat)
|
||||||
|
local cardPos = card.getPosition()
|
||||||
|
|
||||||
|
-- don't continue for cards on the deck (Norman) or in the discard pile
|
||||||
|
if mat.positionToLocal(cardPos).x < -1 then return end
|
||||||
|
|
||||||
|
-- get current amount of resource tokens on the card
|
||||||
|
local search = internal.searchOnCard(cardPos, card.getRotation())
|
||||||
|
local clickableResourceCounter = nil
|
||||||
|
local foundTokens = 0
|
||||||
|
|
||||||
|
for _, obj in ipairs(search) do
|
||||||
|
local obj = obj.hit_object
|
||||||
|
local memo = obj.getMemo()
|
||||||
|
|
||||||
|
if (stateTable[memo] or 0) > 0 then
|
||||||
|
foundTokens = foundTokens + math.abs(obj.getQuantity())
|
||||||
|
obj.destruct()
|
||||||
|
elseif memo == "resourceCounter" then
|
||||||
|
foundTokens = obj.getVar("val")
|
||||||
|
clickableResourceCounter = obj
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- this is the theoretical new amount of uses (to be checked below)
|
||||||
|
local newCount = foundTokens + uses[1].replenish
|
||||||
|
|
||||||
|
-- if there are already more uses than the replenish amount, keep them
|
||||||
|
if foundTokens > uses[1].count then
|
||||||
|
newCount = foundTokens
|
||||||
|
-- only replenish up until the replenish amount
|
||||||
|
elseif newCount > uses[1].count then
|
||||||
|
newCount = uses[1].count
|
||||||
|
end
|
||||||
|
|
||||||
|
-- update the clickable counter or spawn a group of tokens
|
||||||
|
if clickableResourceCounter then
|
||||||
|
clickableResourceCounter.call("updateVal", newCount)
|
||||||
|
else
|
||||||
|
TokenManager.spawnTokenGroup(card, uses[1].token, newCount, _, uses[1].type)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- searches on a card (standard size) and returns the result
|
||||||
|
---@param position Table Position of the card
|
||||||
|
---@param rotation Table Rotation of the card
|
||||||
|
internal.searchOnCard = function(position, rotation)
|
||||||
|
return Physics.cast({
|
||||||
|
origin = position,
|
||||||
|
direction = {0, 1, 0},
|
||||||
|
orientation = rotation,
|
||||||
|
type = 3,
|
||||||
|
size = { 2.5, 0.5, 3.5 },
|
||||||
|
max_distance = 1,
|
||||||
|
debug = false
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
return TokenManager
|
return TokenManager
|
||||||
end
|
end
|
||||||
|
@ -288,13 +288,7 @@ function doUpkeep(_, clickedByColor, isRightClick)
|
|||||||
forcedLearning = true
|
forcedLearning = true
|
||||||
end
|
end
|
||||||
if cardMetadata.uses ~= nil then
|
if cardMetadata.uses ~= nil then
|
||||||
-- check for cards with 'replenish' in their metadata
|
tokenManager.maybeReplenishCard(obj, cardMetadata.uses, self)
|
||||||
-- TODO: support for cards with multiple uses AND replenish (as of yet, no official card needs that)
|
|
||||||
local count = cardMetadata.uses[1].count
|
|
||||||
local replenish = cardMetadata.uses[1].replenish
|
|
||||||
if count and replenish then
|
|
||||||
replenishTokens(obj, count, replenish)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -539,49 +533,6 @@ end
|
|||||||
-- playmat token spawning
|
-- playmat token spawning
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
-- replenish Tokens for specific cards (like 'Physical Training (4)')
|
|
||||||
function replenishTokens(card, count, replenish)
|
|
||||||
local cardPos = card.getPosition()
|
|
||||||
|
|
||||||
-- don't continue for cards on your deck (Norman) or in your discard pile
|
|
||||||
if self.positionToLocal(cardPos).x < -1 then return end
|
|
||||||
|
|
||||||
-- get current amount of resource tokens on the card
|
|
||||||
local search = searchArea(cardPos, { 2.5, 0.5, 3.5 })
|
|
||||||
local clickableResourceCounter = nil
|
|
||||||
local foundTokens = 0
|
|
||||||
|
|
||||||
for _, obj in ipairs(search) do
|
|
||||||
local obj = obj.hit_object
|
|
||||||
if obj.getCustomObject().image == "http://cloud-3.steamusercontent.com/ugc/1758068501357192910/11DDDC7EF621320962FDCF3AE3211D5EDC3D1573/" then
|
|
||||||
foundTokens = foundTokens + math.abs(obj.getQuantity())
|
|
||||||
obj.destruct()
|
|
||||||
elseif obj.getMemo() == "resourceCounter" then
|
|
||||||
foundTokens = obj.getVar("val")
|
|
||||||
clickableResourceCounter = obj
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- this is the theoretical new amount of uses (to be checked below)
|
|
||||||
local newCount = foundTokens + replenish
|
|
||||||
|
|
||||||
-- if there are already more uses than the replenish amount, keep them
|
|
||||||
if foundTokens > count then
|
|
||||||
newCount = foundTokens
|
|
||||||
-- only replenish up until the replenish amount
|
|
||||||
elseif newCount > count then
|
|
||||||
newCount = count
|
|
||||||
end
|
|
||||||
|
|
||||||
-- update the clickable counter or spawn a group of tokens
|
|
||||||
if clickableResourceCounter then
|
|
||||||
clickableResourceCounter.call("updateVal", newCount)
|
|
||||||
else
|
|
||||||
tokenManager.spawnTokenGroup(card, "resource", newCount)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Finds all customizable cards in this play area and updates their metadata based on the selections
|
-- Finds all customizable cards in this play area and updates their metadata based on the selections
|
||||||
-- on the matching upgrade sheet.
|
-- on the matching upgrade sheet.
|
||||||
-- This method is theoretically O(n^2), and should be used sparingly. In practice it will only be
|
-- This method is theoretically O(n^2), and should be used sparingly. In practice it will only be
|
||||||
|
Loading…
Reference in New Issue
Block a user