diff --git a/src/core/GUIDReferenceHandler.ttslua b/src/core/GUIDReferenceHandler.ttslua index 1a187064..c125f5d1 100644 --- a/src/core/GUIDReferenceHandler.ttslua +++ b/src/core/GUIDReferenceHandler.ttslua @@ -51,6 +51,7 @@ local GuidReferences = { DeckImporter = "a28140", DoomCounter = "85c4c6", DoomInPlayCounter = "652ff3", + InvestigatorCounter = "f182ee", MasterClueCounter = "4a3aa4", MythosArea = "9f334f", NavigationOverlayHandler = "797ede", diff --git a/src/core/PlayArea.ttslua b/src/core/PlayArea.ttslua index cfdf7932..9a284a59 100644 --- a/src/core/PlayArea.ttslua +++ b/src/core/PlayArea.ttslua @@ -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 diff --git a/src/core/PlayAreaApi.ttslua b/src/core/PlayAreaApi.ttslua index a66bc39e..e903e2c8 100644 --- a/src/core/PlayAreaApi.ttslua +++ b/src/core/PlayAreaApi.ttslua @@ -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 diff --git a/src/core/token/TokenManager.ttslua b/src/core/token/TokenManager.ttslua index 192d7aad..297c7061 100644 --- a/src/core/token/TokenManager.ttslua +++ b/src/core/token/TokenManager.ttslua @@ -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