diff --git a/objects/AllPlayerCards.15bb07/StellaClark.00e18e.gmnotes b/objects/AllPlayerCards.15bb07/StellaClark.00e18e.gmnotes index 54a5e010..ede7ce7d 100644 --- a/objects/AllPlayerCards.15bb07/StellaClark.00e18e.gmnotes +++ b/objects/AllPlayerCards.15bb07/StellaClark.00e18e.gmnotes @@ -8,7 +8,6 @@ "combatIcons": 3, "agilityIcons": 4, "cycle": "Investigator Packs", - "extraToken": "Survivor", "signatures": [ { "60502": 3, diff --git a/objects/AllPlayerCards.15bb07/StellaClark.00e18e.json b/objects/AllPlayerCards.15bb07/StellaClark.00e18e.json index 782945dc..80d677fe 100644 --- a/objects/AllPlayerCards.15bb07/StellaClark.00e18e.json +++ b/objects/AllPlayerCards.15bb07/StellaClark.00e18e.json @@ -33,7 +33,7 @@ "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": false, - "LuaScript": "", + "LuaScript": "require(\"playercards/cards/StellaClark\")", "LuaScriptState": "", "MeasureMovement": false, "Name": "Card", @@ -58,5 +58,5 @@ "scaleZ": 1.15 }, "Value": 0, - "XmlUI": "" + "XmlUI": "\u003cInclude src=\"playercards/StellaClark.xml\"/\u003e" } diff --git a/src/playercards/cards/StellaClark.ttslua b/src/playercards/cards/StellaClark.ttslua new file mode 100644 index 00000000..b6692bc4 --- /dev/null +++ b/src/playercards/cards/StellaClark.ttslua @@ -0,0 +1,118 @@ +require("playercards/CardsWithHelper") +local guidReferenceApi = require("core/GUIDReferenceApi") +local playermatApi = require("playermat/PlayermatApi") +local searchLib = require("util/SearchLib") +local tokenManagerApi = require("core/token/TokenManagerApi") + +-- intentionally global +hasXML = true +isHelperEnabled = false +local updated +local state + +local xmlData = { + Action = { color = "#6D202CE6", onClick = "addExtraAction" }, + ElderSign = { color = "#50A8CEE6", onClick = "elderSignAbility" } +} + +function updateSave() + self.script_state = JSON.encode({ + isHelperEnabled = isHelperEnabled, + state = state + }) +end + +function onLoad(savedData) + self.addTag("DoInUpkeep") + if savedData and savedData ~= "" then + local loadedData = JSON.decode(savedData) + isHelperEnabled = loadedData.isHelperEnabled + state = loadedData.state + else + state = { Action = true, ElderSign = true } + end + syncDisplayWithOptionPanel() +end + +function initialize() + setUiState(state) + updated = true +end + +function addExtraAction() + if not updated then return end + updated = false + + local position = self.getPosition() + local matColor = playermatApi.getMatColorByPosition(position) + local mat = guidReferenceApi.getObjectByOwnerAndType(matColor, "Playermat") + local rotation = mat.getRotation() + + -- find empty action token slots by checking snap points + local snaps = mat.getSnapPoints() + + -- get first empty slot in the top row (so the second empty slot because of the ability token) + local emptyPos = position -- default to card position + for i, snap in ipairs(snaps) do + if i > 1 then + if snap.tags[1] == "UniversalToken" then + local snapPos = mat.positionToWorld(snap.position) + local searchResult = searchLib.atPosition(snapPos, "isUniversalToken") + if #searchResult == 0 then + emptyPos = snapPos + break + end + end + end + end + + local callbackName = "updateUniversalActionAbilityToken" + local callbackParams = { class = "Survivor", symbol = "Survivor", addTag = "Temporary"} + tokenManagerApi.spawnToken(emptyPos + Vector(0, 0.7, 0), "universalActionAbility", rotation, callbackName, callbackParams) + state = { Action = false, ElderSign = true } + setUiState(state) + updated = true + updateSave() +end + +function elderSignAbility() + local matColor = playermatApi.getMatColorByPosition(self.getPosition()) + playermatApi.updateCounter(matColor, "DamageCounter", _, -1) + playermatApi.updateCounter(matColor, "HorrorCounter", _, -1) + + -- check if reaction ability has already been used + local actionColor = self.UI.getAttribute("Action", "color") + if actionColor ~= "#353535E6" then + addExtraAction() + broadcastToAll("Healing 1 damage and 1 horror from Stella and triggering her reaction.", "White") + else + broadcastToAll("Healing 1 damage and 1 horror from Stella.", "White") + end +end + +function setUiState(params) + for buttonId, onState in pairs(params) do + if onState then + self.UI.setAttribute(buttonId, "color", xmlData[buttonId].color) + self.UI.setAttribute(buttonId, "onClick", xmlData[buttonId].onClick) + self.UI.setAttribute(buttonId, "textColor", "white") + else + self.UI.setAttribute(buttonId, "color", "#353535E6") + self.UI.setAttribute(buttonId, "onClick", "errorMessage") + self.UI.setAttribute(buttonId, "textColor", "#A0A0A0") + end + end +end + +function errorMessage(_, _, triggeringButton) + if triggeringButton == "Action" then + broadcastToAll("You have already triggered this once this round.", "Red") + end +end + +function doInUpkeep() + state = { Action = true, ElderSign = true } + setUiState(state) + updated = true + updateSave() +end \ No newline at end of file diff --git a/src/playermat/Playermat.ttslua b/src/playermat/Playermat.ttslua index 67abe0a2..622a1456 100644 --- a/src/playermat/Playermat.ttslua +++ b/src/playermat/Playermat.ttslua @@ -345,8 +345,17 @@ function doUpkeep(_, clickedByColor, isRightClick) discardListOfObjects({ obj }) elseif obj.hasTag("UniversalToken") == true and obj.is_face_down then obj.flip() - elseif obj.type == "Card" and not inArea(self.positionToLocal(obj.getPosition()), INVESTIGATOR_AREA) then + elseif obj.type == "Card" then local cardMetadata = JSON.decode(obj.getGMNotes()) or {} + + if obj.hasTag("DoInUpkeep") then + obj.call("doInUpkeep") + end + -- do not rotate, replenish, etc. on cards in investigator card area + if inArea(self.positionToLocal(obj.getPosition()), INVESTIGATOR_AREA) then + return + end + if not (obj.getVar("do_not_ready") or obj.hasTag("DoNotReady")) then local cardRotation = obj.getRotation() local yRotDiff = round(cardRotation.y, 0) - rot.y diff --git a/xml/playercards/StellaClark.xml b/xml/playercards/StellaClark.xml new file mode 100644 index 00000000..68f3e43d --- /dev/null +++ b/xml/playercards/StellaClark.xml @@ -0,0 +1,30 @@ + +