diff --git a/src/accessories/CleanUpHelper.ttslua b/src/accessories/CleanUpHelper.ttslua index a42fd377..85b95587 100644 --- a/src/accessories/CleanUpHelper.ttslua +++ b/src/accessories/CleanUpHelper.ttslua @@ -168,6 +168,12 @@ function resetDoomCounter() else printToAll("Doom counter could not be found.", "Yellow") end + + -- reset subtractDoom setting + local doomInPlayCounter = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DoomInPlayCounter") + if doomInPlayCounter ~= nil then + toggleSubtractDoom(false) + end end -- adds the ignore tag to the custom data helper diff --git a/src/core/DoomCounter.ttslua b/src/core/DoomCounter.ttslua index ab91f407..4f4167cb 100644 --- a/src/core/DoomCounter.ttslua +++ b/src/core/DoomCounter.ttslua @@ -71,13 +71,28 @@ function onNumberTyped(_, number) end -- called by updateVal and addVal to broadcast total doom in play or on the agenda --- shows the "Doom on the Agenda / Doom Treshold" if metadata is present +-- shows "Doom on the Agenda / Doom Threshold" if metadata is present -- otherwise shows total "Doom in Play" function broadcastDoom(val) + local md = getDoomMetadata() + local mod = getDoomThresholdModifier() + local invCount = playAreaApi.getInvestigatorCount() + + -- maybe apply additional doom threshold for solo play + local soloDoomThreshold = 0 + if invCount == 1 then + soloDoomThreshold = md.additionalDoomForSolo or 0 + end + + -- sum the doom thresholds and modifiers + local doomThreshold = (md.doomThreshold or 0) + mod + (md.doomThresholdPerInvestigator or 0) * invCount + soloDoomThreshold + local doomInPlayCounter = guidReferenceApi.getObjectByOwnerAndType("Mythos", "DoomInPlayCounter") + if doomInPlayCounter and md.subtractDoomInPlay then + toggleSubtractDoom(true) + end local doomInPlay = doomInPlayCounter and doomInPlayCounter.call("getDoomCount") or 0 local totalDoom = val + doomInPlay - local doomThreshold = getDoomThreshold() local broadcastParts = {} @@ -107,6 +122,11 @@ function broadcastDoom(val) end broadcastToAll(table.concat(broadcastParts, "")) + + -- maybe let players know about modifier + if mod ~= 0 then + printToAll("Doom Threshold was modified by " .. mod .. " due to cards in play.", "Orange") + end end -- called by "Reset" button to remove doom @@ -122,32 +142,50 @@ function startReset() end -- get doom threshold from top card of Agenda deck -function getDoomThreshold() - local agendaPos = { -2.72, 1.6, 0.37 } +function getDoomMetadata() + local agendaPos = Vector(-2.72, 1.6, 0.37) local searchResult = searchLib.atPosition(agendaPos, "isCardOrDeck") if #searchResult == 1 then local obj = searchResult[1] if obj.type == "Card" then - return getDoomThresholdFromGMNotes(obj.getGMNotes()) + return JSON.decode(obj.getGMNotes()) or {} else -- handle agenda deck local containedObjects = obj.getData().ContainedObjects local topCardData = containedObjects[#containedObjects] - return getDoomThresholdFromGMNotes(topCardData.GMNotes) + return JSON.decode(topCardData.GMNotes) or {} end end - return nil + return {} end --- decodes the gm notes and return the doom treshhold -function getDoomThresholdFromGMNotes(notes) - local metadata = JSON.decode(notes) or {} - if metadata.doomThresholdPerInvestigator then - return metadata.doomThresholdPerInvestigator * playAreaApi.getInvestigatorCount() + metadata.doomThreshold - else - return metadata.doomThreshold +function getDoomThresholdModifier() + local mod = 0 + local appliedModifierGUIDs = {} + + -- check playarea + local playAreaZone = guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayAreaZone") + for _, obj in ipairs(playAreaZone.getObjects()) do + if not obj.is_face_down and obj.type == "Card" then + local md = JSON.decode(obj.getGMNotes()) or {} + mod = mod + (md.modifyDoomThreshold or 0) + appliedModifierGUIDs[obj.getGUID()] = true + end end + + -- check mythos area (make sure we don't apply cards twice that are in both areas) + local searchPos = Vector(-1.31, 2, -4) + local searchRot = Vector(0, 270, 0) + local searchSize = Vector(25, 1, 13.5) + local searchFilter = "isCard" + for _, obj in ipairs(searchLib.inArea(searchPos, searchRot, searchSize, searchFilter)) do + if not obj.is_face_down and appliedModifierGUIDs[obj.getGUID()] == nil then + local md = JSON.decode(obj.getGMNotes()) or {} + mod = mod + (md.modifyDoomThreshold or 0) + end + end + return mod end -- XML UI functions diff --git a/src/core/DoomInPlayCounter.ttslua b/src/core/DoomInPlayCounter.ttslua index e2c4ab21..b2898429 100644 --- a/src/core/DoomInPlayCounter.ttslua +++ b/src/core/DoomInPlayCounter.ttslua @@ -45,8 +45,12 @@ function onLoad(savedData) Wait.time(updateCounter, 2, -1) end -function toggleSubtractDoom() - subtractDoom = not subtractDoom +function toggleSubtractDoom(override) + if override then + subtractDoom = override + else + subtractDoom = not subtractDoom + end updateSave() if subtractDoom then diff --git a/src/playermat/ClueCounter.ttslua b/src/playermat/ClueCounter.ttslua index a08e0a4b..42fafadd 100644 --- a/src/playermat/ClueCounter.ttslua +++ b/src/playermat/ClueCounter.ttslua @@ -31,10 +31,10 @@ function onLoad() searchParam.filter = "isClue" -- start loop - Wait.time(countItems, 1.5, -1) + Wait.time(countItems, 1.75, -1) end --- activated once per second, counts clues on the playermat +-- counts clues on the playermat function countItems() local totalValue = 0 for _, item in ipairs(getClues()) do diff --git a/src/util/SearchLib.ttslua b/src/util/SearchLib.ttslua index 1700e51c..543cf6b6 100644 --- a/src/util/SearchLib.ttslua +++ b/src/util/SearchLib.ttslua @@ -18,10 +18,7 @@ do ---@param direction? table Direction (positive is up) ---@param maxDistance? number Distance for the cast local function returnSearchResult(pos, rot, size, filter, direction, maxDistance) - local filterFunc - if filter then - filterFunc = filterFunctions[filter] - end + local filterFunc = filter and filterFunctions[filter] local searchResult = Physics.cast({ origin = pos, direction = direction or { 0, 1, 0 },