From ddb264fe13a3605c9e4f426f3f340d7ff4053c79 Mon Sep 17 00:00:00 2001 From: Buhallin Date: Sat, 17 Jun 2023 01:18:07 -0700 Subject: [PATCH] Update player mat handling of customizable cards - Fixes broken data retrieval to get the selected upgrades - Moves "is this customization active" logic into the UpgradeSheetLibrary - Extends the area covered by searchAroundSelf() to extend farther in (and past) the set aside card areas - Made searchAroundSelf() dynamic, removing the need for explicit position and areas --- objects/Playermat1White.8b081b.ttslua | 2 - objects/Playermat2Orange.bd0ff4.ttslua | 2 - objects/Playermat3Green.383d8b.ttslua | 2 - objects/Playermat4Red.0840d5.ttslua | 2 - .../customizable/UpgradeSheetLibrary.ttslua | 13 +++ src/playermat/Playmat.ttslua | 88 ++++++++++++------- src/playermat/PlaymatApi.ttslua | 6 ++ 7 files changed, 77 insertions(+), 38 deletions(-) diff --git a/objects/Playermat1White.8b081b.ttslua b/objects/Playermat1White.8b081b.ttslua index 7dd4c4fd..6d2d842f 100644 --- a/objects/Playermat1White.8b081b.ttslua +++ b/objects/Playermat1White.8b081b.ttslua @@ -2,8 +2,6 @@ -- specific setup (different for each playmat) --------------------------------------------------------- -PLAY_ZONE_POSITION = { x = -54.5, y = 4, z = 19 } -PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 } TRASHCAN_GUID = "147e80" STAT_TRACKER_GUID = "e598c2" RESOURCE_COUNTER_GUID = "4406f0" diff --git a/objects/Playermat2Orange.bd0ff4.ttslua b/objects/Playermat2Orange.bd0ff4.ttslua index c30fe5af..4530453c 100644 --- a/objects/Playermat2Orange.bd0ff4.ttslua +++ b/objects/Playermat2Orange.bd0ff4.ttslua @@ -2,8 +2,6 @@ -- specific setup (different for each playmat) --------------------------------------------------------- -PLAY_ZONE_POSITION = { x = -54.5, y = 4, z = -19 } -PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 } TRASHCAN_GUID = "f7b6c8" STAT_TRACKER_GUID = "b4a5f7" RESOURCE_COUNTER_GUID = "816d84" diff --git a/objects/Playermat3Green.383d8b.ttslua b/objects/Playermat3Green.383d8b.ttslua index 35b55b38..818bd09f 100644 --- a/objects/Playermat3Green.383d8b.ttslua +++ b/objects/Playermat3Green.383d8b.ttslua @@ -2,8 +2,6 @@ -- specific setup (different for each playmat) --------------------------------------------------------- -PLAY_ZONE_POSITION = { x = -26.5, y = 4, z = 26.5 } -PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 } TRASHCAN_GUID = "5f896a" STAT_TRACKER_GUID = "af7ed7" RESOURCE_COUNTER_GUID = "cd15ac" diff --git a/objects/Playermat4Red.0840d5.ttslua b/objects/Playermat4Red.0840d5.ttslua index 082fc126..6c0fb70f 100644 --- a/objects/Playermat4Red.0840d5.ttslua +++ b/objects/Playermat4Red.0840d5.ttslua @@ -2,8 +2,6 @@ -- specific setup (different for each playmat) --------------------------------------------------------- -PLAY_ZONE_POSITION = { x = -26.5, y = 4, z = -26.5 } -PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 } TRASHCAN_GUID = "4b8594" STAT_TRACKER_GUID = "e74881" RESOURCE_COUNTER_GUID = "a4b60d" diff --git a/src/playercards/customizable/UpgradeSheetLibrary.ttslua b/src/playercards/customizable/UpgradeSheetLibrary.ttslua index 2356fd91..e28f04a7 100644 --- a/src/playercards/customizable/UpgradeSheetLibrary.ttslua +++ b/src/playercards/customizable/UpgradeSheetLibrary.ttslua @@ -19,6 +19,8 @@ -- selectedUpgrades holds the state of checkboxes and text input, each element being: -- selectedUpgrades[row] = { xp = #, text = "" } +local playmatApi = require("playermat/PlaymatApi") + -- Y position for UI elements. Visibility of checkboxes moves the checkbox inside the card object -- when not selected. local Y_VISIBLE = 0.25 @@ -74,6 +76,16 @@ function getSelfId() return metadata.id end +function isUpgradeActive(row) + return customizations[row] ~= nil + and customizations[row].checkboxes ~= nil + and customizations[row].checkboxes.count ~= nil + and customizations[row].checkboxes.count > 0 + and selectedUpgrades[row] ~= nil + and selectedUpgrades[row].xp ~= nil + and selectedUpgrades[row].xp >= customizations[row].checkboxes.count +end + function resetSelections() selectedUpgrades = { } updateDisplay() @@ -218,6 +230,7 @@ function clickCheckbox(row, col, buttonIndex) selectedUpgrades[row].xp = col end updateCheckboxes(row) + playmatApi.syncAllCustomizableCards() end -- Updates saved value for given text box when it loses focus diff --git a/src/playermat/Playmat.ttslua b/src/playermat/Playmat.ttslua index b80ee944..15fb59cf 100644 --- a/src/playermat/Playmat.ttslua +++ b/src/playermat/Playmat.ttslua @@ -15,6 +15,8 @@ local DRAWN_CHAOS_TOKEN_OFFSET = {-1.55, 0.25, -0.58} -- x-Values for discard buttons local DISCARD_BUTTON_OFFSETS = {-1.365, -0.91, -0.455, 0, 0.455, 0.91} +local SEARCH_AROUND_SELF_X_BUFFER = 18 + -- defined areas for the function "inArea()"" local MAIN_PLAY_AREA = { upperLeft = { @@ -155,8 +157,33 @@ function searchArea(origin, size) }) end +-- Finds all objects on the playmat and associated set aside zone. function searchAroundSelf() - return searchArea(PLAY_ZONE_POSITION, PLAY_ZONE_SCALE) + local bounds = self.getBoundsNormalized() + -- Increase the width to cover the set aside zone + bounds.size.x = bounds.size.x + SEARCH_AROUND_SELF_X_BUFFER + -- Since the cast is centered on the position, shift left or right to keep the non-set aside edge + -- of the cast at the edge of the playmat + -- setAsideDirection accounts for the set aside zone being on the left or right, depending on the + -- table position of the playmat + local setAsideDirection = bounds.center.z > 0 and 1 or -1 + local localCenter = self.positionToLocal(bounds.center) + localCenter.x = localCenter.x + + setAsideDirection * SEARCH_AROUND_SELF_X_BUFFER / 2 / self.getScale().x + + return searchArea(self.positionToWorld(localCenter), bounds.size) +end + +function findCardsAroundSelf() + local cards = { } + for _, collision in ipairs(searchAroundSelf()) do + local obj = collision.hit_object + if obj.name == "Card" or obj.name == "CardCustom" then + table.insert(cards, obj) + end + end + + return cards end function doNotReady(card) @@ -536,23 +563,9 @@ function replenishTokens(card, count, replenish) end end - -- handling Runic Axe upgrade sheet for additional replenish - if card.getName() == "Runic Axe" then - for _, v in ipairs(searchAroundSelf()) do - local obj = v.hit_object - if obj.tag == "Card" then - local notes = JSON.decode(obj.getGMNotes()) or {} - if notes ~= nil and notes.id == "09022-c" then - if obj.getVar("markedBoxes")[7] == 3 then replenish = 2 end - break - end - end - end - end - -- this is the theoretical new amount of uses (to be checked below) local newCount = foundTokens + replenish - + -- if there are already more uses than the replenish amount, keep them if foundTokens > count then newCount = foundTokens @@ -569,21 +582,36 @@ function replenishTokens(card, count, replenish) end end +-- Finds all customizable cards in this play area and updates their metadata based on the selections +-- on the matching upgrade sheet. +-- This method is theoretically O(n^2), and should be used sparingly. In practice it will only be +-- called when a checkbox is added or removed in-game (which should be rare), and is bounded by the +-- number of customizable cards in play. +function syncAllCustomizableCards() + for _, card in ipairs(findCardsAroundSelf()) do + syncCustomizableMetadata(card) + end +end + function syncCustomizableMetadata(card) local cardMetadata = JSON.decode(card.getGMNotes()) or { } - if cardMetadata ~= nil and cardMetadata.customizations ~= nil then - for _, collision in ipairs(searchAroundSelf()) do - local obj = collision.hit_object - if obj.name == "Card" or obj.name == "CardCustom" then - local notes = JSON.decode(obj.getGMNotes()) or { } - if notes.id == (cardMetadata.id .. "-c") then - for i, customization in ipairs(cardMetadata.customizations) do - if obj.getVar("markedBoxes")[i] == customization.xp - and customization.replaces ~= nil - and customization.replaces.uses ~= nil then - cardMetadata.uses = customization.replaces.uses - card.setGMNotes(JSON.encode(cardMetadata)) - end + if cardMetadata == nil or cardMetadata.customizations == nil then + return + end + for _, upgradeSheet in ipairs(findCardsAroundSelf()) do + local upgradeSheetMetadata = JSON.decode(upgradeSheet.getGMNotes()) or { } + if upgradeSheetMetadata.id == (cardMetadata.id .. "-c") then + for i, customization in ipairs(cardMetadata.customizations) do + if customization.replaces ~= nil and customization.replaces.uses ~= nil then + -- Allowed use of call(), no APIs for individual cards + if upgradeSheet.call("isUpgradeActive", i) then + cardMetadata.uses = customization.replaces.uses + card.setGMNotes(JSON.encode(cardMetadata)) + else + -- TODO: Get the original metadata to restore it... maybe. This should only be + -- necessary in the very unlikely case that a user un-checks a previously-full upgrade + -- row while the card is in play. It will be much easier once the AllPlayerCardsApi is + -- in place, so defer until it is end end end @@ -633,7 +661,7 @@ function shouldSpawnTokens(card) if card.is_face_down then return false end - + local localCardPos = self.positionToLocal(card.getPosition()) local metadata = JSON.decode(card.getGMNotes()) diff --git a/src/playermat/PlaymatApi.ttslua b/src/playermat/PlaymatApi.ttslua index 34fe1235..39c51f86 100644 --- a/src/playermat/PlaymatApi.ttslua +++ b/src/playermat/PlaymatApi.ttslua @@ -185,6 +185,12 @@ do end end + PlaymatApi.syncAllCustomizableCards = function() + for _, mat in ipairs(internal.getMatForColor("All")) do + mat.call("syncAllCustomizableCards") + end + end + -- Convenience function to look up a mat's object by color, or get all mats. ---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also -- accepts "All" as a special value which will return all four mats.