added investigator counter to handler

This commit is contained in:
Chr1Z93 2023-10-10 13:20:50 +02:00
parent 5cd37055a8
commit 7b0fd216ef
4 changed files with 85 additions and 82 deletions

View File

@ -51,6 +51,7 @@ local GuidReferences = {
DeckImporter = "a28140",
DoomCounter = "85c4c6",
DoomInPlayCounter = "652ff3",
InvestigatorCounter = "f182ee",
MasterClueCounter = "4a3aa4",
MythosArea = "9f334f",
NavigationOverlayHandler = "797ede",

View File

@ -2,61 +2,60 @@
-- general setup
---------------------------------------------------------
local guidHandler = getObjectFromGUID("123456")
-- Location connection directional options
local BIDIRECTIONAL = 0
local ONE_WAY = 1
local INCOMING_ONE_WAY = 2
local BIDIRECTIONAL = 0
local ONE_WAY = 1
local INCOMING_ONE_WAY = 2
-- Connector draw parameters
local CONNECTION_THICKNESS = 0.015
local CONNECTION_THICKNESS = 0.015
local DRAGGING_CONNECTION_THICKNESS = 0.15
local DRAGGING_CONNECTION_COLOR = { 0.8, 0.8, 0.8, 1 }
local CONNECTION_COLOR = { 0.4, 0.4, 0.4, 1 }
local DIRECTIONAL_ARROW_DISTANCE = 3.5
local ARROW_ARM_LENGTH = 0.9
local ARROW_ANGLE = 25
local DRAGGING_CONNECTION_COLOR = { 0.8, 0.8, 0.8, 1 }
local CONNECTION_COLOR = { 0.4, 0.4, 0.4, 1 }
local DIRECTIONAL_ARROW_DISTANCE = 3.5
local ARROW_ARM_LENGTH = 0.9
local ARROW_ANGLE = 25
-- Height to draw the connector lines, places them just above the table and always below cards
local CONNECTION_LINE_Y = 1.529
local CONNECTION_LINE_Y = 1.529
-- we use this to turn off collision handling until onLoad() is complete
local collisionEnabled = false
local collisionEnabled = false
-- used for recreating the link to a custom data helper after image change
customDataHelper = nil
customDataHelper = nil
local DEFAULT_URL = "http://cloud-3.steamusercontent.com/ugc/998015670465071049/FFAE162920D67CF38045EFBD3B85AD0F916147B2/"
local DEFAULT_URL =
"http://cloud-3.steamusercontent.com/ugc/998015670465071049/FFAE162920D67CF38045EFBD3B85AD0F916147B2/"
local SHIFT_OFFSETS = {
local SHIFT_OFFSETS = {
left = { x = 0.00, y = 0, z = 7.67 },
right = { x = 0.00, y = 0, z = -7.67 },
up = { x = 6.54, y = 0, z = 0.00 },
down = { x = -6.54, y = 0, z = 0.00 }
}
local SHIFT_EXCLUSION = {
local SHIFT_EXCLUSION = {
["b7b45b"] = true,
["f182ee"] = true,
["721ba2"] = true
}
local LOC_LINK_EXCLUDE_SCENARIOS = {
local LOC_LINK_EXCLUDE_SCENARIOS = {
["The Witching Hour"] = true,
["The Heart of Madness"] = true
}
local tokenManager = require("core/token/TokenManager")
local tokenManager = require("core/token/TokenManager")
local clueData = {}
local spawnedLocationGUIDs = {}
local locations = {}
local locationConnections = {}
local draggingGuids = {}
local clueData = {}
local spawnedLocationGUIDs = {}
local locations = {}
local locationConnections = {}
local draggingGuids = {}
local locationData
local currentScenario
local missingData = {}
local countedVP = {}
local missingData = {}
local countedVP = {}
---------------------------------------------------------
-- general code
@ -71,8 +70,8 @@ end
function onLoad(saveState)
-- records locations we have spawned clues for
local save = JSON.decode(saveState) or { }
locations = save.trackedLocations or { }
local save = JSON.decode(saveState) or {}
locations = save.trackedLocations or {}
currentScenario = save.currentScenario
self.interactable = false
@ -93,13 +92,13 @@ function updateSurface(newURL)
local customInfo = self.getCustomObject()
if newURL ~= "" and newURL ~= nil and newURL ~= DEFAULT_URL then
customInfo.image = newURL
broadcastToAll("New Playmat Image Applied", { 0.2, 0.9, 0.2 })
customInfo.image = newURL
broadcastToAll("New Playmat Image Applied", { 0.2, 0.9, 0.2 })
else
customInfo.image = DEFAULT_URL
broadcastToAll("Default Playmat Image Applied", { 0.2, 0.9, 0.2 })
customInfo.image = DEFAULT_URL
broadcastToAll("Default Playmat Image Applied", { 0.2, 0.9, 0.2 })
end
self.setCustomObject(customInfo)
local guid = nil
@ -108,7 +107,7 @@ function updateSurface(newURL)
self.reload()
if guid ~= nil then
Wait.time(function() updateLocations({ guid }) end, 1)
Wait.time(function() updateLocations({ guid }) end, 1)
end
end
@ -129,12 +128,14 @@ function onCollisionEnter(collisionInfo)
if shouldSpawnTokens(card) then
tokenManager.spawnForCard(card)
end
-- If this card was being dragged, clear the dragging connections. A multi-drag/drop may send
-- the dropped card immediately into a deck, so this has to be done here
if draggingGuids[card.getGUID()] ~= nil then
card.setVectorLines(nil)
draggingGuids[card.getGUID()] = nil
end
maybeTrackLocation(card)
end
@ -167,20 +168,20 @@ function onObjectPickUp(player, object)
-- should be tracking
if showLocationLinks() and isInPlayArea(object) and object.getGMNotes() ~= nil and object.getGMNotes() ~= "" then
local pickedUpGuid = object.getGUID()
local metadata = JSON.decode(object.getGMNotes()) or { }
local metadata = JSON.decode(object.getGMNotes()) or {}
if metadata.type == "Location" then
-- onCollisionExit sometimes comes 1 frame after onObjectPickUp (rather than before it or in
-- the same frame). This causes a mismatch in the data between dragging the on-table, and
-- that one frame draws connectors on the card which then show up as shadows for snap points.
-- Waiting ensures we always do thing in the expected Exit->PickUp order
Wait.frames(function()
if object.is_face_down then
draggingGuids[pickedUpGuid] = metadata.locationBack
else
draggingGuids[pickedUpGuid] = metadata.locationFront
end
rebuildConnectionList()
end, 2)
if object.is_face_down then
draggingGuids[pickedUpGuid] = metadata.locationBack
else
draggingGuids[pickedUpGuid] = metadata.locationFront
end
rebuildConnectionList()
end, 2)
end
end
end
@ -273,11 +274,11 @@ end
-- drawBaseConnections()
function rebuildConnectionList()
if not showLocationLinks() then
locationConnections = { }
locationConnections = {}
return
end
local iconCardList = { }
local iconCardList = {}
-- Build a list of cards with each icon as their location ID
for cardId, metadata in pairs(draggingGuids) do
@ -288,7 +289,7 @@ function rebuildConnectionList()
end
-- Pair up all the icons
locationConnections = { }
locationConnections = {}
for cardId, metadata in pairs(draggingGuids) do
buildConnection(cardId, iconCardList, metadata)
end
@ -307,7 +308,7 @@ function buildLocListByIcon(cardId, iconCardList, locData)
if locData ~= nil and locData.icons ~= nil then
for icon in string.gmatch(locData.icons, "%a+") do
if iconCardList[icon] == nil then
iconCardList[icon] = { }
iconCardList[icon] = {}
end
table.insert(iconCardList[icon], cardId)
end
@ -321,19 +322,19 @@ end
---@param locData Table A table containing the metadata for the card (for the correct side)
function buildConnection(cardId, iconCardList, locData)
if locData ~= nil and locData.connections ~= nil then
locationConnections[cardId] = { }
locationConnections[cardId] = {}
for icon in string.gmatch(locData.connections, "%a+") do
if iconCardList[icon] ~= nil then
for _, connectedGuid in ipairs(iconCardList[icon]) do
-- If the reciprocal exists, convert it to BiDi, otherwise add as a one-way
if locationConnections[connectedGuid] ~= nil
and (locationConnections[connectedGuid][cardId] == ONE_WAY
or locationConnections[connectedGuid][cardId] == BIDIRECTIONAL) then
or locationConnections[connectedGuid][cardId] == BIDIRECTIONAL) then
locationConnections[connectedGuid][cardId] = BIDIRECTIONAL
locationConnections[cardId][connectedGuid] = nil
else
if locationConnections[connectedGuid] == nil then
locationConnections[connectedGuid] = { }
locationConnections[connectedGuid] = {}
end
locationConnections[cardId][connectedGuid] = ONE_WAY
locationConnections[connectedGuid][cardId] = INCOMING_ONE_WAY
@ -348,10 +349,10 @@ end
-- Constructed vectors will be set to the playmat
function drawBaseConnections()
if not showLocationLinks() then
locationConnections = { }
locationConnections = {}
return
end
local cardConnectionLines = { }
local cardConnectionLines = {}
for originGuid, targetGuids in pairs(locationConnections) do
-- Objects should reliably exist at this point, but since this can be called during onUpdate the
@ -380,8 +381,8 @@ function drawDraggingConnections()
if not showLocationLinks() then
return
end
local cardConnectionLines = { }
local ownedVectors = { }
local cardConnectionLines = {}
local ownedVectors = {}
for originGuid, _ in pairs(draggingGuids) do
targetGuids = locationConnections[originGuid]
@ -389,7 +390,7 @@ function drawDraggingConnections()
-- object checks are conservative just to make sure.
local origin = getObjectFromGUID(originGuid)
if draggingGuids[originGuid] and origin ~= nil and targetGuids ~= nil then
ownedVectors[originGuid] = { }
ownedVectors[originGuid] = {}
for targetGuid, direction in pairs(targetGuids) do
local target = getObjectFromGUID(targetGuid)
if target != nil then
@ -427,9 +428,9 @@ function addBidirectionalVector(card1, card2, vectorOwner, lines)
local pos2 = vectorOwner.positionToLocal(cardPos2)
table.insert(lines, {
points = { pos1, pos2 },
color = vectorOwner == self and CONNECTION_COLOR or DRAGGING_CONNECTION_COLOR,
thickness = vectorOwner == self and CONNECTION_THICKNESS or DRAGGING_CONNECTION_THICKNESS,
points = { pos1, pos2 },
color = vectorOwner == self and CONNECTION_COLOR or DRAGGING_CONNECTION_COLOR,
thickness = vectorOwner == self and CONNECTION_THICKNESS or DRAGGING_CONNECTION_THICKNESS,
})
end
@ -451,11 +452,13 @@ function addOneWayVector(origin, target, vectorOwner, lines)
-- Calculate card distance to be closer for horizontal positions than vertical, since cards are
-- taller than they are wide
local heading = Vector(originPos):sub(targetPos):heading("y")
local distanceFromCard = DIRECTIONAL_ARROW_DISTANCE * 0.7 + DIRECTIONAL_ARROW_DISTANCE * 0.3 * math.abs(math.sin(math.rad(heading)))
local distanceFromCard = DIRECTIONAL_ARROW_DISTANCE * 0.7 +
DIRECTIONAL_ARROW_DISTANCE * 0.3 * math.abs(math.sin(math.rad(heading)))
-- Calculate the three possible arrow positions. These are offset by half the arrow length to
-- make them visually balanced by keeping the arrows centered, not tracking the point
local midpoint = Vector(originPos):add(targetPos):scale(Vector(0.5, 0.5, 0.5)):moveTowards(targetPos, ARROW_ARM_LENGTH / 2)
local midpoint = Vector(originPos):add(targetPos):scale(Vector(0.5, 0.5, 0.5)):moveTowards(targetPos,
ARROW_ARM_LENGTH / 2)
local closeToOrigin = Vector(originPos):moveTowards(targetPos, distanceFromCard + ARROW_ARM_LENGTH / 2)
local closeToTarget = Vector(targetPos):moveTowards(originPos, distanceFromCard - ARROW_ARM_LENGTH / 2)
@ -474,14 +477,16 @@ end
--- positioning and scaling, as well as highlighting connections during a drag operation
---@param lines Table List of vector line elements. Mutable, will be updated to add this arrow
function addArrowLines(arrowheadPos, originPos, vectorOwner, lines)
local arrowArm1 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", -1 * ARROW_ANGLE):add(arrowheadPos)
local arrowArm2 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", ARROW_ANGLE):add(arrowheadPos)
local arrowArm1 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y",
-1 * ARROW_ANGLE):add(arrowheadPos)
local arrowArm2 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y",
ARROW_ANGLE):add(arrowheadPos)
local head = vectorOwner.positionToLocal(arrowheadPos)
local arm1 = vectorOwner.positionToLocal(arrowArm1)
local arm2 = vectorOwner.positionToLocal(arrowArm2)
table.insert(lines, {
points = { arm1, head, arm2},
points = { arm1, head, arm2 },
color = vectorOwner == self and CONNECTION_COLOR or DRAGGING_CONNECTION_COLOR,
thickness = vectorOwner == self and CONNECTION_THICKNESS or DRAGGING_CONNECTION_THICKNESS,
})
@ -508,6 +513,7 @@ function shiftContentsRight(playerColor)
end
function shiftContents(playerColor, direction)
local guidHandler = getObjectFromGUID("123456")
local zone = guidHandler.call("getObjectByOwnerAndType", { owner = "Mythos", type = "PlayAreaZone" })
if not zone then
broadcastToColor("Scripting zone couldn't be found.", playerColor, "Red")
@ -530,8 +536,8 @@ function isInPlayArea(object)
local bounds = self.getBounds()
local position = object.getPosition()
-- Corners are arbitrary since it's all global - c1 goes down both axes, c2 goes up
local c1 = { x = bounds.center.x - bounds.size.x / 2, z = bounds.center.z - bounds.size.z / 2}
local c2 = { x = bounds.center.x + bounds.size.x / 2, z = bounds.center.z + bounds.size.z / 2}
local c1 = { x = bounds.center.x - bounds.size.x / 2, z = bounds.center.z - bounds.size.z / 2 }
local c2 = { x = bounds.center.x + bounds.size.x / 2, z = bounds.center.z + bounds.size.z / 2 }
return position.x > c1.x and position.x < c2.x and position.z > c1.z and position.z < c2.z
end
@ -582,7 +588,7 @@ function countVP()
local cardVP = tonumber(metadata.victory) or 0
if cardVP ~= 0 and not cardHasClues(cardId) then
totalVP = totalVP + cardVP
if cardVP >0 then
if cardVP > 0 then
table.insert(countedVP, getObjectFromGUID(cardId))
end
end
@ -651,8 +657,8 @@ end
-- rebuilds local snap points (could be useful in the future again)
function buildSnaps()
local upperleft = { x = 1.53, z = -1.09}
local lowerright = {x = -1.53, z = 1.55}
local upperleft = { x = 1.53, z = -1.09 }
local lowerright = { x = -1.53, z = 1.55 }
local snaps = {}
-- creates 81 snap points, for uneven rows + columns it makes a rotation snap point
@ -666,7 +672,7 @@ function buildSnaps()
-- enable rotation snaps for uneven rows / columns
if (i % 2 ~= 0) and (j % 2 ~= 0) then
snap.rotation = {0, 0, 0}
snap.rotation = { 0, 0, 0 }
snap.rotation_snap = true
end
@ -678,6 +684,6 @@ end
-- utility function
function round(num, numDecimalPlaces)
local mult = 10^(numDecimalPlaces or 0)
local mult = 10 ^ (numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
end

View File

@ -14,7 +14,7 @@ do
-- Returns the current value of the investigator counter from the playmat
---@return Integer. Number of investigators currently set on the counter
PlayAreaApi.getInvestigatorCount = function()
getInvestigatorCounter().getVar("val")
return getInvestigatorCounter().getVar("val")
end
-- Updates the current value of the investigator counter from the playmat

View File

@ -365,18 +365,16 @@ do
if uses == nil then return end
-- go through tokens to spawn
local type, token, tokenCount
local tokenCount
for i, useInfo in ipairs(uses) do
type = useInfo.type
token = useInfo.token
tokenCount = (useInfo.count or 0)
+ (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount()
if extraUses ~= nil and extraUses[type] ~= nil then
tokenCount = tokenCount + extraUses[type]
tokenCount = (useInfo.count or 0) + (useInfo.countPerInvestigator or 0) * playAreaApi.getInvestigatorCount()
if extraUses ~= nil and extraUses[useInfo.type] ~= nil then
tokenCount = tokenCount + extraUses[useInfo.type]
end
-- 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, type)
TokenManager.spawnTokenGroup(card, useInfo.token, tokenCount, (i - 1) * 0.8, useInfo.type)
end
tokenSpawnTrackerApi.markTokensSpawned(card.getGUID())
end
@ -400,9 +398,8 @@ do
---@param playerData Table Player card data structure retrieved from the DataHelper. Should be
-- the right data for this card.
internal.spawnPlayerCardTokensFromDataHelper = function(card, playerData)
token = playerData.tokenType
tokenCount = playerData.tokenCount
--log("Spawning data helper tokens for "..card.getName()..'['..card.getDescription()..']: '..tokenCount.."x "..token)
local token = playerData.tokenType
local tokenCount = playerData.tokenCount
TokenManager.spawnTokenGroup(card, token, tokenCount)
tokenSpawnTrackerApi.markTokensSpawned(card.getGUID())
end
@ -435,7 +432,6 @@ do
return 0
end
--log(card.getName() .. ' : ' .. locationData.type .. ' : ' .. locationData.value .. ' : ' .. locationData.clueSide)
if ((card.is_face_down and locationData.clueSide == 'back')
or (not card.is_face_down and locationData.clueSide == 'front')) then
if locationData.type == 'fixed' then