From c05238cbce7a8859bc32d3ea73d9f7291badd60f Mon Sep 17 00:00:00 2001 From: Buhallin Date: Fri, 2 Dec 2022 11:45:59 -0800 Subject: [PATCH 1/5] Automatic location connections, Phase 1 --- src/core/PlayArea.ttslua | 221 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 216 insertions(+), 5 deletions(-) diff --git a/src/core/PlayArea.ttslua b/src/core/PlayArea.ttslua index 503cc145..e7e6deec 100644 --- a/src/core/PlayArea.ttslua +++ b/src/core/PlayArea.ttslua @@ -3,14 +3,27 @@ --------------------------------------------------------- -- set true to enable debug logging -DEBUG = false +local DEBUG = true + +-- Location connection directional options +local BIDIRECTIONAL = 0 +local ONE_WAY = 1 +local CONNECTION_THICKNESS = 0.015 +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 -- we use this to turn off collision handling until onLoad() is complete -COLLISION_ENABLED = false +local collisionEnabled = false local INVESTIGATOR_COUNTER_GUID = "f182ee" local clueData = {} -spawnedLocationGUIDs = {} +local spawnedLocationGUIDs = {} + +local locations = { } +local locationConnections = { } +local draggingGuids = { } --------------------------------------------------------- -- general code @@ -35,7 +48,7 @@ function onLoad(save_state) LOCATIONS = dataHelper.getTable('LOCATIONS_DATA') self.interactable = DEBUG - Wait.time(function() COLLISION_ENABLED = true end, 1) + Wait.time(function() collisionEnabled = true end, 1) end function log(message) @@ -112,7 +125,7 @@ function updateLocations(args) end function onCollisionEnter(collision_info) - if not COLLISION_ENABLED then return end + if not collisionEnabled then return end -- check if we should spawn clues here and do so according to playercount local object = collision_info.collision_object @@ -120,9 +133,207 @@ function onCollisionEnter(collision_info) local clueCount = getClueCount(object, object.is_face_down, getInvestigatorCount()) if clueCount > 0 then spawnCluesAtLocation(clueCount, object) end end + draggingGuid = nil + maybeTrackLocation(collision_info.collision_object) end +function onCollisionExit(collisionInfo) + maybeUntrackLocation(collisionInfo.collision_object) +end + +function onObjectPickUp(player, object) + -- onCollisionExit fires first, so we have to check the card to see if it's a location we should + -- be tracking + if isInPlayArea(object) and object.getGMNotes() ~= nil and object.getGMNotes() ~= "" then + local pickedUpGuid = object.getGUID() + local metadata = JSON.decode(object.getGMNotes()) + if (metadata.type == "Location") then + draggingGuids[pickedUpGuid] = metadata + rebuildConnectionList() + end + end +end + +function onUpdate() + local needsConnectionDraw = false + for guid, _ in pairs(draggingGuids) do + local obj = getObjectFromGUID(guid) + if obj == nil or not isInPlayArea(obj) then + draggingGuids[guid] = nil + rebuildConnectionList() + end + -- Even if the last location left the play area, need one last draw to clear the lines + needsConnectionDraw = true + end + if needsConnectionDraw then + drawConnections() + end +end + +function maybeTrackLocation(card) + -- Collision checks for any part of the card overlap, but our other tracking is centerpoint + -- Ignore any collision where the centerpoint isn't in the area + if isInPlayArea(card) then + local metadata = JSON.decode(card.getGMNotes()) or { } + if metadata.type == "Location" then + locations[card.getGUID()] = metadata + rebuildConnectionList() + end + end +end + +function maybeUntrackLocation(card) + local metadata = JSON.decode(card.getGMNotes()) or { } + if metadata.type == "Location" then + locations[card.getGUID()] = nil + rebuildConnectionList() + end +end + +function rebuildConnectionList() + local iconCardList = { } + + for cardId, metadata in pairs(draggingGuids) do + buildLocListByIcon(cardId, iconCardList) + end + for cardId, metadata in pairs(locations) do + buildLocListByIcon(cardId, iconCardList) + end + + locationConnections = { } + for cardId, metadata in pairs(draggingGuids) do + buildConnection(cardId, iconCardList) + end + for cardId, metadata in pairs(locations) do + -- Build everything else + if draggingGuids[cardId] == nil then + buildConnection(cardId, iconCardList) + end + end + + drawConnections() +end + +function buildLocListByIcon(cardId, iconCardList) + local card = getObjectFromGUID(cardId) + local locData = getLocationData(card) + if locData.icons ~= nil then + for icon in string.gmatch(locData.icons, "%a+") do + if iconCardList[icon] == nil then + iconCardList[icon] = { } + end + table.insert(iconCardList[icon], card.getGUID()) + end + end +end + +function buildConnection(cardId, iconCardList) + local card = getObjectFromGUID(cardId) + local locData = getLocationData(card) + if locData.connections ~= nil then + locationConnections[card.getGUID()] = { } + 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][card.getGUID()] ~= nil then + locationConnections[connectedGuid][card.getGUID()] = BIDIRECTIONAL + else + locationConnections[card.getGUID()][connectedGuid] = ONE_WAY + end + end + end + end + end +end + +function getLocationData(card) + if card == nil then + return { } + end + if card.is_face_down then + return JSON.decode(card.getGMNotes()).locationBack + else + return JSON.decode(card.getGMNotes()).locationFront + end +end + +function drawConnections() + local cardConnectionLines = { } + for originGuid, targetGuids in pairs(locationConnections) do + local originCard = getObjectFromGUID(originGuid) + for targetGuid, direction in pairs(targetGuids) do + local targetCard = getObjectFromGUID(targetGuid) + if direction == BIDIRECTIONAL then + addBidirectionalVector(originCard, targetCard, cardConnectionLines) + elseif direction == ONE_WAY then + addOneWayVector(originCard, targetCard, cardConnectionLines) + end + end + end + self.setVectorLines(cardConnectionLines) +end + +function addBidirectionalVector(card1, card2, lines) + table.insert(lines, { + points = { self.positionToLocal(card1.getPosition()), self.positionToLocal(card2.getPosition()) }, + color = CONNECTION_COLOR, + thickness = CONNECTION_THICKNESS, + }); +end + +function addOneWayVector(origin, target, lines) + -- Start with the BiDi then add the arrow lines to it + addBidirectionalVector(origin, target, lines) + local originPos = origin.getPosition() + local targetPos = target.getPosition() + + -- 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))) + + -- 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 closeToOrigin = Vector(originPos):moveTowards(targetPos, distanceFromCard + ARROW_ARM_LENGTH / 2) + local closeToTarget = Vector(targetPos):moveTowards(originPos, distanceFromCard - ARROW_ARM_LENGTH / 2) + + if (originPos:distance(closeToOrigin) > originPos:distance(closeToTarget)) then + addArrowLines(midpoint, originPos, lines) + else + addArrowLines(closeToOrigin, originPos, lines) + addArrowLines(closeToTarget, originPos, lines) + end +end + +function addArrowLines(arrowheadPos, originPos, 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 head = self.positionToLocal(arrowheadPos) + local arm1 = self.positionToLocal(arrowArm1) + local arm2 = self.positionToLocal(arrowArm2) + table.insert(lines, { + points = { arm1, head, arm2}, + color = CONNECTION_COLOR, + thickness = CONNECTION_THICKNESS + }) +end + + function getInvestigatorCount() local investigatorCounter = getObjectFromGUID('f182ee') return investigatorCounter.getVar("val") end + +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} + + return position.x > c1.x and position.x < c2.x and position.z > c1.z and position.z < c2.z +end From 5d1e23a91b3d77163a48c1c38ddb09e333bc86cc Mon Sep 17 00:00:00 2001 From: Buhallin Date: Fri, 2 Dec 2022 17:42:19 -0800 Subject: [PATCH 2/5] Finalize location connections Includes some bugfixes and further optimizations --- src/core/PlayArea.ttslua | 109 ++++++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 19 deletions(-) diff --git a/src/core/PlayArea.ttslua b/src/core/PlayArea.ttslua index e7e6deec..ed2fb5c9 100644 --- a/src/core/PlayArea.ttslua +++ b/src/core/PlayArea.ttslua @@ -3,17 +3,22 @@ --------------------------------------------------------- -- set true to enable debug logging -local DEBUG = true +local DEBUG = false -- Location connection directional options local BIDIRECTIONAL = 0 local ONE_WAY = 1 + +-- Connector draw parameters local CONNECTION_THICKNESS = 0.015 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.525 + -- we use this to turn off collision handling until onLoad() is complete local collisionEnabled = false @@ -124,23 +129,28 @@ function updateLocations(args) end end -function onCollisionEnter(collision_info) +function onCollisionEnter(collisionInfo) if not collisionEnabled then return end -- check if we should spawn clues here and do so according to playercount - local object = collision_info.collision_object + local object = collisionInfo.collision_object if getLocation(object) ~= nil and spawnedLocationGUIDs[object.getGUID()] == nil then local clueCount = getClueCount(object, object.is_face_down, getInvestigatorCount()) if clueCount > 0 then spawnCluesAtLocation(clueCount, object) end end - draggingGuid = nil - maybeTrackLocation(collision_info.collision_object) + draggingGuids[object.getGUID()] = nil + maybeTrackLocation(collisionInfo.collision_object) end function onCollisionExit(collisionInfo) maybeUntrackLocation(collisionInfo.collision_object) end +-- Destroyed objects don't trigger onCollisionExit(), so check on destruction to untrack as well +function onObjectDestroy(object) + maybeUntrackLocation(object) +end + function onObjectPickUp(player, object) -- onCollisionExit fires first, so we have to check the card to see if it's a location we should -- be tracking @@ -155,21 +165,30 @@ function onObjectPickUp(player, object) end function onUpdate() + -- Due to the frequence of onUpdate calls, ensure that we only process any changes to the + -- connection list once, and only redraw once + local needsConnectionRebuild = false local needsConnectionDraw = false for guid, _ in pairs(draggingGuids) do local obj = getObjectFromGUID(guid) if obj == nil or not isInPlayArea(obj) then draggingGuids[guid] = nil - rebuildConnectionList() + needsConnectionRebuild = true end -- Even if the last location left the play area, need one last draw to clear the lines needsConnectionDraw = true end + if (needsConnectionRebuild) then + rebuildConnectionList() + end if needsConnectionDraw then drawConnections() end end +-- Checks the given card and adds it to the list of locations tracked for connection purposes. +-- A card will be added to the tracking if it is a location in the play area (based on centerpoint). +-- @param A card object, possibly a location. function maybeTrackLocation(card) -- Collision checks for any part of the card overlap, but our other tracking is centerpoint -- Ignore any collision where the centerpoint isn't in the area @@ -178,18 +197,28 @@ function maybeTrackLocation(card) if metadata.type == "Location" then locations[card.getGUID()] = metadata rebuildConnectionList() + drawConnections() end end end +-- Stop tracking a location for connection drawing. This should be called for both collision exit +-- and destruction, as a destroyed object does not trigger collision exit. An object can also be +-- deleted mid-drag, but the ordering for drag events means we can't clear those here and those will +-- be cleared in the next onUpdate() cycle. +-- @param card Card to (maybe) stop tracking function maybeUntrackLocation(card) - local metadata = JSON.decode(card.getGMNotes()) or { } - if metadata.type == "Location" then + if locations[card.getGUID()] ~= nil then locations[card.getGUID()] = nil rebuildConnectionList() + drawConnections() end end +-- Builds a list of GUID to GUID connection information based on the currently tracked locations. +-- This will update the connection information and store it in the locationConnections data member, +-- but does not draw those connections. This should often be followed by a call to +-- drawConnections() function rebuildConnectionList() local iconCardList = { } @@ -210,10 +239,11 @@ function rebuildConnectionList() buildConnection(cardId, iconCardList) end end - - drawConnections() end +-- Extracts the card's icon string into a list of individual location icons +-- @param cardID GUID of the card to pull the icon data from +-- @param iconCardList A table of icon->GUID list. Mutable, will be updated by this method function buildLocListByIcon(cardId, iconCardList) local card = getObjectFromGUID(cardId) local locData = getLocationData(card) @@ -227,6 +257,10 @@ function buildLocListByIcon(cardId, iconCardList) end end +-- Builds the connections for the given cardID by finding matching icons and adding them to the +-- Playarea's locationConnections table. +-- @param cardId GUID of the card to build the connections for +-- @param iconCardList A table of icon->GUID List. Used to find matching icons for connections. function buildConnection(cardId, iconCardList) local card = getObjectFromGUID(cardId) local locData = getLocationData(card) @@ -248,6 +282,10 @@ function buildConnection(cardId, iconCardList) end end +-- Helper method to extract the location metadata from a card based on whether it's front or back +-- is showing. +-- @param card Card object to extract data from +-- @return Table with either the locationFront or locationBack metadata structure function getLocationData(card) if card == nil then return { } @@ -259,35 +297,61 @@ function getLocationData(card) end end +-- Draws the lines for connections currently in locationConnections. function drawConnections() local cardConnectionLines = { } + for originGuid, targetGuids in pairs(locationConnections) do - local originCard = getObjectFromGUID(originGuid) - for targetGuid, direction in pairs(targetGuids) do - local targetCard = getObjectFromGUID(targetGuid) - if direction == BIDIRECTIONAL then - addBidirectionalVector(originCard, targetCard, cardConnectionLines) - elseif direction == ONE_WAY then - addOneWayVector(originCard, targetCard, cardConnectionLines) + -- Objects should reliably exist at this point, but since this can be called during onUpdate the + -- object checks are conservative just to make sure. + local origin = getObjectFromGUID(originGuid) + if origin != nil then + for targetGuid, direction in pairs(targetGuids) do + local target = getObjectFromGUID(targetGuid) + if target != nil then + if direction == BIDIRECTIONAL then + addBidirectionalVector(origin, target, cardConnectionLines) + elseif direction == ONE_WAY then + addOneWayVector(origin, target, cardConnectionLines) + end + end end end end self.setVectorLines(cardConnectionLines) end +-- Draws a bidirectional location connection between the two cards, adding the lines to do so to the +-- given lines list. +-- @param card1 One of the card objects to connect +-- @param card2 The other card object to connect +-- @param lines List of vector line elements. Mutable, will be updated to add this connector function addBidirectionalVector(card1, card2, lines) + local cardPos1 = card1.getPosition() + local cardPos2 = card2.getPosition() + cardPos1.y = CONNECTION_LINE_Y + cardPos2.y = CONNECTION_LINE_Y + local pos1 = self.positionToLocal(cardPos1) + local pos2 = self.positionToLocal(cardPos2) table.insert(lines, { - points = { self.positionToLocal(card1.getPosition()), self.positionToLocal(card2.getPosition()) }, + points = { pos1, pos2 }, color = CONNECTION_COLOR, thickness = CONNECTION_THICKNESS, }); end +-- Draws a one-way location connection between the two cards, adding the lines to do so to the +-- given lines list. Arrows will point towards the target card. +-- @param origin Origin card in the connection +-- @param target Target card object to connect +-- @param lines List of vector line elements. Mutable, will be updated to add this connector function addOneWayVector(origin, target, lines) -- Start with the BiDi then add the arrow lines to it addBidirectionalVector(origin, target, lines) local originPos = origin.getPosition() local targetPos = target.getPosition() + originPos.y = CONNECTION_LINE_Y + targetPos.y = CONNECTION_LINE_Y -- Calculate card distance to be closer for horizontal positions than vertical, since cards are -- taller than they are wide @@ -308,6 +372,10 @@ function addOneWayVector(origin, target, lines) end end +-- Draws an arrowhead at the given position. +-- @param arrowheadPosition Centerpoint of the arrowhead to draw (NOT the tip of the arrow) +-- @param originPos Origin point of the connection, used to position the arrow arms +-- @param lines List of vector line elements. Mutable, will be updated to add this arrow function addArrowLines(arrowheadPos, originPos, 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) @@ -322,12 +390,15 @@ function addArrowLines(arrowheadPos, originPos, lines) }) end - function getInvestigatorCount() local investigatorCounter = getObjectFromGUID('f182ee') return investigatorCounter.getVar("val") end +-- Check to see if the given object is within the bounds of the play area, based solely on the X and +-- Z coordinates, ignoring height +-- @param object Object to check +-- @return True if the object is inside the play area function isInPlayArea(object) local bounds = self.getBounds() local position = object.getPosition() From 1af38ee3ae5f6e2b1fe593481990152ee8ebeb99 Mon Sep 17 00:00:00 2001 From: Buhallin Date: Sun, 4 Dec 2022 23:54:34 -0800 Subject: [PATCH 3/5] Handle connections for double-sided and locked locations --- src/core/PlayArea.ttslua | 41 ++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/core/PlayArea.ttslua b/src/core/PlayArea.ttslua index ed2fb5c9..902f32ae 100644 --- a/src/core/PlayArea.ttslua +++ b/src/core/PlayArea.ttslua @@ -17,7 +17,7 @@ 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.525 +local CONNECTION_LINE_Y = 1.529 -- we use this to turn off collision handling until onLoad() is complete local collisionEnabled = false @@ -30,15 +30,24 @@ local locations = { } local locationConnections = { } local draggingGuids = { } +local locationData + --------------------------------------------------------- -- general code --------------------------------------------------------- -function onSave() return JSON.encode(spawnedLocationGUIDs) end +function onSave() + return JSON.encode({ + spawnedLocations = spawnedLocationGUIDs, + trackedLocations = locations + }) +end -function onLoad(save_state) +function onLoad(saveState) -- records locations we have spawned clues for - spawnedLocationGUIDs = JSON.decode(save_state) or {} + local save = JSON.decode(saveState) or { } + spawnedLocationGUIDs = save.spawnedLocations or { } + locations = save.trackedLocations or { } local TOKEN_DATA = Global.getTable('TOKEN_DATA') clueData = { @@ -50,7 +59,7 @@ function onLoad(save_state) } local dataHelper = getObjectFromGUID('708279') - LOCATIONS = dataHelper.getTable('LOCATIONS_DATA') + locationData = dataHelper.getTable('LOCATIONS_DATA') self.interactable = DEBUG Wait.time(function() collisionEnabled = true end, 1) @@ -66,7 +75,7 @@ end -- try the compound key then the name alone as default function getLocation(object) - return LOCATIONS[object.getName() .. '_' .. object.getGUID()] or LOCATIONS[object.getName()] + return locationData[object.getName() .. '_' .. object.getGUID()] or locationData[object.getName()] end -- Return the number of clues to spawn on this location @@ -125,7 +134,7 @@ function updateLocations(args) local custom_data_helper = getObjectFromGUID(args[1]) for k, v in pairs(custom_data_helper.getTable("LOCATIONS_DATA")) do - LOCATIONS[k] = v + locationData[k] = v end end @@ -208,7 +217,9 @@ end -- be cleared in the next onUpdate() cycle. -- @param card Card to (maybe) stop tracking function maybeUntrackLocation(card) - if locations[card.getGUID()] ~= nil then + -- Locked objects no longer collide (hence triggering an exit event) but are still in the play + -- area. If the object is now locked, don't remove it. + if locations[card.getGUID()] ~= nil and not card.locked then locations[card.getGUID()] = nil rebuildConnectionList() drawConnections() @@ -222,6 +233,7 @@ end function rebuildConnectionList() local iconCardList = { } + -- Build a list of cards with each icon as their location ID for cardId, metadata in pairs(draggingGuids) do buildLocListByIcon(cardId, iconCardList) end @@ -229,12 +241,12 @@ function rebuildConnectionList() buildLocListByIcon(cardId, iconCardList) end + -- Pair up all the icons locationConnections = { } for cardId, metadata in pairs(draggingGuids) do buildConnection(cardId, iconCardList) end for cardId, metadata in pairs(locations) do - -- Build everything else if draggingGuids[cardId] == nil then buildConnection(cardId, iconCardList) end @@ -247,7 +259,7 @@ end function buildLocListByIcon(cardId, iconCardList) local card = getObjectFromGUID(cardId) local locData = getLocationData(card) - if locData.icons ~= nil then + if locData ~= nil and locData.icons ~= nil then for icon in string.gmatch(locData.icons, "%a+") do if iconCardList[icon] == nil then iconCardList[icon] = { } @@ -264,7 +276,7 @@ end function buildConnection(cardId, iconCardList) local card = getObjectFromGUID(cardId) local locData = getLocationData(card) - if locData.connections ~= nil then + if locData ~= nil and locData.connections ~= nil then locationConnections[card.getGUID()] = { } for icon in string.gmatch(locData.connections, "%a+") do if iconCardList[icon] ~= nil then @@ -272,7 +284,7 @@ function buildConnection(cardId, iconCardList) -- If the reciprocal exists, convert it to BiDi, otherwise add as a one-way if locationConnections[connectedGuid] ~= nil and locationConnections[connectedGuid][card.getGUID()] ~= nil then - locationConnections[connectedGuid][card.getGUID()] = BIDIRECTIONAL + locationConnections[connectedGuid][card.getGUID()] = BIDIRECTIONAL else locationConnections[card.getGUID()][connectedGuid] = ONE_WAY end @@ -285,10 +297,11 @@ end -- Helper method to extract the location metadata from a card based on whether it's front or back -- is showing. -- @param card Card object to extract data from --- @return Table with either the locationFront or locationBack metadata structure +-- @return Table with either the locationFront or locationBack metadata structure, or nil if the +-- metadata doesn't exist function getLocationData(card) if card == nil then - return { } + return nil end if card.is_face_down then return JSON.decode(card.getGMNotes()).locationBack From 2239133013c2439c3ae813be84bd34813721c3f7 Mon Sep 17 00:00:00 2001 From: Buhallin Date: Fri, 30 Dec 2022 20:43:04 -0800 Subject: [PATCH 4/5] Disable automatic location connections for some scenarios The excluded scenarios have very complex connection limitations beyond what's on the cards; we should handle them eventually, but for now we just don't draw the connections for those scenarios. --- src/core/PlayArea.ttslua | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/core/PlayArea.ttslua b/src/core/PlayArea.ttslua index cf81fe85..5afff938 100644 --- a/src/core/PlayArea.ttslua +++ b/src/core/PlayArea.ttslua @@ -35,6 +35,10 @@ local SHIFT_EXCLUSION = { ["f182ee"] = true, ["721ba2"] = true } +local LOC_LINK_EXCLUDE_SCENARIOS = { + ["Devil Reef"] = true, + ["The Witching Hour"] = true, +} local INVESTIGATOR_COUNTER_GUID = "f182ee" local PLAY_AREA_ZONE_GUID = "a2f932" @@ -119,7 +123,7 @@ end function onObjectPickUp(player, object) -- onCollisionExit fires first, so we have to check the card to see if it's a location we should -- be tracking - if isInPlayArea(object) and object.getGMNotes() ~= nil and object.getGMNotes() ~= "" then + if showLocationLinks() and isInPlayArea(object) and object.getGMNotes() ~= nil and object.getGMNotes() ~= "" then local pickedUpGuid = object.getGUID() local metadata = JSON.decode(object.getGMNotes()) if (metadata.type == "Location") then @@ -157,7 +161,7 @@ end function maybeTrackLocation(card) -- Collision checks for any part of the card overlap, but our other tracking is centerpoint -- Ignore any collision where the centerpoint isn't in the area - if isInPlayArea(card) then + if showLocationLinks() and isInPlayArea(card) then local metadata = JSON.decode(card.getGMNotes()) or { } if metadata.type == "Location" then locations[card.getGUID()] = metadata @@ -187,6 +191,11 @@ end -- but does not draw those connections. This should often be followed by a call to -- drawConnections() function rebuildConnectionList() + if not showLocationLinks() then + locationConnections = { } + return + end + local iconCardList = { } -- Build a list of cards with each icon as their location ID @@ -268,6 +277,10 @@ end -- Draws the lines for connections currently in locationConnections. function drawConnections() + if not showLocationLinks() then + locationConnections = { } + return + end local cardConnectionLines = { } for originGuid, targetGuids in pairs(locationConnections) do @@ -422,4 +435,11 @@ end function onScenarioChanged(scenarioName) currentScenario = scenarioName + if not showLocationLinks() then + broadcastToAll("Automatic location connections not available for this scenario") + end +end + +function showLocationLinks() + return not LOC_LINK_EXCLUDE_SCENARIOS[currentScenario] end From 45d62067ca39758351d1625170ade40b5e842aca Mon Sep 17 00:00:00 2001 From: Buhallin Date: Sat, 31 Dec 2022 20:55:03 -0800 Subject: [PATCH 5/5] Cleanup from comments --- src/core/PlayArea.ttslua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/PlayArea.ttslua b/src/core/PlayArea.ttslua index 5afff938..3fa91628 100644 --- a/src/core/PlayArea.ttslua +++ b/src/core/PlayArea.ttslua @@ -5,7 +5,7 @@ local tokenManager = require("core/token/TokenManager") --------------------------------------------------------- -- set true to enable debug logging -local DEBUG = true +local DEBUG = false -- Location connection directional options local BIDIRECTIONAL = 0 @@ -319,7 +319,7 @@ function addBidirectionalVector(card1, card2, lines) points = { pos1, pos2 }, color = CONNECTION_COLOR, thickness = CONNECTION_THICKNESS, - }); + }) end -- Draws a one-way location connection between the two cards, adding the lines to do so to the