Merge branch 'main' into colored-broadcasts

This commit is contained in:
Chr1Z93 2024-07-01 22:49:14 +02:00
commit 67106f4d21
23 changed files with 139 additions and 96 deletions

View File

@ -30,14 +30,14 @@
"URL": "http://cloud-3.steamusercontent.com/ugc/2026086584372569912/5CB461AEAE2E59D3064D90A776EB86C46081EC78/"
},
{
"Name": "option-on",
"Name": "option_on",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/2462982115668997008/2178787B67B3C96F3419EDBAB8420E39893756BC/"
"URL": "http://cloud-3.steamusercontent.com/ugc/2024962321889555728/22ABD35CBB49A001F3A5318E4AFCFB22D24FEA39/"
},
{
"Name": "option-off",
"Name": "option_off",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/2462982115668996901/D6438ECBB11DECC6DB9987589FF526FBAD4D2368/"
"URL": "http://cloud-3.steamusercontent.com/ugc/2024962321889555661/6643E5CC9160FF4624672C255D0DF7B313DA00A5/"
},
{
"Name": "font_arkhamicons",
@ -69,16 +69,6 @@
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/2280574378889753733/F67B7B37FF7AA253B6D697E577DF54A3E76030C2/"
},
{
"Name": "option_on",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/2024962321889555728/22ABD35CBB49A001F3A5318E4AFCFB22D24FEA39/"
},
{
"Name": "option_off",
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/2024962321889555661/6643E5CC9160FF4624672C255D0DF7B313DA00A5/"
},
{
"Name": "SpeechBubble",
"Type": 0,

View File

@ -369,9 +369,9 @@ function tidyPlayerMatCoroutine()
if tekeliliHelper then
tekeliliHelper.call("spawnStoredTekelili", color)
end
end
::continue::
end
end
-- mythos area cleanup
local trash = guidReferenceApi.getObjectByOwnerAndType("Mythos", "Trash")

View File

@ -42,10 +42,11 @@ function onLoad(savedData)
color = { r = 0, g = 0, b = 0, a = 0 }
})
self.addContextMenuItem("toggle broadcasting", updateBroadcast)
self.addContextMenuItem("Toggle Broadcasting", updateBroadcast)
end
function updateBroadcast()
function updateBroadcast(playerColor)
Player[playerColor].clearSelectedObjects()
for _, tracker in ipairs(getObjectsWithTag("LinkedPhaseTracker")) do
tracker.setVar("broadcastChange", not broadcastChange)
end

View File

@ -32,7 +32,7 @@ function onload(savedData)
isSetup = false
movingCards = false
self.addContextMenuItem('Reset helper', resetHelper)
self.addContextMenuItem('Reset Helper', resetHelper)
if savedData and savedData ~= '' then
local loaded_data = JSON.decode(savedData)
@ -242,7 +242,8 @@ function finish()
0.75)
end
function resetHelper()
function resetHelper(playerColor)
Player[playerColor].clearSelectedObjects()
for i, card in ipairs(self.getObjects()) do
self.takeObject({
index = 0,
@ -269,7 +270,5 @@ function resetHelper()
isSetup = false
movingCards = false
self.reset()
print('Underworld Market Helper: Helper has been reset.')
end

View File

@ -1448,7 +1448,7 @@ function onClick_toggleOption(_, _, id)
local currentState = optionPanel[id]
local newState = not currentState
applyOptionPanelChange(id, newState)
UI.setAttribute(id, "image", newState and "option-on" or "option-off")
UI.setAttribute(id, "image", newState and "option_on" or "option_off")
end
-- color selection for playArea
@ -1542,9 +1542,9 @@ function updateOptionPanelState()
elseif (type(optionValue) == "boolean" and optionValue)
or (type(optionValue) == "string" and optionValue)
or (type(optionValue) == "table" and #optionValue ~= 0) then
UI.setAttribute(id, "image", "option-on")
UI.setAttribute(id, "image", "option_on")
else
UI.setAttribute(id, "image", "option-off")
UI.setAttribute(id, "image", "option_off")
end
end
end

View File

@ -78,7 +78,7 @@ function onCollisionEnter(collisionInfo)
local localPos = self.positionToLocal(object.getPosition())
if inArea(localPos, ENCOUNTER_DECK_AREA) or inArea(localPos, ENCOUNTER_DISCARD_AREA) then
Wait.frames(function() tokenSpawnTrackerApi.resetTokensSpawned(object.getGUID()) end, 1)
Wait.frames(function() tokenSpawnTrackerApi.resetTokensSpawned(object) end, 1)
removeTokensFromObject(object)
end
end
@ -100,7 +100,7 @@ end
function onObjectEnterContainer(container, object)
local localPos = self.positionToLocal(container.getPosition())
if inArea(localPos, ENCOUNTER_DECK_AREA) or inArea(localPos, ENCOUNTER_DISCARD_AREA) then
tokenSpawnTrackerApi.resetTokensSpawned(object.getGUID())
tokenSpawnTrackerApi.resetTokensSpawned(object)
removeTokensFromObject(object)
end
end

View File

@ -202,6 +202,7 @@ end
function addContextMenu()
self.addContextMenuItem("Change color", function(playerColor)
Player[playerColor].clearSelectedObjects()
local currentClassDisplayName = listOfClassDisplayNames[getIndexOfValue(listOfClasses, class)]
Player[playerColor].showOptionsDialog("Choose color", listOfClassDisplayNames, currentClassDisplayName,
function(_, selectedIndex)
@ -210,6 +211,7 @@ function addContextMenu()
end)
self.addContextMenuItem("Change 1st symbol", function(playerColor)
Player[playerColor].clearSelectedObjects()
local symbolList = getSymbolList()
Player[playerColor].showOptionsDialog("Choose symbol", listOfSymbols, symbolList[1], function(newSymbol)
if newSymbol == "None" then
@ -229,6 +231,7 @@ function addContextMenu()
end)
self.addContextMenuItem("Change 2nd symbol", function(playerColor)
Player[playerColor].clearSelectedObjects()
local symbolList = getSymbolList()
Player[playerColor].showOptionsDialog("Choose 2nd symbol", listOfSymbols, symbolList[2] or symbolList[1],
function(newSymbol)

View File

@ -211,10 +211,11 @@ do
if tokenType == "clue" then
offsets = internal.buildClueOffsets(card, tokenCount)
else
-- only up to 12 offset tables defined (TODO: stack more than 12 tokens and generate offsets dynamically)
-- only up to 12 offset tables defined
if tokenCount > 12 then
printToAll("Spawning maximum of 12 tokens.")
tokenCount = 12
printToAll("Attempting to spawn " .. tokenCount .. " tokens. Spawning clickable counter instead.")
TokenManager.spawnResourceCounterToken(card, tokenCount)
return
end
for i = 1, tokenCount do
offsets[i] = card.positionToWorld(PLAYER_CARD_TOKEN_OFFSETS[tokenCount][i])
@ -297,20 +298,13 @@ do
-- Checks a card for metadata to maybe replenish it
---@param card tts__Object Card object to be replenished
---@param uses table The already decoded metadata.uses (to avoid decoding again)
---@param mat tts__Object The playermat the card is placed on (for rotation and casting)
TokenManager.maybeReplenishCard = function(card, uses, mat)
TokenManager.maybeReplenishCard = function(card, uses)
-- TODO: support for cards with multiple uses AND replenish (as of yet, no official card needs that)
if uses[1].count and uses[1].replenish then
internal.replenishTokens(card, uses, mat)
internal.replenishTokens(card, uses)
end
end
-- Delegate function to the token spawn tracker. Exists to avoid circular dependencies in some callers
---@param card tts__Object Card object to reset the tokens for
TokenManager.resetTokensSpawned = function(card)
tokenSpawnTrackerApi.resetTokensSpawned(card.getGUID())
end
-- Pushes new player card data into the local copy of the Data Helper player data.
---@param dataTable table Key/Value pairs following the DataHelper style
TokenManager.addPlayerCardData = function(dataTable)
@ -483,16 +477,16 @@ do
---@param card tts__Object Card object to be replenished
---@param uses table The already decoded metadata.uses (to avoid decoding again)
---@param mat tts__Object The playermat the card is placed on (for rotation and casting)
internal.replenishTokens = function(card, uses, mat)
-- get current amount of resource tokens on the card
internal.replenishTokens = function(card, uses)
-- get current amount of matching resource tokens on the card
local clickableResourceCounter = nil
local foundTokens = 0
local searchType = string.lower(uses[1].type)
for _, obj in ipairs(searchLib.onObject(card, "isTileOrToken")) do
local memo = obj.getMemo()
if (stateTable[memo] or 0) > 0 then
if searchType == memo then
foundTokens = foundTokens + math.abs(obj.getQuantity())
obj.destruct()
elseif memo == "resourceCounter" then

View File

@ -22,8 +22,8 @@ function markTokensSpawned(cardGuid)
spawnedCardGuids[cardGuid] = true
end
function resetTokensSpawned(cardGuid)
spawnedCardGuids[cardGuid] = nil
function resetTokensSpawned(card)
spawnedCardGuids[card.getGUID()] = nil
end
function resetAll() spawnedCardGuids = {} end
@ -52,6 +52,6 @@ end
-- Listener to reset card token spawns when they enter a hand.
function onObjectEnterZone(zone, enterObject)
if zone.type == "Hand" and enterObject.type == "Card" then
resetTokensSpawned(enterObject.getGUID())
resetTokensSpawned(enterObject)
end
end

View File

@ -14,8 +14,8 @@ do
return getSpawnTracker().call("markTokensSpawned", cardGuid)
end
TokenSpawnTracker.resetTokensSpawned = function(cardGuid)
return getSpawnTracker().call("resetTokensSpawned", cardGuid)
TokenSpawnTracker.resetTokensSpawned = function(card)
return getSpawnTracker().call("resetTokensSpawned", card)
end
TokenSpawnTracker.resetAllAssetAndEvents = function()

View File

@ -63,9 +63,8 @@ function onLoad(savedData)
local loadedData = JSON.decode(savedData)
isHelperEnabled = loadedData.isHelperEnabled
end
checkOptionPanel()
createHelperXML()
updateDisplay()
checkOptionPanel()
end
function createHelperXML()

View File

@ -5,6 +5,8 @@ function checkOptionPanel()
local options = optionPanelApi.getOptions()
if options.enableCardHelpers then
setHelperState(true)
else
updateDisplay()
end
end

View File

@ -5,7 +5,8 @@ function onLoad()
end
-- rotates the alt_view_angle
function rotatePreview()
function rotatePreview(playerColor)
Player[playerColor].clearSelectedObjects()
local angle = self.alt_view_angle
if angle.y == 0 then
angle.y = 180
@ -16,7 +17,7 @@ function rotatePreview()
end
-- rotates this card and the preview
function rotateSelfAndPreview()
function rotateSelfAndPreview(playerColor)
self.setRotationSmooth(self.getRotation() + Vector(0, 180, 0))
rotatePreview()
rotatePreview(playerColor)
end

View File

@ -16,7 +16,6 @@ function onLoad(savedData)
isHelperEnabled = loadedData.isHelperEnabled
end
checkOptionPanel()
updateDisplay()
end
-- hide buttons and stop monitoring

View File

@ -46,7 +46,6 @@ function onLoad(savedData)
activeButtonIndex = loadedData.activeButtonIndex
end
checkOptionPanel()
updateDisplay()
if activeButtonIndex > 0 then
selectButton(activeButtonIndex)
@ -89,6 +88,7 @@ function createButtons()
local upgradeSheet = findUpgradeSheet()
if upgradeSheet then
for i = 1, 4 do
log(4)
if upgradeSheet.call("isUpgradeActive", i) then
table.insert(hypothesisList, customizableList[i])
end
@ -110,7 +110,7 @@ end
function findUpgradeSheet()
local matColor = playermatApi.getMatColorByPosition(self.getPosition())
local result = playermatApi.searchAroundPlaymat(matColor, "isCard")
local result = playermatApi.searchAroundPlayermat(matColor, "isCard")
for j, card in ipairs(result) do
local metadata = JSON.decode(card.getGMNotes()) or {}
if metadata.id == "09041-c" then

View File

@ -6,9 +6,21 @@ local clickableResourceCounter = nil
local foundTokens = 0
function onLoad()
self.addContextMenuItem("Add 4 resources", function(playerColor) add4(playerColor) end)
self.addContextMenuItem("Take all resources", function(playerColor) takeAll(playerColor) end)
self.addContextMenuItem("Discard all resources", function(playerColor) loseAll(playerColor) end)
self.addContextMenuItem("Add 4 resources",
function(playerColor)
Player[playerColor].clearSelectedObjects()
add4(playerColor)
end)
self.addContextMenuItem("Take all resources",
function(playerColor)
Player[playerColor].clearSelectedObjects()
takeAll(playerColor)
end)
self.addContextMenuItem("Discard all resources",
function(playerColor)
Player[playerColor].clearSelectedObjects()
loseAll(playerColor)
end)
end
function searchSelf()
@ -34,15 +46,10 @@ function add4(playerColor)
local newCount = foundTokens + 4
if clickableResourceCounter then
clickableResourceCounter.call("updateVal", newCount)
else
if newCount > 12 then
printToColor("Count increased to " .. newCount .. " resources. Spawning clickable counter instead.", playerColor)
tokenManager.spawnResourceCounterToken(self, newCount)
else
tokenManager.spawnTokenGroup(self, "resource", newCount)
end
end
end
function takeAll(playerColor)
searchSelf()

View File

@ -61,6 +61,7 @@ end
-- Create dialog window to choose sigil and create sigil-drawing button
function chooseSigil(playerColor)
Player[playerColor].clearSelectedObjects()
self.clearContextMenu()
self.addContextMenuItem("Clear Helper", deleteButtons)
@ -80,7 +81,8 @@ function chooseSigil(playerColor)
end
-- Delete button and remove sigil
function deleteButtons()
function deleteButtons(playerColor)
Player[playerColor].clearSelectedObjects()
self.clearContextMenu()
self.addContextMenuItem("Enable Helper", chooseSigil)
self.UI.setXml("")

View File

@ -17,6 +17,7 @@ function onLoad()
end
function contextFunc(playerColor, amount)
Player[playerColor].clearSelectedObjects()
deckData = {}
local options = {}

View File

@ -5,7 +5,8 @@ function onLoad()
end
-- called by context menu entry
function shortSupply(color)
function shortSupply(playerColor)
Player[playerColor].clearSelectedObjects()
local matColor = playermatApi.getMatColorByPosition(self.getPosition())
-- get draw deck and discard position
@ -15,20 +16,20 @@ function shortSupply(color)
-- error handling
if discardPos == nil then
broadcastToColor("Couldn't retrieve discard position from playermat!", color, "Red")
broadcastToColor("Couldn't retrieve discard position from playermat!", playerColor, "Red")
return
end
if drawDeck == nil then
broadcastToColor("Deck not found!", color, "Yellow")
broadcastToColor("Deck not found!", playerColor, "Yellow")
return
elseif drawDeck.type ~= "Deck" then
broadcastToColor("Deck only contains a single card!", color, "Yellow")
broadcastToColor("Deck only contains a single card!", playerColor, "Yellow")
return
end
-- discard cards, waiting 0.7 seconds between each discard to give players visiblity of the cards
broadcastToColor("Discarding top 10 cards for player color '" .. matColor .. "'.", color, "White")
broadcastToColor("Discarding top 10 cards for player color '" .. matColor .. "'.", playerColor, "White")
for i = 1, 10 do
Wait.time(function() drawDeck.takeObject({ flip = true, position = { discardPos.x, 2 + 0.075 * i, discardPos.z } }) end, .7 * (i - 1))
end

View File

@ -7,7 +7,8 @@ function onLoad()
end
-- uses the tekeli-li helper to place this card at the bottom of the deck
function returnSelf()
function returnSelf(playerColor)
Player[playerColor].clearSelectedObjects()
local helper = getTekeliliHelper()
if helper == nil then
printToAll("Couldn't find Tekeli-li Helper!")
@ -18,6 +19,7 @@ end
-- places this card below the deck of the player that triggered it
function placeBelowDeck(playerColor)
Player[playerColor].clearSelectedObjects()
local matColor = playermatApi.getMatColor(playerColor)
local deckPos = playermatApi.getDrawPosition(matColor)
local deckRot = playermatApi.returnRotation(matColor)

View File

@ -6,6 +6,7 @@ local navigationOverlayApi = require("core/NavigationOverlayApi")
local searchLib = require("util/SearchLib")
local tokenChecker = require("core/token/TokenChecker")
local tokenManager = require("core/token/TokenManager")
local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi")
-- we use this to turn off collision handling until onLoad() is complete
local collisionEnabled = false
@ -62,12 +63,12 @@ local buttonParameters = {
-- table of texture URLs
local nameToTexture = {
Guardian = "http://cloud-3.steamusercontent.com/ugc/2444972799638881117/169F4520A94FB186B54E0F2BF4BAC809844C923E/",
Mystic = "http://cloud-3.steamusercontent.com/ugc/2444972799638880413/B59966123EA41649EDCBD614167E590C8C105582/",
Guardian = "http://cloud-3.steamusercontent.com/ugc/2501268517203536128/853B9CD08FC14A8B2A08C73D8ED77E0FE235CCCB/",
Mystic = "http://cloud-3.steamusercontent.com/ugc/2501268517203536470/11C99488B9CA9236059A5F02E4A852A7C77B42A6/",
Neutral = "http://cloud-3.steamusercontent.com/ugc/2462982115659543571/5D778EA4BC682DAE97E8F59A991BCF8CB3979B04/",
Rogue = "http://cloud-3.steamusercontent.com/ugc/2444972799638880905/CFC02BF5A6140B9B4B92312AD6DC74D8DD61180B/",
Seeker = "http://cloud-3.steamusercontent.com/ugc/2444972799638881117/169F4520A94FB186B54E0F2BF4BAC809844C923E/",
Survivor = "http://cloud-3.steamusercontent.com/ugc/2444972799638880687/EEDF8F8BC3266069FECB09775845BE2501310C17/"
Rogue = "http://cloud-3.steamusercontent.com/ugc/2501268517203536767/587791B327255DB8F953B27BB9E4DE602FA32B64/",
Seeker = "http://cloud-3.steamusercontent.com/ugc/2501268517203537098/EFD9FC4CCDB105EFFDFF7A57C915CD984865760D/",
Survivor = "http://cloud-3.steamusercontent.com/ugc/2501268517203537426/14EF780606D9A449F31A007226CB48D05AA820FF/"
}
-- translation table for slot names to characters for special font
@ -344,7 +345,7 @@ function doUpkeep(_, clickedByColor, isRightClick)
end
-- maybe replenish uses on certain cards (don't continue for cards on the deck (Norman) or in the discard pile)
if cardMetadata.uses ~= nil and self.positionToLocal(obj.getPosition()).x < -1 then
if cardMetadata.uses ~= nil and self.positionToLocal(obj.getPosition()).x > -1 then
tokenManager.maybeReplenishCard(obj, cardMetadata.uses, self)
end
elseif obj.type == "Deck" and forcedLearning == false then
@ -821,7 +822,7 @@ function onCollisionEnter(collisionInfo)
local localCardPos = self.positionToLocal(object.getPosition())
if inArea(localCardPos, DECK_DISCARD_AREA) then
tokenManager.resetTokensSpawned(object)
tokenSpawnTrackerApi.resetTokensSpawned(object)
removeTokensFromObject(object)
elseif shouldSpawnTokens(object) then
spawnTokensFor(object)
@ -865,7 +866,7 @@ function onObjectEnterContainer(container, object)
local localCardPos = self.positionToLocal(object.getPosition())
if inArea(localCardPos, DECK_DISCARD_AREA) then
tokenManager.resetTokensSpawned(object)
tokenSpawnTrackerApi.resetTokensSpawned(object)
removeTokensFromObject(object)
end
end

View File

@ -62,7 +62,7 @@
<Panel class="doubleColumn-wrapper"
padding="0 17 3 3"/>
<Button class="optionToggle"
image="option-off"
image="option_off"
rectAlignment="MiddleRight"
offsetXY="-30 0"
colors="#FFFFFF|#dfdfdf"

View File

@ -1,25 +1,54 @@
<!-- Default formatting -->
<Defaults>
<Text color="black" alignment="MiddleLeft"/>
<Text class="h1" fontSize="160" font="font_teutonic-arkham"/>
<Text class="h2" fontSize="120" font="font_teutonic-arkham"/>
<Text class="p" fontSize="60" alignment="UpperLeft"/>
<Text color="black"
alignment="MiddleLeft"/>
<Text class="h1"
fontSize="160"
font="font_teutonic-arkham"/>
<Text class="h2"
fontSize="120"
font="font_teutonic-arkham"/>
<Text class="p"
fontSize="60"
alignment="UpperLeft"/>
<Panel rotation="0 0 180"/>
<Panel class="window" width="1500" height="1500" color="white" outline="white" outlineSize="10 10"/>
<Panel class="window"
width="1500"
height="1500"
color="white"
outline="white"
outlineSize="10 10"/>
<Row dontUseTableRowBackground="true"/>
<Row class="header" color="#707070"/>
<Row class="option" preferredHeight="200" color="#9e9e9e"/>
<Row class="header"
color="#707070"/>
<Row class="option"
preferredHeight="200"
color="#9e9e9e"/>
<!-- row heights: 70 x lines + 50 -->
<Row class="description" color="#cfcfcf"/>
<Row class="description"
color="#cfcfcf"/>
<Button class="optionToggle" rectAlignment="MiddleRight" offsetXY="-30 0" colors="#FFFFFF|#dfdfdf" height="160" width="288" ignoreLayout="True" fontSize="60"/>
<Button class="optionToggle"
rectAlignment="MiddleRight"
offsetXY="-30 0"
colors="#FFFFFF|#dfdfdf"
height="160"
width="288"
ignoreLayout="True"
fontSize="60"/>
</Defaults>
<!-- Option window -->
<Panel id="options" class="window" offsetXY="-580 200" scale="0.5 0.5" active="false" showAnimation="FadeIn" hideAnimation="FadeOut">
<Panel id="options"
class="window"
offsetXY="-580 200"
scale="0.5 0.5"
active="false"
showAnimation="FadeIn"
hideAnimation="FadeOut">
<TableLayout cellPadding="25 25 15 15">
<!-- Header -->
<Row class="header">
@ -32,10 +61,14 @@
<Row class="option">
<Cell>
<Text class="h2">Import trauma</Text>
<Button class="optionToggle" id="importTrauma" onClick="optionButtonClick(importTrauma)" image="option_on"/>
<Button class="optionToggle"
id="importTrauma"
onClick="optionButtonClick(importTrauma)"
image="option_on"/>
</Cell>
</Row>
<Row class="description" preferredHeight="330">
<Row class="description"
preferredHeight="330">
<Cell>
<Text class="p">Enables importing trauma values from the campaign log (custom content might give wrong values!).&#xA;Enter players in the campaign log in this order:&#xA;White, Orange, Green, Red.</Text>
</Cell>
@ -45,10 +78,14 @@
<Row class="option">
<Cell>
<Text class="h2">Tidy playermats</Text>
<Button class="optionToggle" id="tidyPlayermats" onClick="optionButtonClick(tidyPlayermats)" image="option_on"/>
<Button class="optionToggle"
id="tidyPlayermats"
onClick="optionButtonClick(tidyPlayermats)"
image="option_on"/>
</Cell>
</Row>
<Row class="description" preferredHeight="190">
<Row class="description"
preferredHeight="190">
<Cell>
<Text class="p">Controls whether the playermats should get tidied (removal of all cards and tokens).</Text>
</Cell>
@ -58,10 +95,14 @@
<Row class="option">
<Cell>
<Text class="h2">Remove drawn lines</Text>
<Button class="optionToggle" id="removeDrawnLines" onClick="optionButtonClick(removeDrawnLines)" image="option_off"/>
<Button class="optionToggle"
id="removeDrawnLines"
onClick="optionButtonClick(removeDrawnLines)"
image="option_off"/>
</Cell>
</Row>
<Row class="description" preferredHeight="120">
<Row class="description"
preferredHeight="120">
<Cell>
<Text class="p">Controls whether all drawn lines should be removed.</Text>
</Cell>