updated playermats and stattracker

This commit is contained in:
Chr1Z93 2022-11-12 12:43:35 +01:00
parent bc01f28c29
commit c8462f664d
31 changed files with 628 additions and 1342 deletions

View File

@ -206,27 +206,11 @@
"EdgeoftheEarth.895eaa", "EdgeoftheEarth.895eaa",
"TheDream-Eaters.a16a1a", "TheDream-Eaters.a16a1a",
"ReturntoTheCircleUndone.757324", "ReturntoTheCircleUndone.757324",
"Intellect.0016fc",
"Playermat4Red.0840d5", "Playermat4Red.0840d5",
"Agility.181fa2",
"Combat.19026b",
"Agility.2c3f8d",
"Playermat3Green.383d8b", "Playermat3Green.383d8b",
"Intellect.4ca990",
"MiscDoominplay.652ff3", "MiscDoominplay.652ff3",
"Willpower.85a8ed",
"Playermat1White.8b081b", "Playermat1White.8b081b",
"Willpower.8b6743",
"Combat.9136c6",
"Combat.93a48b",
"Agility.a0b6df",
"Willpower.afc290",
"Intellect.b4ef12",
"Combat.b661a6",
"Playermat2Orange.bd0ff4", "Playermat2Orange.bd0ff4",
"Intellect.c1fe65",
"Agility.d4df33",
"Willpower.fa6df4",
"CustomDataHelper.2547b3", "CustomDataHelper.2547b3",
"LolaNeutral.637e17", "LolaNeutral.637e17",
"LolaNeutral.e003fe", "LolaNeutral.e003fe",
@ -258,7 +242,11 @@
"PhaseTracker.d0c8fa", "PhaseTracker.d0c8fa",
"AllPlayerCards.15bb07", "AllPlayerCards.15bb07",
"Search-A-Card.24051a", "Search-A-Card.24051a",
"231Notes-10152022.268764" "231Notes-10152022.268764",
"StatTracker.af7ed7",
"StatTracker.e598c2",
"StatTracker.b4a5f7",
"StatTracker.e74881"
], ],
"PlayArea": 1, "PlayArea": 1,
"PlayerCounts": [ "PlayerCounts": [

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/vXVWwD0.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "2c3f8d",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Agility",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -15.861,
"posY": 1.548,
"posZ": -19.216,
"rotX": 0,
"rotY": 180,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/vXVWwD0.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "a0b6df",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Agility",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -47.642,
"posY": 1.6,
"posZ": 5.825,
"rotX": 0,
"rotY": 270,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/vXVWwD0.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "d4df33",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Agility",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -47.641,
"posY": 1.59,
"posZ": -25.644,
"rotX": 0,
"rotY": 270,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/YBjxze6.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "19026b",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Combat",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -34.137,
"posY": 1.585,
"posZ": 19.236,
"rotX": 0,
"rotY": 0,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/sj8GatY.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "0016fc",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Intellect",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -32.672,
"posY": 1.583,
"posZ": 19.236,
"rotX": 0,
"rotY": 0,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/sj8GatY.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "4ca990",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Intellect",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -47.638,
"posY": 1.591,
"posZ": -22.713,
"rotX": 0,
"rotY": 270,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/sj8GatY.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "b4ef12",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Intellect",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -18.79,
"posY": 1.552,
"posZ": -19.216,
"rotX": 0,
"rotY": 180,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/sj8GatY.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "c1fe65",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Intellect",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -47.642,
"posY": 1.601,
"posZ": 8.755,
"rotX": 0,
"rotY": 270,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -228,7 +228,7 @@
"IgnoreFoW": false, "IgnoreFoW": false,
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": true, "Locked": true,
"LuaScriptState": "{\"playerColor\":\"White\",\"zoneID\":\"7af2cf\"}", "LuaScriptState": "{\"activeInvestigatorId\":\"00000\",\"playerColor\":\"White\",\"zoneID\":\"7af2cf\"}",
"LuaScript_path": "Playermat1White.8b081b.ttslua", "LuaScript_path": "Playermat1White.8b081b.ttslua",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Tile", "Name": "Custom_Tile",

View File

@ -1,41 +1,15 @@
-- set true to enable debug logging ---------------------------------------------------------
DEBUG = false -- specific setup (different for each playmat)
-- we use this to turn off collision handling (for clue spawning) ---------------------------------------------------------
-- until after load is complete (probably a better way to do this)
COLLISION_ENABLED = false
-- position offsets, adjust these to reposition things relative to mat [x,y,z]
DRAWN_ENCOUNTER_CARD_OFFSET = {1.365, 0.5, -0.635}
DRAWN_CHAOS_TOKEN_OFFSET = {-1.55, 0.5, -0.58}
DISCARD_BUTTON_OFFSETS = {
{-1.365, 0.2, -0.945},
{-0.91, 0.2, -0.945},
{-0.455, 0.2, -0.945},
{0, 0.2, -0.945},
{0.455, 0.2, -0.945},
{0.91, 0.2, -0.945},
}
-- draw deck and discard zone
DECK_POSITION = { x=-1.4, y=0, z=0.3 }
DECK_ZONE_SCALE = { x=3, y=5, z=8 }
DRAW_DECK_POSITION = { x=-54.8, y=2.5, z=4.3 }
-- play zone PLAYER_COLOR = "White"
PLAYER_COLOR = "White" PLAY_ZONE_POSITION = { x = -54.5, y = 4, z = 21 }
PLAY_ZONE_POSITION = { x=-54.42, y=4.10, z=20.96} PLAY_ZONE_SCALE = { x = 36, y = 5.1, z = 14.5 }
PLAY_ZONE_ROTATION = { x=0, y=270, z=0 } DRAW_DECK_POSITION = { x = -54.8, y = 2.5, z = 4.29 }
PLAY_ZONE_SCALE = { x=36.63, y=5.10, z=14.59} DISCARD_PILE_POSITION = { x = -58.9, y = 4, z = 4.29 }
RESOURCE_COUNTER_GUID = "4406f0" TRASHCAN = getObjectFromGUID("147e80")
STAT_TRACKER = getObjectFromGUID("e598c2")
-- the position of the global discard pile RESOURCE_COUNTER = getObjectFromGUID("4406f0")
-- TODO: delegate to global for any auto discard actions
DISCARD_POSITION = {-3.85, 3, 10.38}
-- DISCARD PILE POSITION
DISCARD_PILE_POSITION = {-59.13, 4, 4.40 }
local willpowerTokenGuid = "85a8ed"
local intellectTokenGuid = "c1fe65"
local combatTokenGuid = "9136c6"
local agilityTokenGuid = "a0b6df"
require("playermat/Playmat") require("playermat/Playmat")

View File

@ -228,7 +228,7 @@
"IgnoreFoW": false, "IgnoreFoW": false,
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": true, "Locked": true,
"LuaScriptState": "{\"playerColor\":\"Orange\",\"zoneID\":\"b047f8\"}", "LuaScriptState": "{\"activeInvestigatorId\":\"00000\",\"playerColor\":\"Orange\",\"zoneID\":\"b047f8\"}",
"LuaScript_path": "Playermat2Orange.bd0ff4.ttslua", "LuaScript_path": "Playermat2Orange.bd0ff4.ttslua",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Tile", "Name": "Custom_Tile",

View File

@ -1,41 +1,15 @@
-- set true to enable debug logging ---------------------------------------------------------
DEBUG = false -- specific setup (different for each playmat)
-- we use this to turn off collision handling (for clue spawning) ---------------------------------------------------------
-- until after load is complete (probably a better way to do this)
COLLISION_ENABLED = false
-- position offsets, adjust these to reposition things relative to mat [x,y,z]
DRAWN_ENCOUNTER_CARD_OFFSET = {1.365, 0.5, -0.635}
DRAWN_CHAOS_TOKEN_OFFSET = {-1.55, 0.5, -0.58}
DISCARD_BUTTON_OFFSETS = {
{-1.365, 0.2, -0.945},
{-0.91, 0.2, -0.945},
{-0.455, 0.2, -0.945},
{0, 0.2, -0.945},
{0.455, 0.2, -0.945},
{0.91, 0.2, -0.945},
}
-- draw deck and discard zone
DECK_POSITION = { x=-1.4, y=0, z=0.3 }
DECK_ZONE_SCALE = { x=3, y=5, z=8 }
DRAW_DECK_POSITION = { x=-55, y=2.5, z=-27.8 }
-- play zone PLAYER_COLOR = "Orange"
PLAYER_COLOR = "Orange" PLAY_ZONE_POSITION = { x = -54.5, y = 4, z = -21 }
PLAY_ZONE_POSITION = { x=-54.53, y=4.10, z=-20.94} PLAY_ZONE_SCALE = { x = 36, y = 5.1, z = 14.5 }
PLAY_ZONE_ROTATION = { x=0, y=270, z=0 } DRAW_DECK_POSITION = { x = -54.86, y = 2.5, z = -27.82 }
PLAY_ZONE_SCALE = { x=36.96, y=5.10, z=14.70} DISCARD_PILE_POSITION = { x = -58.96, y = 4, z = -27.82 }
RESOURCE_COUNTER_GUID = "816d84" TRASHCAN = getObjectFromGUID("f7b6c8")
STAT_TRACKER = getObjectFromGUID("b4a5f7")
-- the position of the global discard pile RESOURCE_COUNTER = getObjectFromGUID("816d84")
-- TODO: delegate to global for any auto discard actions
DISCARD_POSITION = {-3.85, 3, 10.38}
-- DISCARD PILE POSITION
DISCARD_PILE_POSITION = { -59.19, 4, -22.78 }
local willpowerTokenGuid = "afc290"
local intellectTokenGuid = "4ca990"
local combatTokenGuid = "b661a6"
local agilityTokenGuid = "d4df33"
require("playermat/Playmat") require("playermat/Playmat")

View File

@ -228,7 +228,7 @@
"IgnoreFoW": false, "IgnoreFoW": false,
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": true, "Locked": true,
"LuaScriptState": "{\"playerColor\":\"Green\",\"zoneID\":\"fb28e1\"}", "LuaScriptState": "{\"activeInvestigatorId\":\"00000\",\"playerColor\":\"Green\",\"zoneID\":\"fb28e1\"}",
"LuaScript_path": "Playermat3Green.383d8b.ttslua", "LuaScript_path": "Playermat3Green.383d8b.ttslua",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Tile", "Name": "Custom_Tile",

View File

@ -1,41 +1,15 @@
-- set true to enable debug logging ---------------------------------------------------------
DEBUG = false -- specific setup (different for each playmat)
-- we use this to turn off collision handling (for clue spawning) ---------------------------------------------------------
-- until after load is complete (probably a better way to do this)
COLLISION_ENABLED = false
-- position offsets, adjust these to reposition things relative to mat [x,y,z]
DRAWN_ENCOUNTER_CARD_OFFSET = {1.365, 0.5, -0.635}
DRAWN_CHAOS_TOKEN_OFFSET = {-1.55, 0.5, -0.58}
DISCARD_BUTTON_OFFSETS = {
{-1.365, 0.2, -0.945},
{-0.91, 0.2, -0.945},
{-0.455, 0.2, -0.945},
{0, 0.2, -0.945},
{0.455, 0.2, -0.945},
{0.91, 0.2, -0.945},
}
-- draw deck and discard zone
DECK_POSITION = { x=-1.4, y=0, z=0.3 }
DECK_ZONE_SCALE = { x=3, y=5, z=8 }
DRAW_DECK_POSITION = { x=-37.2, y=2.5, z=26.3 }
-- play zone PLAYER_COLOR = "Green"
PLAYER_COLOR = "Green" PLAY_ZONE_POSITION = { x = -25, y = 4, z = 27 }
PLAY_ZONE_POSITION = { x=-25, y=4, z=27 } PLAY_ZONE_SCALE = { x = 30, y = 5, z = 14.5 }
PLAY_ZONE_ROTATION = { x=0, y=0, z=0 } DRAW_DECK_POSITION = { x = -37.26, y = 2.5, z = 26.4 }
PLAY_ZONE_SCALE = { x=30, y=5, z=15 } DISCARD_PILE_POSITION = { x = -37.26, y = 4, z = 30.50 }
RESOURCE_COUNTER_GUID = "cd15ac" TRASHCAN = getObjectFromGUID("5f896a")
STAT_TRACKER = getObjectFromGUID("af7ed7")
-- the position of the global discard pile RESOURCE_COUNTER = getObjectFromGUID("cd15ac")
-- TODO: delegate to global for any auto discard actions
DISCARD_POSITION = {-3.85, 3, 10.38}
-- DISCARD PILE POSITION
DISCARD_PILE_POSITION = { -37.11, 4, 30.76 }
local willpowerTokenGuid = "fa6df4"
local intellectTokenGuid = "0016fc"
local combatTokenGuid = "19026b"
local agilityTokenGuid = "181fa2"
require("playermat/Playmat") require("playermat/Playmat")

View File

@ -228,7 +228,7 @@
"IgnoreFoW": false, "IgnoreFoW": false,
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": true, "Locked": true,
"LuaScriptState": "{\"playerColor\":\"Red\",\"zoneID\":\"18538f\"}", "LuaScriptState": "{\"activeInvestigatorId\":\"00000\",\"playerColor\":\"Red\",\"zoneID\":\"18538f\"}",
"LuaScript_path": "Playermat4Red.0840d5.ttslua", "LuaScript_path": "Playermat4Red.0840d5.ttslua",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Tile", "Name": "Custom_Tile",

View File

@ -1,41 +1,15 @@
-- set true to enable debug logging ---------------------------------------------------------
DEBUG = false -- specific setup (different for each playmat)
-- we use this to turn off collision handling (for clue spawning) ---------------------------------------------------------
-- until after load is complete (probably a better way to do this)
COLLISION_ENABLED = false
-- position offsets, adjust these to reposition things relative to mat [x,y,z]
DRAWN_ENCOUNTER_CARD_OFFSET = {1.365, 0.5, -0.635}
DRAWN_CHAOS_TOKEN_OFFSET = {-1.55, 0.5, -0.58}
DISCARD_BUTTON_OFFSETS = {
{-1.365, 0.2, -0.945},
{-0.91, 0.2, -0.945},
{-0.455, 0.2, -0.945},
{0, 0.2, -0.945},
{0.455, 0.2, -0.945},
{0.91, 0.2, -0.945},
}
-- draw deck and discard zone
DECK_POSITION = { x=-1.4, y=0, z=0.3 }
DECK_ZONE_SCALE = { x=3, y=5, z=8 }
DRAW_DECK_POSITION = { x=-13.7, y=2.5, z=-26.4 }
-- play zone PLAYER_COLOR = "Red"
PLAYER_COLOR = "Red" PLAY_ZONE_POSITION = { x = -25, y = 4, z = -27 }
PLAY_ZONE_POSITION = { x=-25, y=4, z=-27 } PLAY_ZONE_SCALE = { x = 30, y = 5, z = 14.5 }
PLAY_ZONE_ROTATION = { x=0, y=180, z=0 } DRAW_DECK_POSITION = { x = -13.78, y = 2.5, z = -26.37 }
PLAY_ZONE_SCALE = { x=30, y=5, z=15 } DISCARD_PILE_POSITION = { x = -13.78, y = 4, z = -30.48 }
RESOURCE_COUNTER_GUID = "a4b60d" TRASHCAN = getObjectFromGUID("4b8594")
STAT_TRACKER = getObjectFromGUID("e74881")
-- the position of the global discard pile RESOURCE_COUNTER = getObjectFromGUID("a4b60d")
-- TODO: delegate to global for any auto discard actions
DISCARD_POSITION = {-3.85, 3, 10.38}
-- DISCARD PILE POSITION
DISCARD_PILE_POSITION = { -18.79, 4, -30.84 }
local willpowerTokenGuid = "8b6743"
local intellectTokenGuid = "b4ef12"
local combatTokenGuid = "93a48b"
local agilityTokenGuid = "2c3f8d"
require("playermat/Playmat") require("playermat/Playmat")

View File

@ -19,41 +19,42 @@
}, },
"ImageScalar": 1, "ImageScalar": 1,
"ImageSecondaryURL": "", "ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/vXVWwD0.png", "ImageURL": "http://cloud-3.steamusercontent.com/ugc/1910115722579978285/38E3156A777396FF8C96D2191720790162749C40/",
"WidthScale": 0 "WidthScale": 0
}, },
"Description": "Left click - Increase\nRight click - Decrease", "Description": "Displays the stats of your investigator and can be clicked to increase / decrease the stats.\n\nSee context menu for additional information.",
"DragSelectable": true, "DragSelectable": true,
"GMNotes": "", "GMNotes": "",
"GUID": "181fa2", "GUID": "af7ed7",
"Grid": false, "Grid": true,
"GridProjection": false, "GridProjection": false,
"Hands": false, "Hands": false,
"HideWhenFaceDown": false, "HideWhenFaceDown": false,
"IgnoreFoW": false, "IgnoreFoW": false,
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": true, "Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")", "LuaScriptState": "[1,1,1,1]",
"LuaScriptState": "[true,0]", "LuaScript_path": "StatTracker.af7ed7.ttslua",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Token", "Name": "Custom_Token",
"Nickname": "Agility", "Nickname": "Stat Tracker",
"Snap": false, "Snap": true,
"Sticky": true, "Sticky": true,
"Tags": [ "Tags": [
"CleanUpHelper_ignore" "CleanUpHelper_ignore",
"displacement_excluded"
], ],
"Tooltip": false, "Tooltip": true,
"Transform": { "Transform": {
"posX": -35.602, "posX": -32,
"posY": 1.587, "posY": 1.531,
"posZ": 19.236, "posZ": 19.3,
"rotX": 0, "rotX": 0,
"rotY": 0, "rotY": 0,
"rotZ": 0, "rotZ": 0,
"scaleX": 0.429196239, "scaleX": 0.95,
"scaleY": 1, "scaleY": 1,
"scaleZ": 0.429196239 "scaleZ": 0.95
}, },
"Value": 0, "Value": 0,
"XmlUI": "" "XmlUI": ""

View File

@ -0,0 +1 @@
require("playermat/statTracker")

View File

@ -19,41 +19,42 @@
}, },
"ImageScalar": 1, "ImageScalar": 1,
"ImageSecondaryURL": "", "ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/YBjxze6.png", "ImageURL": "http://cloud-3.steamusercontent.com/ugc/1910115722579978285/38E3156A777396FF8C96D2191720790162749C40/",
"WidthScale": 0 "WidthScale": 0
}, },
"Description": "Left click - Increase\nRight click - Decrease", "Description": "Displays the stats of your investigator and can be clicked to increase / decrease the stats.\n\nSee context menu for additional information.",
"DragSelectable": true, "DragSelectable": true,
"GMNotes": "", "GMNotes": "",
"GUID": "b661a6", "GUID": "b4a5f7",
"Grid": false, "Grid": true,
"GridProjection": false, "GridProjection": false,
"Hands": false, "Hands": false,
"HideWhenFaceDown": false, "HideWhenFaceDown": false,
"IgnoreFoW": false, "IgnoreFoW": false,
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": true, "Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")", "LuaScriptState": "[1,1,1,1]",
"LuaScriptState": "[true,0]", "LuaScript_path": "StatTracker.b4a5f7.ttslua",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Token", "Name": "Custom_Token",
"Nickname": "Combat", "Nickname": "Stat Tracker",
"Snap": false, "Snap": true,
"Sticky": true, "Sticky": true,
"Tags": [ "Tags": [
"CleanUpHelper_ignore" "CleanUpHelper_ignore",
"displacement_excluded"
], ],
"Tooltip": false, "Tooltip": true,
"Transform": { "Transform": {
"posX": -47.641, "posX": -47.75,
"posY": 1.591, "posY": 1.531,
"posZ": -24.179, "posZ": -22,
"rotX": 0, "rotX": 0,
"rotY": 270, "rotY": 270,
"rotZ": 0, "rotZ": 0,
"scaleX": 0.429196239, "scaleX": 0.95,
"scaleY": 1, "scaleY": 1,
"scaleZ": 0.429196239 "scaleZ": 0.95
}, },
"Value": 0, "Value": 0,
"XmlUI": "" "XmlUI": ""

View File

@ -0,0 +1 @@
require("playermat/statTracker")

View File

@ -19,41 +19,42 @@
}, },
"ImageScalar": 1, "ImageScalar": 1,
"ImageSecondaryURL": "", "ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/YBjxze6.png", "ImageURL": "http://cloud-3.steamusercontent.com/ugc/1910115722579978285/38E3156A777396FF8C96D2191720790162749C40/",
"WidthScale": 0 "WidthScale": 0
}, },
"Description": "Left click - Increase\nRight click - Decrease", "Description": "Displays the stats of your investigator and can be clicked to increase / decrease the stats.\n\nSee context menu for additional information.",
"DragSelectable": true, "DragSelectable": true,
"GMNotes": "", "GMNotes": "",
"GUID": "9136c6", "GUID": "e598c2",
"Grid": false, "Grid": true,
"GridProjection": false, "GridProjection": false,
"Hands": false, "Hands": false,
"HideWhenFaceDown": false, "HideWhenFaceDown": false,
"IgnoreFoW": false, "IgnoreFoW": false,
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": true, "Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")", "LuaScriptState": "[1,1,1,1]",
"LuaScriptState": "[true,0]", "LuaScript_path": "StatTracker.e598c2.ttslua",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Token", "Name": "Custom_Token",
"Nickname": "Combat", "Nickname": "Stat Tracker",
"Snap": false, "Snap": true,
"Sticky": true, "Sticky": true,
"Tags": [ "Tags": [
"CleanUpHelper_ignore" "CleanUpHelper_ignore",
"displacement_excluded"
], ],
"Tooltip": false, "Tooltip": true,
"Transform": { "Transform": {
"posX": -47.642, "posX": -47.75,
"posY": 1.6, "posY": 1.531,
"posZ": 7.29, "posZ": 9,
"rotX": 0, "rotX": 0,
"rotY": 270, "rotY": 270,
"rotZ": 0, "rotZ": 0,
"scaleX": 0.429196239, "scaleX": 0.95,
"scaleY": 1, "scaleY": 1,
"scaleZ": 0.429196239 "scaleZ": 0.95
}, },
"Value": 0, "Value": 0,
"XmlUI": "" "XmlUI": ""

View File

@ -0,0 +1 @@
require("playermat/statTracker")

View File

@ -19,41 +19,42 @@
}, },
"ImageScalar": 1, "ImageScalar": 1,
"ImageSecondaryURL": "", "ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/YBjxze6.png", "ImageURL": "http://cloud-3.steamusercontent.com/ugc/1910115722579978285/38E3156A777396FF8C96D2191720790162749C40/",
"WidthScale": 0 "WidthScale": 0
}, },
"Description": "Left click - Increase\nRight click - Decrease", "Description": "Displays the stats of your investigator and can be clicked to increase / decrease the stats.\n\nSee context menu for additional information.",
"DragSelectable": true, "DragSelectable": true,
"GMNotes": "", "GMNotes": "",
"GUID": "93a48b", "GUID": "e74881",
"Grid": false, "Grid": true,
"GridProjection": false, "GridProjection": false,
"Hands": false, "Hands": false,
"HideWhenFaceDown": false, "HideWhenFaceDown": false,
"IgnoreFoW": false, "IgnoreFoW": false,
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": true, "Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")", "LuaScriptState": "[1,1,1,1]",
"LuaScriptState": "[true,0]", "LuaScript_path": "StatTracker.e74881.ttslua",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Token", "Name": "Custom_Token",
"Nickname": "Combat", "Nickname": "Stat Tracker",
"Snap": false, "Snap": true,
"Sticky": true, "Sticky": true,
"Tags": [ "Tags": [
"CleanUpHelper_ignore" "CleanUpHelper_ignore",
"displacement_excluded"
], ],
"Tooltip": false, "Tooltip": true,
"Transform": { "Transform": {
"posX": -17.326, "posX": -19,
"posY": 1.55, "posY": 1.531,
"posZ": -19.216, "posZ": -19.35,
"rotX": 0, "rotX": 0,
"rotY": 180, "rotY": 180,
"rotZ": 0, "rotZ": 0,
"scaleX": 0.429196239, "scaleX": 0.95,
"scaleY": 1, "scaleY": 1,
"scaleZ": 0.429196239 "scaleZ": 0.95
}, },
"Value": 0, "Value": 0,
"XmlUI": "" "XmlUI": ""

View File

@ -0,0 +1 @@
require("playermat/statTracker")

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/i2IDOcO.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "85a8ed",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Willpower",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -47.642,
"posY": 1.601,
"posZ": 10.22,
"rotX": 0,
"rotY": 270,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/i2IDOcO.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "8b6743",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Willpower",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -20.253,
"posY": 1.554,
"posZ": -19.216,
"rotX": 0,
"rotY": 180,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/i2IDOcO.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "afc290",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Willpower",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -47.638,
"posY": 1.592,
"posZ": -21.248,
"rotX": 0,
"rotY": 270,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,60 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"CustomImage": {
"CustomToken": {
"MergeDistancePixels": 5,
"Stackable": false,
"StandUp": false,
"Thickness": 0.1
},
"ImageScalar": 1,
"ImageSecondaryURL": "",
"ImageURL": "https://i.imgur.com/i2IDOcO.png",
"WidthScale": 0
},
"Description": "Left click - Increase\nRight click - Decrease",
"DragSelectable": true,
"GMNotes": "",
"GUID": "fa6df4",
"Grid": false,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"playermat/SkillToken\")",
"LuaScriptState": "[true,0]",
"MeasureMovement": false,
"Name": "Custom_Token",
"Nickname": "Willpower",
"Snap": false,
"Sticky": true,
"Tags": [
"CleanUpHelper_ignore"
],
"Tooltip": false,
"Transform": {
"posX": -31.208,
"posY": 1.581,
"posZ": 19.236,
"rotX": 0,
"rotY": 0,
"rotZ": 0,
"scaleX": 0.429196239,
"scaleY": 1,
"scaleZ": 0.429196239
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,90 +1,67 @@
local activeInvestigatorId = nil ---------------------------------------------------------
-- general setup (identical for each playmat)
---------------------------------------------------------
function log(message) -- set true to enable debug logging and show Physics.cast()
if DEBUG then local DEBUG = false
print(message)
end
end
-- builds a function that discards things in searchPostion to discardPostition -- we use this to turn off collision handling until onLoad() is complete
function makeDiscardHandlerFor(searchPosition, discardPosition) local COLLISION_ENABLED = false
return function (_)
local discardItemList = findObjectsAtPosition(searchPosition)
for _, obj in ipairs(discardItemList) do
obj.setPositionSmooth(discardPosition, false, true)
obj.setRotation({0, -90, 0})
end
end
end
-- build a discard button at position to discard from searchPosition to discardPosition -- position offsets relative to mat [x, y, z]
-- number must be unique local DRAWN_ENCOUNTER_CARD_OFFSET = {1.365, 0.5, -0.635}
function makeDiscardButton(position, searchPosition, discardPosition, number) local DRAWN_CHAOS_TOKEN_OFFSET = {-1.55, 0.5, -0.58}
local handler = makeDiscardHandlerFor(searchPosition, discardPosition) local DISCARD_BUTTON_OFFSETS = {
local handlerName = 'handler' .. number {-1.365, 0.1, -0.945},
self.setVar(handlerName, handler) {-0.91, 0.1, -0.945},
self.createButton({ {-0.455, 0.1, -0.945},
label = "Discard", {0, 0.1, -0.945},
click_function= handlerName, {0.455, 0.1, -0.945},
function_owner= self, {0.91, 0.1, -0.945}
position = position, }
scale = {0.12, 0.12, 0.12},
width = 800,
height = 280,
font_size = 180,
})
end
function onload(save_state) local PLAY_ZONE_ROTATION = self.getRotation()
activeInvestigatorId = "00000"
---------------------------------------------------------
-- general code (identical for each playmat)
---------------------------------------------------------
function onSave() return JSON.encode({zoneID = zoneID, playerColor = PLAYER_COLOR, activeInvestigatorId = activeInvestigatorId}) end
function onLoad(save_state)
self.interactable = DEBUG self.interactable = DEBUG
DATA_HELPER = getObjectFromGUID('708279') DATA_HELPER = getObjectFromGUID('708279')
PLAYER_CARDS = DATA_HELPER.getTable('PLAYER_CARD_DATA') PLAYER_CARDS = DATA_HELPER.getTable('PLAYER_CARD_DATA')
PLAYER_CARD_TOKEN_OFFSETS = DATA_HELPER.getTable('PLAYER_CARD_TOKEN_OFFSETS') PLAYER_CARD_TOKEN_OFFSETS = DATA_HELPER.getTable('PLAYER_CARD_TOKEN_OFFSETS')
-- positions of encounter card slots for i = 1, 6 do
local encounterSlots = { makeDiscardButton(DISCARD_BUTTON_OFFSETS[i], {-3.85, 3, 10.38}, i)
{1.365, 0, -0.7},
{0.91, 0, -0.7},
{0.455, 0, -0.7},
{0, 0, -0.7},
{-0.455, 0, -0.7},
{-0.91, 0, -0.7},
}
local i = 1
while i <= 6 do
makeDiscardButton(DISCARD_BUTTON_OFFSETS[i], encounterSlots[i], DISCARD_POSITION, i)
i = i + 1
end end
self.createButton({ self.createButton({
label = " ",
click_function = "drawEncountercard", click_function = "drawEncountercard",
function_owner = self, function_owner = self,
position = {-1.88,0,-0.7}, position = {-1.84, 0, -0.65},
rotation = {0,-15,0}, rotation = {0, 80, 0},
width = 170, width = 265,
height = 255, height = 190
font_size = 50
}) })
self.createButton({ self.createButton({
label=" ",
click_function = "drawChaostokenButton", click_function = "drawChaostokenButton",
function_owner = self, function_owner = self,
position = {1.84,0.0,-0.74}, position = {1.85, 0, -0.74},
rotation = {0,-45,0}, rotation = {0, -45, 0},
width = 125, width = 135,
height = 125, height = 135
font_size = 50
}) })
self.createButton({ self.createButton({
label="Upkeep", label = "Upkeep",
click_function = "doUpkeep", click_function = "doUpkeep",
function_owner = self, function_owner = self,
position = {1.84,0.1,-0.44}, position = {1.84, 0.1, -0.44},
scale = {0.12, 0.12, 0.12}, scale = {0.12, 0.12, 0.12},
width = 800, width = 800,
height = 280, height = 280,
@ -93,293 +70,271 @@ function onload(save_state)
local state = JSON.decode(save_state) local state = JSON.decode(save_state)
if state ~= nil then if state ~= nil then
if state.playerColor ~= nil then zoneID = state.zoneID
PLAYER_COLOR = state.playerColor PLAYER_COLOR = state.playerColor
end activeInvestigatorId = state.activeInvestigatorId
if state.zoneID ~= nil then
zoneID = state.zoneID
Wait.time(checkDeckZoneExists, 30)
else
spawnDeckZone()
end
else
spawnDeckZone()
end end
if getObjectFromGUID(zoneID) == nil then spawnDeckZone() end
COLLISION_ENABLED = true COLLISION_ENABLED = true
end end
function onSave() ---------------------------------------------------------
return JSON.encode({ zoneID=zoneID, playerColor=PLAYER_COLOR }) -- utility functions
---------------------------------------------------------
function log(message)
if DEBUG then print(message) end
end end
-- send messages to player who clicked button if no seated player found
function setMessageColor(color) function setMessageColor(color)
-- send messages to player who clicked button if no seated player found messageColor = Player[PLAYER_COLOR].seated and PLAYER_COLOR or color
messageColor = Player[PLAYER_COLOR].seated and PLAYER_COLOR or color
end end
-- get the draw deck and discard pile objects function spawnDeckZone()
function getDrawDiscardDecks() spawnObject({
drawDeck = nil position = self.positionToWorld({-1.4, 0, 0.3 }),
discardPile = nil scale = {3, 5, 8 },
topCard = nil type = 'ScriptingTrigger',
callback = function (zone) zoneID = zone.getGUID() end,
local zone = getObjectFromGUID(zoneID) callback_owner = self,
if zone == nil then return end rotation = self.getRotation()
})
for i,object in ipairs(zone.getObjects()) do
if object.tag == "Deck" or object.tag == "Card" then
local relativePos = self.positionToLocal(object.getPosition())
if relativePos.z > 0.5 then
discardPile = object
else
if investigator == "Norman Withers" and object.tag == "Card" and not object.is_face_down then
topCard = object
else
drawDeck = object
end
end
end
end
end end
function doUpkeep(obj, color, alt_click) function searchArea(origin, size)
-- right-click binds to new player color return Physics.cast({
if alt_click then origin = origin,
PLAYER_COLOR = color direction = {0, 1, 0},
printToColor("Upkeep button bound to " .. color, color) orientation = PLAY_ZONE_ROTATION,
return type = 3,
end size = size,
max_distance = 1,
debug = DEBUG
})
end
setMessageColor(color) function doNotReady(card) return card.getVar("do_not_ready") or false end
-- unexhaust cards in play zone ---------------------------------------------------------
local objs = Physics.cast({ -- Discard buttons
origin = PLAY_ZONE_POSITION, ---------------------------------------------------------
direction = { x=0, y=1, z=0 },
type = 3,
size = PLAY_ZONE_SCALE,
orientation = PLAY_ZONE_ROTATION
})
local y = PLAY_ZONE_ROTATION.y -- builds a function that discards things in searchPosition to discardPosition
-- stuff on the card/deck will be put into the local trashcan
investigator = nil function makeDiscardHandlerFor(searchPosition, discardPosition)
local miniId = nil return function ()
local forcedLearning = false for _, hitObj in ipairs(findObjectsAtPosition(searchPosition)) do
for i,v in ipairs(objs) do local obj = hitObj.hit_object
local obj = v.hit_object if obj.tag == "Deck" or obj.tag == "Card" then
local props = obj.getCustomObject() or {} if obj.hasTag("PlayerCard") then
if obj.tag == "Card" and not obj.is_face_down and not doNotReady(obj) then obj.setPositionSmooth(DISCARD_PILE_POSITION, false, true)
local notes = JSON.decode(obj.getGMNotes()) or {} obj.setRotation(PLAY_ZONE_ROTATION)
local name = obj.getName() else
if notes.type == "Investigator" and notes.id ~= nil then obj.setPositionSmooth(discardPosition, false, true)
miniId = string.match(notes.id, "%d%d%d%d%d%d-") .. "-m" obj.setRotation({0, -90, 0})
end
if notes.type == "Investigator" or props.unique_back then
if string.match(name, "Jenny Barnes") ~= nil then
investigator = "Jenny Barnes"
elseif name == "Patrice Hathaway" then
investigator = name
elseif string.match(name, "Norman Withers") ~= nil then
investigator = "Norman Withers"
end
elseif name == "Forced Learning" then
forcedLearning = true
else
local r = obj.getRotation()
if (r.y - y > 10) or (y - r.y > 10) then
obj.setRotation(PLAY_ZONE_ROTATION)
end
end
elseif obj.getDescription() == "Action Token" then
if obj.is_face_down then obj.flip() end
end end
end -- don't touch the table or this playmat itself
elseif obj.guid ~= "4ee1f2" and obj ~= self then
-- flip investigator mini-card if found TRASHCAN.putObject(obj)
if miniId ~= nil then
objs = getObjects()
for i,obj in ipairs(objs) do
if obj.tag == "Card" then
local notes = JSON.decode(obj.getGMNotes())
if notes ~= nil and notes.type == "Minicard" and notes.id == miniId then
if obj.is_face_down then
obj.flip()
end
goto done
end
end
end
end
::done::
-- flip summoned servitor mini-cards (To-Do: don't flip all of them)
for i, obj in ipairs(getObjects()) do
if obj.tag == "Card" then
local notes = JSON.decode(obj.getGMNotes())
if notes ~= nil and notes.type == "Minicard" and notes.id == "09080-m" then
if obj.is_face_down then
obj.flip()
end
end
end end
end end
end
-- gain resource
getObjectFromGUID(RESOURCE_COUNTER_GUID).call("add_subtract")
if investigator == "Jenny Barnes" then
getObjectFromGUID(RESOURCE_COUNTER_GUID).call("add_subtract")
printToColor("Gaining 2 resources (Jenny)", messageColor)
end
-- special draw for Patrice Hathaway (shuffle discards if necessary)
if investigator == "Patrice Hathaway" then
patriceDraw()
return
end
-- special draw for Forced Learning
if forcedLearning then
forcedLearningDraw()
return
end
drawCardsWithReshuffle(1)
end end
function doDrawOne(obj, color) -- build a discard button to discard from searchPosition to discardPosition (number must be unique)
setMessageColor(color) function makeDiscardButton(position, discardPosition, number)
drawCardsWithReshuffle(1) local searchPosition = {-position[1], position[2], position[3] + 0.32}
local handler = makeDiscardHandlerFor(searchPosition, discardPosition)
local handlerName = 'handler' .. number
self.setVar(handlerName, handler)
self.createButton({
label = "Discard",
click_function = handlerName,
function_owner = self,
position = position,
scale = {0.12, 0.12, 0.12},
width = 800,
height = 280,
font_size = 180
})
end end
function doNotReady(card) function findObjectsAtPosition(localPos)
if card.getVar("do_not_ready") == true then return Physics.cast({
return true origin = self.positionToWorld(localPos),
else direction = {0, 1, 0},
return false orientation = {0, PLAY_ZONE_ROTATION.y + 90, 0},
end type = 3,
size = {3.2, 1, 2},
max_distance = 0,
debug = DEBUG
})
end end
-- draw X cards (shuffle discards if necessary) ---------------------------------------------------------
function drawCardsWithReshuffle(numCards) -- Upkeep button
if type(numCards) ~= "number" then numCards = 1 end ---------------------------------------------------------
getDrawDiscardDecks() function doUpkeep(_, color, alt_click)
setMessageColor(color)
if investigator == "Norman Withers" then -- right-click binds to new player color
local harbinger = false if alt_click then
if topCard ~= nil and topCard.getName() == "The Harbinger" then PLAYER_COLOR = color
harbinger = true printToColor("Upkeep button bound to " .. color, color)
else return
if drawDeck ~= nil and not drawDeck.is_face_down then end
local cards = drawDeck.getObjects()
local bottomCard = cards[#cards] local forcedLearning = false
if bottomCard.name == "The Harbinger" then
harbinger = true -- unexhaust cards in play zone, flip action tokens and find forcedLearning
end for _, v in ipairs(searchArea(PLAY_ZONE_POSITION, PLAY_ZONE_SCALE)) do
end local obj = v.hit_object
if obj.tag == "Card" and not obj.is_face_down and not doNotReady(obj) then
local notes = JSON.decode(obj.getGMNotes()) or {}
if notes.id == "08031" then
forcedLearning = true
elseif notes.type ~= "Investigator" then
obj.setRotation(PLAY_ZONE_ROTATION)
-- check for cards with 'replenish' in their metadata
if notes.uses ~= nil then
local count = notes.uses[1].count
local replenish = notes.uses[1].replenish
if count and replenish then replenishTokens(obj, count, replenish) end
end end
end
elseif obj.getDescription() == "Action Token" and obj.is_face_down then
obj.flip()
end
end
if harbinger then -- flip investigator mini-card if found
printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) -- flip summoned servitor mini-cards (To-Do: don't flip all of them)
return -1 if activeInvestigatorId ~= nil then
end local miniId = string.match(activeInvestigatorId, "%d%d%d%d%d") .. "-m"
for _, obj in ipairs(getObjects()) do
if topCard ~= nil then if obj.tag == "Card" then
topCard.deal(numCards, PLAYER_COLOR) local notes = JSON.decode(obj.getGMNotes())
numCards = numCards - 1 if obj.is_face_down and notes ~= nil and notes.type == "Minicard" and (notes.id == miniId or notes.id == "09080-m") then
if numCards == 0 then return end obj.flip()
end end
end
end end
end
local deckSize -- gain a resource
if drawDeck == nil then RESOURCE_COUNTER.call("add_subtract")
deckSize = 0
elseif drawDeck.tag == "Deck" then
deckSize = #drawDeck.getObjects()
else
deckSize = 1
end
if deckSize >= numCards then -- gain an additional resource for Jenny Barnes
drawCards(numCards) if string.match(activeInvestigatorId, "%d%d%d%d%d") == "02003" then
return RESOURCE_COUNTER.call("add_subtract")
end printToColor("Gaining 2 resources (Jenny)", messageColor)
end
drawCards(deckSize) -- draw a card (with handling for Patrice and Forced Learning)
if discardPile ~= nil then if activeInvestigatorId == "06005" then
shuffleDiscardIntoDeck()
Wait.time(|| drawCards(numCards - deckSize), 1)
end
printToColor("Take 1 horror (drawing card from empty deck)", messageColor)
end
function drawCards(numCards)
if drawDeck == nil then return end
drawDeck.deal(numCards, PLAYER_COLOR)
end
function shuffleDiscardIntoDeck()
if not discardPile.is_face_down then discardPile.flip() end
discardPile.shuffle()
discardPile.setPositionSmooth(DRAW_DECK_POSITION, false, false)
drawDeck = discardPile
discardPile = nil
end
function patriceDraw()
local handSize = #Player[PLAYER_COLOR].getHandObjects() local handSize = #Player[PLAYER_COLOR].getHandObjects()
if handSize >= 5 then return end if handSize >= 5 then return end
local cardsToDraw = 5 - handSize local cardsToDraw = 5 - handSize
printToColor("Drawing " .. cardsToDraw .. " cards (Patrice)", messageColor) printToColor("Drawing " .. cardsToDraw .. " cards (Patrice)", messageColor)
drawCardsWithReshuffle(cardsToDraw) drawCardsWithReshuffle(cardsToDraw)
end elseif forcedLearning then
function forcedLearningDraw()
printToColor("Drawing 2 cards, discard 1 (Forced Learning)", messageColor) printToColor("Drawing 2 cards, discard 1 (Forced Learning)", messageColor)
drawCardsWithReshuffle(2) drawCardsWithReshuffle(2)
else
drawCardsWithReshuffle(1)
end
end end
function checkDeckZoneExists() -- legacy function for "add draw 1 button"
if getObjectFromGUID(zoneID) ~= nil then return end function doDrawOne(_, color)
spawnDeckZone() setMessageColor(color)
drawCardsWithReshuffle(1)
end end
function spawnDeckZone() -- draw X cards (shuffle discards if necessary)
local pos = self.positionToWorld(DECK_POSITION) function drawCardsWithReshuffle(numCards)
local zoneProps = { if type(numCards) ~= "number" then numCards = 1 end
position = pos, getDrawDiscardDecks()
scale = DECK_ZONE_SCALE,
type = 'ScriptingTrigger',
callback = 'zoneCallback',
callback_owner = self,
rotation = self.getRotation()
}
spawnObject(zoneProps)
end
function zoneCallback(zone) -- Norman Withers handling
zoneID = zone.getGUID() if string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then
end local harbinger = false
if topCard ~= nil and topCard.getName() == "The Harbinger" then harbinger = true
function findObjectsAtPosition(localPos) elseif drawDeck ~= nil and not drawDeck.is_face_down then
local globalPos = self.positionToWorld(localPos) local cards = drawDeck.getObjects()
local objList = Physics.cast({ if cards[#cards].name == "The Harbinger" then harbinger = true end
origin=globalPos, --Where the cast takes place
direction={0,1,0}, --Which direction it moves (up is shown)
type=2, --Type. 2 is "sphere"
size={2,2,2}, --How large that sphere is
max_distance=1, --How far it moves. Just a little bit
debug=false --If it displays the sphere when casting.
})
local decksAndCards = {}
for _, obj in ipairs(objList) do
if obj.hit_object.tag == "Deck" or obj.hit_object.tag == "Card" then
table.insert(decksAndCards, obj.hit_object)
end
end end
return decksAndCards
if harbinger then
printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor)
return
end
if topCard ~= nil then
topCard.deal(numCards, PLAYER_COLOR)
numCards = numCards - 1
if numCards == 0 then return end
end
end
local deckSize = 1
if drawDeck == nil then
deckSize = 0
elseif drawDeck.tag == "Deck" then
deckSize = #drawDeck.getObjects()
end
if deckSize >= numCards then
drawCards(numCards)
return
end
drawCards(deckSize)
if discardPile ~= nil then
shuffleDiscardIntoDeck()
Wait.time(|| drawCards(numCards - deckSize), 1)
end
printToColor("Take 1 horror (drawing card from empty deck)", messageColor)
end
-- get the draw deck and discard pile objects
function getDrawDiscardDecks()
drawDeck = nil
discardPile = nil
topCard = nil
local zone = getObjectFromGUID(zoneID)
if zone == nil then return end
for _, object in ipairs(zone.getObjects()) do
if object.tag == "Deck" or object.tag == "Card" then
if self.positionToLocal(object.getPosition()).z > 0.5 then
discardPile = object
-- Norman Withers handling
elseif string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" and object.tag == "Card" and not object.is_face_down then
topCard = object
else
drawDeck = object
end
end
end
end
function drawCards(numCards)
if drawDeck == nil then return end
drawDeck.deal(numCards, PLAYER_COLOR)
end
function shuffleDiscardIntoDeck()
if not discardPile.is_face_down then discardPile.flip() end
discardPile.shuffle()
discardPile.setPositionSmooth(DRAW_DECK_POSITION, false, false)
drawDeck = discardPile
discardPile = nil
end end
function spawnTokenOn(object, offsets, tokenType) function spawnTokenOn(object, offsets, tokenType)
@ -389,32 +344,62 @@ end
-- spawn a group of tokens of the given type on the object -- spawn a group of tokens of the given type on the object
function spawnTokenGroup(object, tokenType, tokenCount) function spawnTokenGroup(object, tokenType, tokenCount)
if (tokenCount < 1 or tokenCount > 12) then if (tokenCount < 1 or tokenCount > 12) then return end
return
end
local offsets = PLAYER_CARD_TOKEN_OFFSETS[tokenCount] local offsets = PLAYER_CARD_TOKEN_OFFSETS[tokenCount]
if offsets == nil then if offsets == nil then error("couldn't find offsets for " .. tokenCount .. ' tokens') end
error("couldn't find offsets for " .. tokenCount .. ' tokens')
end for i = 1, tokenCount do
local i = 0 spawnTokenOn(object, offsets[i], tokenType)
while i < tokenCount do
local offset = offsets[i + 1]
spawnTokenOn(object, offset, tokenType)
i = i + 1
end end
end end
function buildPlayerCardKey(object) ---------------------------------------------------------
return object.getName() .. ':' .. object.getDescription() -- playmat token spawning
---------------------------------------------------------
-- replenish Tokens for specific cards (like 'Physical Training (4)')
function replenishTokens(card, count, replenish)
local cardPos = card.getPosition()
-- don't continue for cards on your deck (Norman) or in your discard pile
if self.positionToLocal(cardPos).x < -1 then return end
-- get current amount of resource tokens on the card
local search = searchArea(cardPos, { 2.5, 0.5, 3.5 })
local foundTokens = 0
for _, obj in ipairs(search) do
local obj = obj.hit_object
if obj.getCustomObject().image == "http://cloud-3.steamusercontent.com/ugc/1758068501357192910/11DDDC7EF621320962FDCF3AE3211D5EDC3D1573/" then
foundTokens = foundTokens + math.abs(obj.getQuantity())
obj.destruct()
end
end
-- handling Runic Axe upgrade sheet for additional replenish
if card.getName() == "Runic Axe" then
for _, v in ipairs(searchArea(PLAY_ZONE_POSITION, PLAY_ZONE_SCALE)) 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
local newCount = foundTokens + replenish
if newCount > count then newCount = count end
spawnTokenGroup(card, "resource", newCount)
end end
function getPlayerCardData(object) function getPlayerCardData(object)
return PLAYER_CARDS[buildPlayerCardKey(object)] or PLAYER_CARDS[object.getName()] return PLAYER_CARDS[object.getName()..':'..object.getDescription()] or PLAYER_CARDS[object.getName()]
end end
function shouldSpawnTokens(object) function shouldSpawnTokens(object)
-- we assume we shouldn't spawn tokens if in doubt, this should -- don't spawn tokens if in doubt, this should only ever happen onLoad and prevents respawns
-- only ever happen on load and in that case prevents respawns
local spawned = DATA_HELPER.call('getSpawnedPlayerCardGuid', {object.getGUID()}) local spawned = DATA_HELPER.call('getSpawnedPlayerCardGuid', {object.getGUID()})
local hasDataHelperData = getPlayerCardData(object) local hasDataHelperData = getPlayerCardData(object)
local cardMetadata = JSON.decode(object.getGMNotes()) or {} local cardMetadata = JSON.decode(object.getGMNotes()) or {}
@ -424,32 +409,54 @@ end
function markSpawned(object) function markSpawned(object)
local saved = DATA_HELPER.call('setSpawnedPlayerCardGuid', {object.getGUID(), true}) local saved = DATA_HELPER.call('setSpawnedPlayerCardGuid', {object.getGUID(), true})
if not saved then if not saved then error('attempt to mark player card spawned before data loaded') end
error('attempt to mark player card spawned before data loaded')
end
end end
-- contains position and amount of boxes for the upgradesheets that change uses
-- Alchemical Distillation, Damning Testimony, Living Ink and Hyperphysical Shotcaster
local customizationsTable = {
["09040"] = {5, 2},
["09059"] = {2, 2},
["09079"] = {3, 2},
["09119"] = {6, 4}
}
function spawnTokensFor(object) function spawnTokensFor(object)
local cardMetadata = JSON.decode(object.getGMNotes()) or {} local cardMetadata = JSON.decode(object.getGMNotes()) or {}
local token = nil
local type = nil local type = nil
local token = nil
local tokenCount = 0 local tokenCount = 0
if (cardMetadata.uses ~= nil) then if cardMetadata.uses ~= nil then
for i, useInfo in ipairs(cardMetadata.uses) do for _, useInfo in ipairs(cardMetadata.uses) do
token = useInfo.token
type = useInfo.type type = useInfo.type
token = useInfo.token
tokenCount = useInfo.count tokenCount = useInfo.count
if (activeInvestigatorId == "03004" and useInfo.type == "Charge") then
tokenCount = tokenCount + 1
end
log("Spawning tokens for "..object.getName()..'['..object.getDescription()..']: '..tokenCount.."x "..token)
spawnTokenGroup(object, token, tokenCount)
end end
-- additional uses for certain customizable cards (by checking the upgradesheets)
if customizationsTable[cardMetadata.id] ~= nil then
for _, obj in ipairs(searchArea(PLAY_ZONE_POSITION, PLAY_ZONE_SCALE)) do
local obj = obj.hit_object
if obj.tag == "Card" then
local notes = JSON.decode(obj.getGMNotes()) or {}
if notes.id == (cardMetadata.id .. "-c") then
local pos = customizationsTable[cardMetadata.id][1]
local boxes = customizationsTable[cardMetadata.id][2]
if obj.getVar("markedBoxes")[pos] == boxes then tokenCount = tokenCount + 2 end
break
end
end
end
end
-- additional charge for Akachi
if activeInvestigatorId == "03004" and type == "Charge" then tokenCount = tokenCount + 1 end
log("Spawning tokens for "..object.getName()..'['..object.getDescription()..']: '..tokenCount.."x "..token)
spawnTokenGroup(object, token, tokenCount)
else else
local data = getPlayerCardData(object) local data = getPlayerCardData(object)
if data == nil then if data == nil then error('attempt to spawn tokens for ' .. object.getName() .. ': no token data') end
error('attempt to spawn tokens for ' .. object.getName() .. ': no token data')
end
token = data['tokenType'] token = data['tokenType']
tokenCount = data['tokenCount'] tokenCount = data['tokenCount']
log(object.getName() .. '[' .. object.getDescription() .. ']' .. ' : ' .. data['tokenType'] .. ' : ' .. data['tokenCount']) log(object.getName() .. '[' .. object.getDescription() .. ']' .. ' : ' .. data['tokenType'] .. ' : ' .. data['tokenCount'])
@ -460,22 +467,19 @@ function spawnTokensFor(object)
end end
function resetSpawnState() function resetSpawnState()
local zone = getObjectFromGUID(zoneID) local zone = getObjectFromGUID(zoneID)
if zone == nil then return end if zone == nil then return end
for i,object in ipairs(zone.getObjects()) do for _, object in ipairs(zone.getObjects()) do
if object.tag == "Card" then if object.tag == "Card" then
local guid = object.getGUID() unmarkSpawned(object.getGUID(), true)
if guid ~= nil then unmarkSpawned(guid, true) end elseif object.tag == "Deck" then
elseif object.tag == "Deck" then local cards = object.getObjects()
local cards = object.getObjects() for _, v in ipairs(cards) do
if (cards ~= nil) then unmarkSpawned(v.guid)
for i,v in ipairs(cards) do end
if v.guid ~= nil then unmarkSpawned(v.guid) end
end
end
end
end end
end
end end
function unmarkSpawned(guid, force) function unmarkSpawned(guid, force)
@ -484,68 +488,102 @@ function unmarkSpawned(guid, force)
end end
function onCollisionEnter(collision_info) function onCollisionEnter(collision_info)
if (collision_info.collision_object.name == "Card") then if not COLLISION_ENABLED then return end
maybeUpdateActiveInvestigator(collision_info.collision_object)
end
if not COLLISION_ENABLED then
return
end
local object = collision_info.collision_object
Wait.time(resetSpawnState, 1) Wait.time(resetSpawnState, 1)
-- anything to the left of this is legal to spawn local object = collision_info.collision_object
local discardSpawnBoundary = self.positionToWorld({-1.2, 0, 0})
local boundaryLocalToCard = object.positionToLocal(discardSpawnBoundary) -- only continue for cards
if boundaryLocalToCard.x > 0 then if object.name ~= "Card" and object.name ~= "CardCustom" then return end
log('not checking for token spawn, boundary relative is ' .. boundaryLocalToCard.x) maybeUpdateActiveInvestigator(object)
return
end -- don't spawn tokens for cards in discard pile / threat area
if not object.is_face_down and shouldSpawnTokens(object) then local localpos = self.positionToLocal(object.getPosition())
if localpos.x < -0.7 or localpos.z < -0.3 then
log('Not spawning tokens, relative coordinates are x: ' .. localpos.x .. ' z: ' .. localpos.z)
elseif not object.is_face_down and shouldSpawnTokens(object) then
spawnTokensFor(object) spawnTokensFor(object)
end end
end end
---------------------------------------------------------
-- investigator ID grabbing and stat tracker
---------------------------------------------------------
function maybeUpdateActiveInvestigator(card) function maybeUpdateActiveInvestigator(card)
local cardMetadata = JSON.decode(card.getGMNotes()) or {} local notes = JSON.decode(card.getGMNotes())
if (cardMetadata.type == "Investigator") then if notes ~= nil and notes.type == "Investigator" and notes.id ~= activeInvestigatorId then
activeInvestigatorId = cardMetadata.id activeInvestigatorId = notes.id
updateStatToken(willpowerTokenGuid, cardMetadata.willpowerIcons) STAT_TRACKER.call("updateStats", {notes.willpowerIcons, notes.intellectIcons, notes.combatIcons, notes.agilityIcons})
updateStatToken(intellectTokenGuid, cardMetadata.intellectIcons)
updateStatToken(combatTokenGuid, cardMetadata.combatIcons) -- change state of action tokens
updateStatToken(agilityTokenGuid, cardMetadata.agilityIcons) local search = searchArea(self.positionToWorld({-1.1, 0.05, -0.27}), {4, 1, 1})
local small_token = nil
local state_table = {
["Guardian"] = 1,
["Seeker"] = 2,
["Rogue"] = 3,
["Mystic"] = 4,
["Survivor"] = 5,
["Neutral"] = 6
}
for _, obj in ipairs(search) do
local obj = obj.hit_object
if obj.getDescription() == "Action Token" and obj.getStateId() > 0 then
if self.positionToLocal(obj.getPosition()).x > -0.95 then
small_token = obj
else
objState(obj, state_table[notes.class])
end
end
end
-- update the small token with special action for certain investigators
-- Ursula Downs: Investigate action
if activeInvestigatorId == "04002" then
objState(small_token, 8)
-- Daisy Walker (only for normal front, not parallel): Tome action
elseif activeInvestigatorId == "01002" or activeInvestigatorId == "01002-r" or activeInvestigatorId == "01002-pb" then
objState(small_token, 9)
-- Tony Morgan: Engage/Fight action
elseif activeInvestigatorId == "06003" then
objState(small_token, 10)
-- Finn Edwards: Evade action
elseif activeInvestigatorId == "04003" then
objState(small_token, 11)
-- Bob Jenkins: Play Item action
elseif activeInvestigatorId == "08016" then
objState(small_token, 14)
else
objState(small_token, state_table[notes.class])
end
end end
end end
function updateStatToken(tokenGuid, val) function objState(obj, stateId)
local statToken = getObjectFromGUID(tokenGuid) if obj.getStateId() ~= stateId then obj.setState(stateId) end
if (statToken == nil) then
return
end
statToken.call("reset_val")
for i = 1, val do
statToken.call("add_subtract", { alt_click = false })
end
end end
-- functions delegated to Global ---------------------------------------------------------
function drawChaostokenButton(object, player, isRightClick) -- calls to 'Global' / functions for calls from outside
-- local toPosition = self.positionToWorld(DRAWN_CHAOS_TOKEN_OFFSET) ---------------------------------------------------------
function drawChaostokenButton(_, _, isRightClick)
Global.call("drawChaostoken", {self, DRAWN_CHAOS_TOKEN_OFFSET, isRightClick}) Global.call("drawChaostoken", {self, DRAWN_CHAOS_TOKEN_OFFSET, isRightClick})
end end
function drawEncountercard(object, player, isRightClick) function drawEncountercard(_, _, isRightClick)
local toPosition = self.positionToWorld(DRAWN_ENCOUNTER_CARD_OFFSET) Global.call("drawEncountercard", {self.positionToWorld(DRAWN_ENCOUNTER_CARD_OFFSET), self.getRotation(), isRightClick})
Global.call("drawEncountercard", {toPosition, self.getRotation(), isRightClick})
end end
function spawnToken(position, tokenType) function spawnToken(position, tokenType)
Global.call('spawnToken', {position, tokenType}) Global.call('spawnToken', {position, tokenType, PLAY_ZONE_ROTATION})
end end
function updatePlayerCards(args) function updatePlayerCards(args)
local custom_data_helper = getObjectFromGUID(args[1]) local custom_data_helper = getObjectFromGUID(args[1])
data_player_cards = custom_data_helper.getTable("PLAYER_CARD_DATA") data_player_cards = custom_data_helper.getTable("PLAYER_CARD_DATA")
for k, v in pairs(data_player_cards) do for k, v in pairs(data_player_cards) do
PLAYER_CARDS[k] = v PLAYER_CARDS[k] = v
end end
end end

View File

@ -0,0 +1,76 @@
-- Stat Tracker
-- made by: Chr1Z
-- description: helps tracking the stats of your investigator
information = {
version = "1.1",
last_updated = "12.11.2022"
}
local BUTTON_PARAMETERS = {}
BUTTON_PARAMETERS.function_owner = self
BUTTON_PARAMETERS.height = 650
BUTTON_PARAMETERS.width = 700
BUTTON_PARAMETERS.position = { -4.775, 0.1, -0.03 }
BUTTON_PARAMETERS.color = { 0, 0, 0, 0 }
BUTTON_PARAMETERS.font_color = { 0, 0, 0, 100 }
BUTTON_PARAMETERS.font_size = 450
X_OFFSET = 1.91
function onSave() return JSON.encode(stats) end
-- load stats and make buttons (left to right)
function onLoad(saved_data)
stats = JSON.decode(saved_data) or { 1, 1, 1, 1 }
for i = 1, 4 do
BUTTON_PARAMETERS.position[1] = BUTTON_PARAMETERS.position[1] + X_OFFSET
BUTTON_PARAMETERS.label = stats[i] .. " "
BUTTON_PARAMETERS.click_function = attachIndex("button_click", i)
self.createButton(BUTTON_PARAMETERS)
end
self.addContextMenuItem("More Information", function()
printToAll("------------------------------", "White")
printToAll("Stat Tracker v" .. information["version"] .. " by Chr1Z", "Orange")
printToAll("last updated: " .. information["last_updated"], "White")
end)
self.addContextMenuItem("Reset to 1s", function() updateStats({ 1, 1, 1, 1 }) end)
end
-- helper function to carry index
function attachIndex(click_function, index)
local fn_name = click_function .. index
_G[fn_name] = function(obj, player_color, isRightClick)
_G[click_function](obj, player_color, isRightClick, index)
end
return fn_name
end
function button_click(_, _, isRightClick, index)
stats[index] = math.min(math.max(stats[index] + (isRightClick and -1 or 1), 0), 99)
changeButton(index)
end
function changeButton(index)
local font_size = BUTTON_PARAMETERS.font_size
local whitespace = " "
if stats[index] > 9 then
font_size = BUTTON_PARAMETERS.font_size * 0.65
whitespace = " "
end
self.editButton({ index = index - 1, label = stats[index] .. whitespace, font_size = font_size })
end
-- formatting of "newStats": {Willpower, Intellect, Fight, Agility}
function updateStats(newStats)
if newStats and #newStats == 4 then
stats = newStats
elseif newStats then
printToAll("Provided new stats are incomplete or incorrectly formatted.", "Red")
return
end
for i = 1, 4 do changeButton(i) end
end