diff --git a/objects/Playermat1White.8b081b.luascriptstate b/objects/Playermat1White.8b081b.luascriptstate index 22c042f5..b07d33f8 100644 --- a/objects/Playermat1White.8b081b.luascriptstate +++ b/objects/Playermat1White.8b081b.luascriptstate @@ -1,11 +1,14 @@ { - "activeInvestigatorClass": "Neutral", - "activeInvestigatorId": "00000", + "activeInvestigatorData": { + "class": "Neutral", + "id": "00000" + }, "isClassTextureEnabled": true, "isDrawButtonVisible": false, "optionPanelData": { "slotEditing": false }, + "optionPanelVisibility": "", "playerColor": "White", "slotData": [ "any", diff --git a/objects/Playermat2Orange.bd0ff4.luascriptstate b/objects/Playermat2Orange.bd0ff4.luascriptstate index 5ddad419..12215f11 100644 --- a/objects/Playermat2Orange.bd0ff4.luascriptstate +++ b/objects/Playermat2Orange.bd0ff4.luascriptstate @@ -1,11 +1,14 @@ { - "activeInvestigatorClass": "Neutral", - "activeInvestigatorId": "00000", + "activeInvestigatorData": { + "class": "Neutral", + "id": "00000" + }, "isClassTextureEnabled": true, "isDrawButtonVisible": false, "optionPanelData": { "slotEditing": false }, + "optionPanelVisibility": "", "playerColor": "Orange", "slotData": [ "any", diff --git a/objects/Playermat3Green.383d8b.luascriptstate b/objects/Playermat3Green.383d8b.luascriptstate index df95a2d1..11d73e80 100644 --- a/objects/Playermat3Green.383d8b.luascriptstate +++ b/objects/Playermat3Green.383d8b.luascriptstate @@ -1,11 +1,14 @@ { - "activeInvestigatorClass": "Neutral", - "activeInvestigatorId": "00000", + "activeInvestigatorData": { + "class": "Neutral", + "id": "00000" + }, "isClassTextureEnabled": true, "isDrawButtonVisible": false, "optionPanelData": { "slotEditing": false }, + "optionPanelVisibility": "", "playerColor": "Green", "slotData": [ "any", diff --git a/objects/Playermat4Red.0840d5.luascriptstate b/objects/Playermat4Red.0840d5.luascriptstate index e99b5a79..cd96b2c8 100644 --- a/objects/Playermat4Red.0840d5.luascriptstate +++ b/objects/Playermat4Red.0840d5.luascriptstate @@ -1,11 +1,14 @@ { - "activeInvestigatorClass": "Neutral", - "activeInvestigatorId": "00000", + "activeInvestigatorData": { + "class": "Neutral", + "id": "00000" + }, "isClassTextureEnabled": true, "isDrawButtonVisible": false, "optionPanelData": { "slotEditing": false }, + "optionPanelVisibility": "", "playerColor": "Red", "slotData": [ "any", diff --git a/src/accessories/CleanUpHelper.ttslua b/src/accessories/CleanUpHelper.ttslua index e0f47b43..9be7d435 100644 --- a/src/accessories/CleanUpHelper.ttslua +++ b/src/accessories/CleanUpHelper.ttslua @@ -356,12 +356,6 @@ function tidyPlayerMatCoroutine() maybeTrashObject(obj, trash) end - -- reset "activeInvestigatorId" and "...class" - local mat = guidReferenceApi.getObjectByOwnerAndType(color, "Playermat") - mat.setVar("activeInvestigatorId", "00000") - mat.setVar("activeInvestigatorClass", "Neutral") - mat.call("updateTexture") - coWaitFrames(5) -- maybe respawn tekelili cards @@ -370,6 +364,10 @@ function tidyPlayerMatCoroutine() end end end + + -- reset "activeInvestigatorId" and "...class" + playermatApi.setActiveInvestigatorData("All", {class = "Neutral", id = "00000"}) + playermatApi.updateTexture("All") end -- mythos area cleanup diff --git a/src/playermat/Playermat.ttslua b/src/playermat/Playermat.ttslua index 017847a8..c66a933a 100644 --- a/src/playermat/Playermat.ttslua +++ b/src/playermat/Playermat.ttslua @@ -12,19 +12,19 @@ local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi") local availableOptions = { ["PERSONAL SETTINGS"] = { { - id = "slotEditing", - title = "Enable Slot Edit Mode", - type = "toggle" + id = "slotEditing", + title = "Enable Slot Edit Mode", + type = "toggle" }, { - id = "textureSelect", - title = "Select Playermat Texture", - type = "button" + id = "textureSelect", + title = "Select Playermat Texture", + type = "button" }, { - id = "handColorSelect", - title = "Select Hand Color", - type = "button" + id = "handColorSelect", + title = "Select Hand Color", + type = "button" } } } @@ -119,40 +119,42 @@ local defaultSlotData = { "any", "any", "any", "Accessory", "Arcane", "Arcane", "Body" } --- global variables for access -activeInvestigatorClass = "Neutral" -activeInvestigatorId = "00000" -hasDES = false - +local activeInvestigatorData = {} +local hasDES = false local isClassTextureEnabled = true local isDrawButtonVisible = false +local optionPanelVisibility = "" -- table of type-object reference pairs of all owned objects local ownedObjects = {} local matColor = self.getMemo() -function onSave() - return JSON.encode({ - activeInvestigatorClass = activeInvestigatorClass, - activeInvestigatorId = activeInvestigatorId, - isClassTextureEnabled = isClassTextureEnabled, - isDrawButtonVisible = isDrawButtonVisible, - optionPanelData = optionPanelData, - playerColor = playerColor, - slotData = slotData +function updateSave() + optionPanelVisibility = self.UI.getAttribute("optionPanelMain", "visibility") or "" + self.script_state = JSON.encode({ + activeInvestigatorData = activeInvestigatorData, + isClassTextureEnabled = isClassTextureEnabled, + isDrawButtonVisible = isDrawButtonVisible, + optionPanelData = optionPanelData, + optionPanelVisibility = optionPanelVisibility, + playerColor = playerColor, + slotData = slotData }) end function onLoad(savedData) if savedData and savedData ~= "" then - local loadedData = JSON.decode(savedData) - activeInvestigatorClass = loadedData.activeInvestigatorClass - activeInvestigatorId = loadedData.activeInvestigatorId - isClassTextureEnabled = loadedData.isClassTextureEnabled - isDrawButtonVisible = loadedData.isDrawButtonVisible - optionPanelData = loadedData.optionPanelData - playerColor = loadedData.playerColor - slotData = loadedData.slotData + local loadedData = JSON.decode(savedData) + activeInvestigatorData = loadedData.activeInvestigatorData + isClassTextureEnabled = loadedData.isClassTextureEnabled + isDrawButtonVisible = loadedData.isDrawButtonVisible + optionPanelData = loadedData.optionPanelData + optionPanelVisibility = loadedData.optionPanelVisibility + playerColor = loadedData.playerColor + slotData = loadedData.slotData + + -- make sure that edit mode starts disabled + optionPanelData.slotEditing = false end updateMessageColor(playerColor) @@ -195,7 +197,7 @@ function onLoad(savedData) buttonParameters.position.z = 0.92 self.createButton(buttonParameters) - showDrawButton(isDrawButtonVisible) + showDrawButton() createXML() math.randomseed(os.time()) Wait.time(function() collisionEnabled = true end, 0.1) @@ -373,7 +375,7 @@ function doUpkeep(_, clickedByColor, isRightClick) -- flip investigator mini-card and summoned servitor mini-card -- (all characters allowed to account for custom IDs - e.g. 'Z0000' for TTS Zoop generated IDs) - local miniId = string.match(activeInvestigatorId, ".....") .. "-m" + local miniId = string.match(activeInvestigatorData.id, ".....") .. "-m" for _, obj in ipairs(getObjects()) do if obj.type == "Card" and obj.is_face_down then local notes = JSON.decode(obj.getGMNotes()) @@ -389,7 +391,7 @@ function doUpkeep(_, clickedByColor, isRightClick) end -- gain a resource (or two if playing Jenny Barnes) - if string.match(activeInvestigatorId, "%d%d%d%d%d") == "02003" then + if string.match(activeInvestigatorData.id, "%d%d%d%d%d") == "02003" then updateCounter({ type = "ResourceCounter", modifier = 2 }) printToColor("Gaining 2 resources (Jenny)", messageColor) else @@ -397,7 +399,7 @@ function doUpkeep(_, clickedByColor, isRightClick) end -- draw a card (with handling for Patrice and Forced Learning) - if activeInvestigatorId == "06005" then + if activeInvestigatorData.id == "06005" then if forcedLearning then printToColor("Wow, did you really take 'Versatile' to play Patrice with 'Forced Learning'?" .. " Choose which draw replacement effect takes priority and draw cards accordingly.", messageColor) @@ -434,7 +436,7 @@ function doUpkeep(_, clickedByColor, isRightClick) elseif forcedLearning then printToColor("Drawing 2 cards, discard 1 (Forced Learning)", messageColor) drawCardsWithReshuffle(2) - elseif activeInvestigatorId == "89001" then + elseif activeInvestigatorData.id == "89001" then printToColor("Drawing 2 cards (Subject 5U-21)", messageColor) drawCardsWithReshuffle(2) else @@ -764,7 +766,8 @@ function createXML() scale = scale .. " " .. scale, width = "1000", rotation = "0 0 180", - active = "false", + active = optionPanelVisibility ~= "", + visibility = optionPanelVisibility, color = "#000000", outlineSize = "5 5", outline = "grey", @@ -831,7 +834,7 @@ function createXML() totalHeight = totalHeight + rowHeight.option local optionXML = { tag = "Row", - attributes = { preferredHeight = rowHeight.option}, + attributes = { preferredHeight = rowHeight.option }, children = { -- option title { @@ -863,7 +866,7 @@ function createXML() tag = "Button", attributes = { id = optionData.id, - image = optionData.data == true and "option_on" or "option_off", + image = optionPanelData[optionData.id] and "option_on" or "option_off", onClick = "onClick_toggleOption", rectAlignment = "MiddleRight", offsetXY = "-30 0", @@ -907,7 +910,7 @@ function createXML() optionPanelXML.attributes.height = totalHeight -- set correct position to align with playermat - optionPanelXML.attributes.position = (setAsideDirection * 270) .. " " .. (- 95 + scale * totalHeight / 2) .. " -65" + optionPanelXML.attributes.position = (setAsideDirection * 270) .. " " .. (-95 + scale * totalHeight / 2) .. " -65" self.UI.setXmlTable(xml) end @@ -950,12 +953,25 @@ function onClick_handColorSelect(player) if player.color == playerColor then navigationOverlayApi.copyVisibility(playerColor, color) Player[playerColor].changeColor(color) + + -- update visibility for old and new color + Global.call("changeWindowVisibilityForColorWrapper", { + color = playerColor, + windowId = "optionPanelMain", + owner = self + }) + Global.call("changeWindowVisibilityForColorWrapper", { + color = color, + windowId = "optionPanelMain", + owner = self + }) else printToColor("Updated handcolor for this playermat to " .. playerColor .. ".", player.color) end -- update the internal variable playerColor = color + updateSave() end) end @@ -969,6 +985,7 @@ end function applyOptionPanelChange(id, state, clickedByColor) optionPanelData[id] = state + updateSave() if id == "slotEditing" then toggleSlotEditing(_, clickedByColor) @@ -1006,6 +1023,8 @@ function toggleSlotEditing(_, clickedByColor, isRightClick) if currentlyEditingSlots then broadcastToColor("Click on a slot symbol (or an empty slot) to edit it.", messageColor, "Orange") + else + updateSave() end end @@ -1044,6 +1063,7 @@ function resetSlotSymbols() for _, slotName in ipairs(defaultSlotData) do table.insert(slotData, slotName) end + updateSave() updateSlotSymbols() end @@ -1088,7 +1108,7 @@ end function spawnTokensFor(object) local extraUses = {} - if activeInvestigatorId == "03004" then + if activeInvestigatorData.id == "03004" then extraUses["Charge"] = 1 end @@ -1194,9 +1214,9 @@ function maybeUpdateActiveInvestigator(card) local extraToken if notes ~= nil and notes.type == "Investigator" and notes.id ~= nil then - if notes.id == activeInvestigatorId then return end - activeInvestigatorClass = notes.class - activeInvestigatorId = notes.id + if notes.id == activeInvestigatorData.id then return end + activeInvestigatorData.class = notes.class + activeInvestigatorData.id = notes.id extraToken = notes.extraToken ownedObjects.InvestigatorSkillTracker.call("updateStats", { notes.willpowerIcons, @@ -1205,9 +1225,9 @@ function maybeUpdateActiveInvestigator(card) notes.agilityIcons }) updateTexture() - elseif activeInvestigatorId ~= "00000" then - activeInvestigatorClass = "Neutral" - activeInvestigatorId = "00000" + elseif activeInvestigatorData.id ~= "00000" then + activeInvestigatorData.class = "Neutral" + activeInvestigatorData.id = "00000" ownedObjects.InvestigatorSkillTracker.call("updateStats", { 1, 1, 1, 1 }) updateTexture() else @@ -1235,7 +1255,8 @@ function maybeUpdateActiveInvestigator(card) tokenManager.spawnToken(pos, "universalActionAbility", self.getRotation(), function(spawned) - spawned.call("updateClassAndSymbol", { class = activeInvestigatorClass, symbol = activeInvestigatorClass }) + spawned.call("updateClassAndSymbol", + { class = activeInvestigatorData.class, symbol = activeInvestigatorData.class }) end) end @@ -1270,7 +1291,7 @@ function maybeUpdateActiveInvestigator(card) tokenManager.spawnToken(globalSpawnPos, "universalActionAbility", self.getRotation(), function(spawned) - spawned.call("updateClassAndSymbol", { class = activeInvestigatorClass, symbol = str }) + spawned.call("updateClassAndSymbol", { class = activeInvestigatorData.class, symbol = str }) end) end end @@ -1280,11 +1301,13 @@ end -- updates the texture of the playermat ---@param overrideName? string Force a specific texture function updateTexture(overrideName) + updateSave() + local name = "Neutral" -- use class specific texture if enabled if isClassTextureEnabled then - name = activeInvestigatorClass + name = activeInvestigatorData.class end -- get new texture URL @@ -1307,7 +1330,6 @@ function updateTexture(overrideName) end end - self.script_state = onSave() customInfo.image = newUrl ---@diagnostic disable-next-line: param-type-mismatch self.setCustomObject(customInfo) @@ -1402,9 +1424,12 @@ function getEncounterCardDrawPosition(stack) end -- creates / removes the draw 1 button ----@param visible boolean Whether the draw 1 button should be visible +---@param visible? boolean Whether the draw 1 button should be visible function showDrawButton(visible) - isDrawButtonVisible = visible + if visible then + isDrawButtonVisible = visible + updateSave() + end if isDrawButtonVisible then -- Draw 1 button: modified default data @@ -1543,3 +1568,9 @@ function getColoredName(playerColor) -- add bb-code return "[" .. Color.fromString(playerColor):toHex() .. "]" .. displayName .. "[-]" end + +function getActiveInvestigatorData() return activeInvestigatorData end + +function setActiveInvestigatorData(newData) activeInvestigatorData = newData end + +function getDES() return hasDES end diff --git a/src/playermat/PlayermatApi.ttslua b/src/playermat/PlayermatApi.ttslua index 5e446a45..9a1b3d70 100644 --- a/src/playermat/PlayermatApi.ttslua +++ b/src/playermat/PlayermatApi.ttslua @@ -61,7 +61,7 @@ do ---@return boolean: whether DES is present on the playermat PlayermatApi.hasDES = function(matColor) for _, mat in pairs(getMatForColor(matColor)) do - return mat.getVar("hasDES") + return mat.call("getDES") end end @@ -171,19 +171,20 @@ do end end - -- Returns the active investigator id + -- Gets data about the active investigator ---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All") - PlayermatApi.returnInvestigatorId = function(matColor) + PlayermatApi.getActiveInvestigatorData = function(matColor) for _, mat in pairs(getMatForColor(matColor)) do - return mat.getVar("activeInvestigatorId") + return mat.call("getActiveInvestigatorData") end end - -- Returns the class of the active investigator - ---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All") - PlayermatApi.returnInvestigatorClass = function(matColor) + -- Gets data about the active investigator + ---@param matColor string Color of the playermat - White, Orange, Green, Red or All + ---@param newData table New active investigator data (class and id) + PlayermatApi.setActiveInvestigatorData = function(matColor, newData) for _, mat in pairs(getMatForColor(matColor)) do - return mat.getVar("activeInvestigatorClass") + mat.call("setActiveInvestigatorData",newData) end end @@ -235,6 +236,15 @@ do end end + -- updates the texture of the playermat + ---@param matColor string Color of the playermat - White, Orange, Green, Red or All + ---@param overrideName? string Force a specific texture + PlayermatApi.updateTexture = function(matColor, overrideName) + for _, mat in pairs(getMatForColor(matColor)) do + mat.call("updateTexture", overrideName) + end + end + -- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat ---@param matColor string Color of the playermat - White, Orange, Green, Red or All PlayermatApi.removeClues = function(matColor)