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
|
-- Count victory points from locations in play area
|
||||||
---@param highlightOff boolean True if highlighting should be enabled
|
---@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)
|
function countVP(highlightOff)
|
||||||
local totalVP = 0
|
local totalVP = 0
|
||||||
|
|
||||||
|
@ -299,9 +299,10 @@ do
|
|||||||
---@param card tts__Object Card object to be replenished
|
---@param card tts__Object Card object to be replenished
|
||||||
---@param uses table The already decoded metadata.uses (to avoid decoding again)
|
---@param uses table The already decoded metadata.uses (to avoid decoding again)
|
||||||
TokenManager.maybeReplenishCard = function(card, uses)
|
TokenManager.maybeReplenishCard = function(card, uses)
|
||||||
-- TODO: support for cards with multiple uses AND replenish (as of yet, no official card needs that)
|
for _, useInfo in ipairs(uses) do
|
||||||
if uses[1].count and uses[1].replenish then
|
if useInfo.count and useInfo.replenish then
|
||||||
internal.replenishTokens(card, uses)
|
internal.replenishTokens(card, useInfo)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -459,59 +460,76 @@ do
|
|||||||
return nil
|
return nil
|
||||||
end
|
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 card tts__Object Card the clues will be placed on
|
||||||
---@param count number How many clues?
|
---@param count number How many clues?
|
||||||
---@return table: Array of global positions to spawn the clues at
|
---@return table: Array of global positions to spawn the clues at
|
||||||
internal.buildClueOffsets = function(card, count)
|
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 = {}
|
local cluePositions = {}
|
||||||
for i = 1, count do
|
for i = 1, count do
|
||||||
local row = math.floor(1 + (i - 1) / 4)
|
local row = math.floor(1 + (i - 1) / 4)
|
||||||
local column = (i - 1) % 4
|
local column = (i - 1) % 4
|
||||||
local cluePos = card.positionToWorld(Vector(-0.825 + 0.55 * column, 0, -1.5 + 0.55 * row))
|
local localPos = Vector((-0.825 + 0.55 * column) * modifier, 0, -1.5 + 0.55 * row)
|
||||||
cluePos.y = cluePos.y + 0.05
|
local cluePos = card.positionToWorld(localPos) + Vector(0, 0.03, 0)
|
||||||
table.insert(cluePositions, cluePos)
|
table.insert(cluePositions, cluePos)
|
||||||
end
|
end
|
||||||
return cluePositions
|
return cluePositions
|
||||||
end
|
end
|
||||||
|
|
||||||
---@param card tts__Object Card object to be replenished
|
---@param card tts__Object Card object to be replenished
|
||||||
---@param uses table The already decoded metadata.uses (to avoid decoding again)
|
---@param useInfo table The already decoded subtable of metadata.uses (to avoid decoding again)
|
||||||
internal.replenishTokens = function(card, uses)
|
internal.replenishTokens = function(card, useInfo)
|
||||||
-- get current amount of matching resource tokens on the card
|
-- get current amount of matching resource tokens on the card
|
||||||
local clickableResourceCounter = nil
|
local clickableResourceCounter = nil
|
||||||
local foundTokens = 0
|
local foundTokens = 0
|
||||||
local searchType = string.lower(uses[1].type)
|
|
||||||
|
|
||||||
for _, obj in ipairs(searchLib.onObject(card, "isTileOrToken")) do
|
if useInfo.token == "clue" then
|
||||||
local memo = obj.getMemo()
|
for _, obj in ipairs(searchLib.onObject(card, "isClue")) do
|
||||||
|
|
||||||
if searchType == memo then
|
|
||||||
foundTokens = foundTokens + math.abs(obj.getQuantity())
|
foundTokens = foundTokens + math.abs(obj.getQuantity())
|
||||||
obj.destruct()
|
obj.destruct()
|
||||||
elseif memo == "resourceCounter" then
|
end
|
||||||
foundTokens = obj.getVar("val")
|
elseif useInfo.token == "doom" then
|
||||||
clickableResourceCounter = obj
|
for _, obj in ipairs(searchLib.onObject(card, "isDoom")) do
|
||||||
break
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
-- this is the theoretical new amount of uses (to be checked below)
|
-- 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 there are already more uses than the replenish amount, keep them
|
||||||
if foundTokens > uses[1].count then
|
if foundTokens > useInfo.count then
|
||||||
newCount = foundTokens
|
newCount = foundTokens
|
||||||
-- only replenish up until the replenish amount
|
-- only replenish up until the replenish amount
|
||||||
elseif newCount > uses[1].count then
|
elseif newCount > useInfo.count then
|
||||||
newCount = uses[1].count
|
newCount = useInfo.count
|
||||||
end
|
end
|
||||||
|
|
||||||
-- update the clickable counter or spawn a group of tokens
|
-- update the clickable counter or spawn a group of tokens
|
||||||
if clickableResourceCounter then
|
if clickableResourceCounter then
|
||||||
clickableResourceCounter.call("updateVal", newCount)
|
clickableResourceCounter.call("updateVal", newCount)
|
||||||
else
|
else
|
||||||
TokenManager.spawnTokenGroup(card, uses[1].token, newCount, _, uses[1].type)
|
TokenManager.spawnTokenGroup(card, useInfo.token, newCount, _, useInfo.type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ do
|
|||||||
isDeck = function(x) return x.type == "Deck" end,
|
isDeck = function(x) return x.type == "Deck" end,
|
||||||
isCardOrDeck = function(x) return x.type == "Card" or 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,
|
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,
|
isTileOrToken = function(x) return x.type == "Tile" end,
|
||||||
isUniversalToken = function(x) return x.getMemo() == "universalActionAbility" end,
|
isUniversalToken = function(x) return x.getMemo() == "universalActionAbility" end,
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
local guidReferenceApi = require("core/GUIDReferenceApi")
|
|
||||||
local playermatApi = require("playermat/PlayermatApi")
|
local playermatApi = require("playermat/PlayermatApi")
|
||||||
local searchLib = require("util/SearchLib")
|
local searchLib = require("util/SearchLib")
|
||||||
local tokenManager = require("core/token/TokenManager")
|
local tokenManager = require("core/token/TokenManager")
|
||||||
@ -24,35 +23,23 @@ function onScriptingButtonDown(index, playerColor)
|
|||||||
|
|
||||||
-- check for subtype of resource based on card below
|
-- check for subtype of resource based on card below
|
||||||
if tokenType == "resource" then
|
if tokenType == "resource" then
|
||||||
local card
|
local card = getTargetCard(playerColor, position)
|
||||||
local hoverObj = Player[playerColor].getHoverObject()
|
|
||||||
if hoverObj and hoverObj.type == "Card" then
|
if card and not card.is_face_down then
|
||||||
card = hoverObj
|
local status = addUseToCard(card, tokenType)
|
||||||
elseif hoverObj then
|
if status == true then return end
|
||||||
-- 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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- get the metadata from the card and maybe replenish a use
|
-- check hovered object for location data or 'uses (x clues)' and add one
|
||||||
if card and not card.is_face_down then
|
elseif tokenType == "clue" then
|
||||||
local metadata = JSON.decode(card.getGMNotes()) or {}
|
local card = getTargetCard(playerColor, position)
|
||||||
local uses = metadata.uses or {}
|
|
||||||
for _, useInfo in ipairs(uses) do
|
if card and (not card.is_face_down or card.hasTag("Location")) then
|
||||||
if useInfo.token == "resource" then
|
local status = addUseToCard(card, tokenType)
|
||||||
-- artifically create replenish data to re-use that existing functionality
|
if status == true then return end
|
||||||
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
|
|
||||||
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
|
elseif tokenType == "resourceCounter" then
|
||||||
local hoverObj = Player[playerColor].getHoverObject()
|
local hoverObj = Player[playerColor].getHoverObject()
|
||||||
if hoverObj then
|
if hoverObj then
|
||||||
@ -61,7 +48,8 @@ function onScriptingButtonDown(index, playerColor)
|
|||||||
return
|
return
|
||||||
end
|
end
|
||||||
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
|
elseif tokenType == "damage" or tokenType == "horror" then
|
||||||
local hoverObj = Player[playerColor].getHoverObject()
|
local hoverObj = Player[playerColor].getHoverObject()
|
||||||
if hoverObj then
|
if hoverObj then
|
||||||
@ -74,12 +62,74 @@ function onScriptingButtonDown(index, playerColor)
|
|||||||
end
|
end
|
||||||
end
|
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
|
elseif tokenType == "universalActionAbility" then
|
||||||
local matColor = playermatApi.getMatColorByPosition(position)
|
local matColor = playermatApi.getMatColorByPosition(position)
|
||||||
|
local matRotation = playermatApi.returnRotation(matColor)
|
||||||
local class = playermatApi.returnInvestigatorClass(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
|
end
|
||||||
|
|
||||||
tokenManager.spawnToken(position, tokenType, rotation, callback)
|
tokenManager.spawnToken(position, tokenType, rotation, callback)
|
||||||
end
|
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