updated clue spawning
This commit is contained in:
parent
843d6d4e10
commit
8bc7ea9f94
@ -464,7 +464,7 @@ end
|
||||
|
||||
-- Count victory points from locations in play area
|
||||
---@param highlightOff boolean True if highlighting should be enabled
|
||||
---@return. Returns the total amount of VP found in the play area
|
||||
---@return number totalVP Total amount of VP found in the play area
|
||||
function countVP(highlightOff)
|
||||
local totalVP = 0
|
||||
|
||||
|
@ -299,9 +299,10 @@ do
|
||||
---@param card tts__Object Card object to be replenished
|
||||
---@param uses table The already decoded metadata.uses (to avoid decoding again)
|
||||
TokenManager.maybeReplenishCard = function(card, uses)
|
||||
-- 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)
|
||||
for _, useInfo in ipairs(uses) do
|
||||
if useInfo.count and useInfo.replenish then
|
||||
internal.replenishTokens(card, useInfo)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -459,59 +460,76 @@ do
|
||||
return nil
|
||||
end
|
||||
|
||||
-- Dynamically create positions for clues on a card.
|
||||
-- Dynamically create positions for clues on a card
|
||||
---@param card tts__Object Card the clues will be placed on
|
||||
---@param count number How many clues?
|
||||
---@return table: Array of global positions to spawn the clues at
|
||||
internal.buildClueOffsets = function(card, count)
|
||||
-- make sure clues always spawn from left to right
|
||||
local modifier = -1
|
||||
if card.is_face_down then
|
||||
modifier = 1
|
||||
end
|
||||
|
||||
local cluePositions = {}
|
||||
for i = 1, count do
|
||||
local row = math.floor(1 + (i - 1) / 4)
|
||||
local column = (i - 1) % 4
|
||||
local cluePos = card.positionToWorld(Vector(-0.825 + 0.55 * column, 0, -1.5 + 0.55 * row))
|
||||
cluePos.y = cluePos.y + 0.05
|
||||
local localPos = Vector((-0.825 + 0.55 * column) * modifier, 0, -1.5 + 0.55 * row)
|
||||
local cluePos = card.positionToWorld(localPos) + Vector(0, 0.03, 0)
|
||||
table.insert(cluePositions, cluePos)
|
||||
end
|
||||
return cluePositions
|
||||
end
|
||||
|
||||
---@param card tts__Object Card object to be replenished
|
||||
---@param uses table The already decoded metadata.uses (to avoid decoding again)
|
||||
internal.replenishTokens = function(card, uses)
|
||||
---@param useInfo table The already decoded subtable of metadata.uses (to avoid decoding again)
|
||||
internal.replenishTokens = function(card, useInfo)
|
||||
-- get current amount of matching resource tokens on the card
|
||||
local clickableResourceCounter = nil
|
||||
local foundTokens = 0
|
||||
local searchType = string.lower(uses[1].type)
|
||||
|
||||
for _, obj in ipairs(searchLib.onObject(card, "isTileOrToken")) do
|
||||
local memo = obj.getMemo()
|
||||
|
||||
if searchType == memo then
|
||||
if useInfo.token == "clue" then
|
||||
for _, obj in ipairs(searchLib.onObject(card, "isClue")) do
|
||||
foundTokens = foundTokens + math.abs(obj.getQuantity())
|
||||
obj.destruct()
|
||||
elseif memo == "resourceCounter" then
|
||||
foundTokens = obj.getVar("val")
|
||||
clickableResourceCounter = obj
|
||||
break
|
||||
end
|
||||
elseif useInfo.token == "doom" then
|
||||
for _, obj in ipairs(searchLib.onObject(card, "isDoom")) do
|
||||
foundTokens = foundTokens + math.abs(obj.getQuantity())
|
||||
obj.destruct()
|
||||
end
|
||||
else
|
||||
local searchType = string.lower(useInfo.type)
|
||||
for _, obj in ipairs(searchLib.onObject(card, "isTileOrToken")) do
|
||||
local memo = obj.getMemo()
|
||||
if searchType == memo then
|
||||
foundTokens = foundTokens + math.abs(obj.getQuantity())
|
||||
obj.destruct()
|
||||
elseif memo == "resourceCounter" then
|
||||
foundTokens = obj.getVar("val")
|
||||
clickableResourceCounter = obj
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- this is the theoretical new amount of uses (to be checked below)
|
||||
local newCount = foundTokens + uses[1].replenish
|
||||
local newCount = foundTokens + useInfo.replenish
|
||||
|
||||
-- if there are already more uses than the replenish amount, keep them
|
||||
if foundTokens > uses[1].count then
|
||||
if foundTokens > useInfo.count then
|
||||
newCount = foundTokens
|
||||
-- only replenish up until the replenish amount
|
||||
elseif newCount > uses[1].count then
|
||||
newCount = uses[1].count
|
||||
elseif newCount > useInfo.count then
|
||||
newCount = useInfo.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)
|
||||
TokenManager.spawnTokenGroup(card, useInfo.token, newCount, _, useInfo.type)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -5,6 +5,7 @@ do
|
||||
isDeck = function(x) return x.type == "Deck" end,
|
||||
isCardOrDeck = function(x) return x.type == "Card" or x.type == "Deck" end,
|
||||
isClue = function(x) return x.memo == "clueDoom" and x.is_face_down == false end,
|
||||
isDoom = function(x) return x.memo == "clueDoom" and x.is_face_down == true end,
|
||||
isTileOrToken = function(x) return x.type == "Tile" end,
|
||||
isUniversalToken = function(x) return x.getMemo() == "universalActionAbility" end,
|
||||
}
|
||||
|
@ -1,4 +1,3 @@
|
||||
local guidReferenceApi = require("core/GUIDReferenceApi")
|
||||
local playermatApi = require("playermat/PlayermatApi")
|
||||
local searchLib = require("util/SearchLib")
|
||||
local tokenManager = require("core/token/TokenManager")
|
||||
@ -24,35 +23,23 @@ function onScriptingButtonDown(index, playerColor)
|
||||
|
||||
-- check for subtype of resource based on card below
|
||||
if tokenType == "resource" then
|
||||
local card
|
||||
local hoverObj = Player[playerColor].getHoverObject()
|
||||
if hoverObj and hoverObj.type == "Card" then
|
||||
card = hoverObj
|
||||
elseif hoverObj then
|
||||
-- use the first card below the hovered object if it's not a card1
|
||||
for _, obj in ipairs(searchLib.belowPosition(position, "isCard")) do
|
||||
card = obj
|
||||
break
|
||||
end
|
||||
local card = getTargetCard(playerColor, position)
|
||||
|
||||
if card and not card.is_face_down then
|
||||
local status = addUseToCard(card, tokenType)
|
||||
if status == true then return end
|
||||
end
|
||||
|
||||
-- get the metadata from the card and maybe replenish a use
|
||||
if card and not card.is_face_down then
|
||||
local metadata = JSON.decode(card.getGMNotes()) or {}
|
||||
local uses = metadata.uses or {}
|
||||
for _, useInfo in ipairs(uses) do
|
||||
if useInfo.token == "resource" then
|
||||
-- artifically create replenish data to re-use that existing functionality
|
||||
uses[1].count = 999
|
||||
uses[1].replenish = 1
|
||||
local matColor = playermatApi.getMatColorByPosition(position)
|
||||
local mat = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat")
|
||||
tokenManager.maybeReplenishCard(card, uses, mat)
|
||||
return
|
||||
end
|
||||
end
|
||||
-- check hovered object for location data or 'uses (x clues)' and add one
|
||||
elseif tokenType == "clue" then
|
||||
local card = getTargetCard(playerColor, position)
|
||||
|
||||
if card and (not card.is_face_down or card.hasTag("Location")) then
|
||||
local status = addUseToCard(card, tokenType)
|
||||
if status == true then return end
|
||||
end
|
||||
-- check hovered object for "resourceCounter" tokens and increase them instead
|
||||
|
||||
-- check hovered object for "resourceCounter" tokens and increase them instead
|
||||
elseif tokenType == "resourceCounter" then
|
||||
local hoverObj = Player[playerColor].getHoverObject()
|
||||
if hoverObj then
|
||||
@ -61,7 +48,8 @@ function onScriptingButtonDown(index, playerColor)
|
||||
return
|
||||
end
|
||||
end
|
||||
-- check hovered object for "damage" and "horror" tokens and increase them instead
|
||||
|
||||
-- check hovered object for "damage" and "horror" tokens and increase them instead
|
||||
elseif tokenType == "damage" or tokenType == "horror" then
|
||||
local hoverObj = Player[playerColor].getHoverObject()
|
||||
if hoverObj then
|
||||
@ -74,12 +62,74 @@ function onScriptingButtonDown(index, playerColor)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- check for nearest investigator card and change action token state to its class
|
||||
|
||||
-- check for nearest investigator card and change action token state to its class
|
||||
elseif tokenType == "universalActionAbility" then
|
||||
local matColor = playermatApi.getMatColorByPosition(position)
|
||||
local matRotation = playermatApi.returnRotation(matColor)
|
||||
local class = playermatApi.returnInvestigatorClass(matColor)
|
||||
callback = function(spawned) spawned.call("updateClassAndSymbol", { class = class, symbol = class }) end
|
||||
callback = function(spawned)
|
||||
spawned.setRotation(matRotation)
|
||||
spawned.call("updateClassAndSymbol", { class = class, symbol = class })
|
||||
end
|
||||
end
|
||||
|
||||
tokenManager.spawnToken(position, tokenType, rotation, callback)
|
||||
end
|
||||
|
||||
-- gets the target card for this operation
|
||||
---@param playerColor string Color of the triggering player
|
||||
---@param position tts__Vector Position to check for a card (if there isn't a hovered card)
|
||||
function getTargetCard(playerColor, position)
|
||||
local hoverObj = Player[playerColor].getHoverObject()
|
||||
if hoverObj and hoverObj.type == "Card" then
|
||||
return hoverObj
|
||||
elseif hoverObj then
|
||||
-- use the first card below the hovered object if it's not a card
|
||||
for _, obj in ipairs(searchLib.belowPosition(position, "isCard")) do
|
||||
return obj
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- adds a use to a card (TODO: probably move this to the TokenManager?)
|
||||
---@param card tts__Object Card that should get a use added
|
||||
---@param useType string Type of uses to be added
|
||||
function addUseToCard(card, useType)
|
||||
local metadata = JSON.decode(card.getGMNotes()) or {}
|
||||
|
||||
-- get correct data for location
|
||||
if metadata.type == "Location" then
|
||||
if not card.is_face_down and metadata.locationFront ~= nil then
|
||||
metadata = metadata.locationFront
|
||||
elseif metadata.locationBack ~= nil then
|
||||
metadata = metadata.locationBack
|
||||
end
|
||||
|
||||
-- if there are no uses at all, add "empty" uses for fake replenishing (only for clues)
|
||||
if metadata.uses == nil then
|
||||
metadata.uses = { { token = "clue" } }
|
||||
end
|
||||
end
|
||||
|
||||
local match = false
|
||||
for _, useInfo in ipairs(metadata.uses) do
|
||||
if useInfo.token == useType then
|
||||
-- artificially create replenish data to re-use that existing functionality
|
||||
useInfo.count = 999
|
||||
useInfo.replenish = 1
|
||||
match = true
|
||||
else
|
||||
-- artificially disable other uses from replenishing
|
||||
useInfo.replenish = nil
|
||||
end
|
||||
end
|
||||
|
||||
-- if matching uses were found, perform the "fake" replenish
|
||||
if match then
|
||||
tokenManager.maybeReplenishCard(card, metadata.uses)
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user