Merge pull request #313 from argonui/customizable-call

Update player mat handling of customizable cards
This commit is contained in:
Chr1Z 2023-06-18 20:09:04 +02:00 committed by GitHub
commit 04b40f0da1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 77 additions and 38 deletions

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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"

View File

@ -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

View File

@ -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())

View File

@ -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.