diff --git a/config.json b/config.json index 20195516..eed60b85 100644 --- a/config.json +++ b/config.json @@ -206,27 +206,11 @@ "EdgeoftheEarth.895eaa", "TheDream-Eaters.a16a1a", "ReturntoTheCircleUndone.757324", - "Intellect.0016fc", "Playermat4Red.0840d5", - "Agility.181fa2", - "Combat.19026b", - "Agility.2c3f8d", "Playermat3Green.383d8b", - "Intellect.4ca990", "MiscDoominplay.652ff3", - "Willpower.85a8ed", "Playermat1White.8b081b", - "Willpower.8b6743", - "Combat.9136c6", - "Combat.93a48b", - "Agility.a0b6df", - "Willpower.afc290", - "Intellect.b4ef12", - "Combat.b661a6", "Playermat2Orange.bd0ff4", - "Intellect.c1fe65", - "Agility.d4df33", - "Willpower.fa6df4", "CustomDataHelper.2547b3", "LolaNeutral.637e17", "LolaNeutral.e003fe", @@ -258,7 +242,11 @@ "PhaseTracker.d0c8fa", "AllPlayerCards.15bb07", "Search-A-Card.24051a", - "231Notes-10152022.268764" + "231Notes-10152022.268764", + "StatTracker.af7ed7", + "StatTracker.e598c2", + "StatTracker.b4a5f7", + "StatTracker.e74881" ], "PlayArea": 1, "PlayerCounts": [ diff --git a/objects/Agility.2c3f8d.json b/objects/Agility.2c3f8d.json deleted file mode 100644 index d043dab9..00000000 --- a/objects/Agility.2c3f8d.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Agility.a0b6df.json b/objects/Agility.a0b6df.json deleted file mode 100644 index 1b2acbe5..00000000 --- a/objects/Agility.a0b6df.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Agility.d4df33.json b/objects/Agility.d4df33.json deleted file mode 100644 index c7513d8c..00000000 --- a/objects/Agility.d4df33.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Combat.19026b.json b/objects/Combat.19026b.json deleted file mode 100644 index c60a40c0..00000000 --- a/objects/Combat.19026b.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Intellect.0016fc.json b/objects/Intellect.0016fc.json deleted file mode 100644 index 63ea8098..00000000 --- a/objects/Intellect.0016fc.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Intellect.4ca990.json b/objects/Intellect.4ca990.json deleted file mode 100644 index c903d4be..00000000 --- a/objects/Intellect.4ca990.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Intellect.b4ef12.json b/objects/Intellect.b4ef12.json deleted file mode 100644 index 54a6ac79..00000000 --- a/objects/Intellect.b4ef12.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Intellect.c1fe65.json b/objects/Intellect.c1fe65.json deleted file mode 100644 index 67ebe9cb..00000000 --- a/objects/Intellect.c1fe65.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Playermat1White.8b081b.json b/objects/Playermat1White.8b081b.json index 311b7d57..36179aa0 100644 --- a/objects/Playermat1White.8b081b.json +++ b/objects/Playermat1White.8b081b.json @@ -228,7 +228,7 @@ "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": true, - "LuaScriptState": "{\"playerColor\":\"White\",\"zoneID\":\"7af2cf\"}", + "LuaScriptState": "{\"activeInvestigatorId\":\"00000\",\"playerColor\":\"White\",\"zoneID\":\"7af2cf\"}", "LuaScript_path": "Playermat1White.8b081b.ttslua", "MeasureMovement": false, "Name": "Custom_Tile", diff --git a/objects/Playermat1White.8b081b.ttslua b/objects/Playermat1White.8b081b.ttslua index 63b1b83b..6ca92838 100644 --- a/objects/Playermat1White.8b081b.ttslua +++ b/objects/Playermat1White.8b081b.ttslua @@ -1,41 +1,15 @@ --- set true to enable debug logging -DEBUG = false --- 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 } +--------------------------------------------------------- +-- specific setup (different for each playmat) +--------------------------------------------------------- --- play zone -PLAYER_COLOR = "White" -PLAY_ZONE_POSITION = { x=-54.42, y=4.10, z=20.96} -PLAY_ZONE_ROTATION = { x=0, y=270, z=0 } -PLAY_ZONE_SCALE = { x=36.63, y=5.10, z=14.59} +PLAYER_COLOR = "White" +PLAY_ZONE_POSITION = { x = -54.5, y = 4, z = 21 } +PLAY_ZONE_SCALE = { x = 36, y = 5.1, z = 14.5 } +DRAW_DECK_POSITION = { x = -54.8, y = 2.5, z = 4.29 } +DISCARD_PILE_POSITION = { x = -58.9, y = 4, z = 4.29 } -RESOURCE_COUNTER_GUID = "4406f0" - --- the position of the global discard pile --- 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" +TRASHCAN = getObjectFromGUID("147e80") +STAT_TRACKER = getObjectFromGUID("e598c2") +RESOURCE_COUNTER = getObjectFromGUID("4406f0") require("playermat/Playmat") diff --git a/objects/Playermat2Orange.bd0ff4.json b/objects/Playermat2Orange.bd0ff4.json index e4ee53eb..79b1b012 100644 --- a/objects/Playermat2Orange.bd0ff4.json +++ b/objects/Playermat2Orange.bd0ff4.json @@ -228,7 +228,7 @@ "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": true, - "LuaScriptState": "{\"playerColor\":\"Orange\",\"zoneID\":\"b047f8\"}", + "LuaScriptState": "{\"activeInvestigatorId\":\"00000\",\"playerColor\":\"Orange\",\"zoneID\":\"b047f8\"}", "LuaScript_path": "Playermat2Orange.bd0ff4.ttslua", "MeasureMovement": false, "Name": "Custom_Tile", diff --git a/objects/Playermat2Orange.bd0ff4.ttslua b/objects/Playermat2Orange.bd0ff4.ttslua index c13d0c19..d33d35dc 100644 --- a/objects/Playermat2Orange.bd0ff4.ttslua +++ b/objects/Playermat2Orange.bd0ff4.ttslua @@ -1,41 +1,15 @@ --- set true to enable debug logging -DEBUG = false --- 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 } +--------------------------------------------------------- +-- specific setup (different for each playmat) +--------------------------------------------------------- --- play zone -PLAYER_COLOR = "Orange" -PLAY_ZONE_POSITION = { x=-54.53, y=4.10, z=-20.94} -PLAY_ZONE_ROTATION = { x=0, y=270, z=0 } -PLAY_ZONE_SCALE = { x=36.96, y=5.10, z=14.70} +PLAYER_COLOR = "Orange" +PLAY_ZONE_POSITION = { x = -54.5, y = 4, z = -21 } +PLAY_ZONE_SCALE = { x = 36, y = 5.1, z = 14.5 } +DRAW_DECK_POSITION = { x = -54.86, y = 2.5, z = -27.82 } +DISCARD_PILE_POSITION = { x = -58.96, y = 4, z = -27.82 } -RESOURCE_COUNTER_GUID = "816d84" - --- the position of the global discard pile --- 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" +TRASHCAN = getObjectFromGUID("f7b6c8") +STAT_TRACKER = getObjectFromGUID("b4a5f7") +RESOURCE_COUNTER = getObjectFromGUID("816d84") require("playermat/Playmat") diff --git a/objects/Playermat3Green.383d8b.json b/objects/Playermat3Green.383d8b.json index c750a37c..45791bdf 100644 --- a/objects/Playermat3Green.383d8b.json +++ b/objects/Playermat3Green.383d8b.json @@ -228,7 +228,7 @@ "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": true, - "LuaScriptState": "{\"playerColor\":\"Green\",\"zoneID\":\"fb28e1\"}", + "LuaScriptState": "{\"activeInvestigatorId\":\"00000\",\"playerColor\":\"Green\",\"zoneID\":\"fb28e1\"}", "LuaScript_path": "Playermat3Green.383d8b.ttslua", "MeasureMovement": false, "Name": "Custom_Tile", diff --git a/objects/Playermat3Green.383d8b.ttslua b/objects/Playermat3Green.383d8b.ttslua index f01598ac..4cf61742 100644 --- a/objects/Playermat3Green.383d8b.ttslua +++ b/objects/Playermat3Green.383d8b.ttslua @@ -1,41 +1,15 @@ --- set true to enable debug logging -DEBUG = false --- 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 } +--------------------------------------------------------- +-- specific setup (different for each playmat) +--------------------------------------------------------- --- play zone -PLAYER_COLOR = "Green" -PLAY_ZONE_POSITION = { x=-25, y=4, z=27 } -PLAY_ZONE_ROTATION = { x=0, y=0, z=0 } -PLAY_ZONE_SCALE = { x=30, y=5, z=15 } +PLAYER_COLOR = "Green" +PLAY_ZONE_POSITION = { x = -25, y = 4, z = 27 } +PLAY_ZONE_SCALE = { x = 30, y = 5, z = 14.5 } +DRAW_DECK_POSITION = { x = -37.26, y = 2.5, z = 26.4 } +DISCARD_PILE_POSITION = { x = -37.26, y = 4, z = 30.50 } -RESOURCE_COUNTER_GUID = "cd15ac" - --- the position of the global discard pile --- 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" +TRASHCAN = getObjectFromGUID("5f896a") +STAT_TRACKER = getObjectFromGUID("af7ed7") +RESOURCE_COUNTER = getObjectFromGUID("cd15ac") require("playermat/Playmat") diff --git a/objects/Playermat4Red.0840d5.json b/objects/Playermat4Red.0840d5.json index f3a48336..9f0ef153 100644 --- a/objects/Playermat4Red.0840d5.json +++ b/objects/Playermat4Red.0840d5.json @@ -228,7 +228,7 @@ "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": true, - "LuaScriptState": "{\"playerColor\":\"Red\",\"zoneID\":\"18538f\"}", + "LuaScriptState": "{\"activeInvestigatorId\":\"00000\",\"playerColor\":\"Red\",\"zoneID\":\"18538f\"}", "LuaScript_path": "Playermat4Red.0840d5.ttslua", "MeasureMovement": false, "Name": "Custom_Tile", diff --git a/objects/Playermat4Red.0840d5.ttslua b/objects/Playermat4Red.0840d5.ttslua index 1090eaa9..7c7e5f88 100644 --- a/objects/Playermat4Red.0840d5.ttslua +++ b/objects/Playermat4Red.0840d5.ttslua @@ -1,41 +1,15 @@ --- set true to enable debug logging -DEBUG = false --- 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 } +--------------------------------------------------------- +-- specific setup (different for each playmat) +--------------------------------------------------------- --- play zone -PLAYER_COLOR = "Red" -PLAY_ZONE_POSITION = { x=-25, y=4, z=-27 } -PLAY_ZONE_ROTATION = { x=0, y=180, z=0 } -PLAY_ZONE_SCALE = { x=30, y=5, z=15 } +PLAYER_COLOR = "Red" +PLAY_ZONE_POSITION = { x = -25, y = 4, z = -27 } +PLAY_ZONE_SCALE = { x = 30, y = 5, z = 14.5 } +DRAW_DECK_POSITION = { x = -13.78, y = 2.5, z = -26.37 } +DISCARD_PILE_POSITION = { x = -13.78, y = 4, z = -30.48 } -RESOURCE_COUNTER_GUID = "a4b60d" - --- the position of the global discard pile --- 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" +TRASHCAN = getObjectFromGUID("4b8594") +STAT_TRACKER = getObjectFromGUID("e74881") +RESOURCE_COUNTER = getObjectFromGUID("a4b60d") require("playermat/Playmat") diff --git a/objects/Agility.181fa2.json b/objects/StatTracker.af7ed7.json similarity index 55% rename from objects/Agility.181fa2.json rename to objects/StatTracker.af7ed7.json index 16baab3f..1db8f7e3 100644 --- a/objects/Agility.181fa2.json +++ b/objects/StatTracker.af7ed7.json @@ -19,41 +19,42 @@ }, "ImageScalar": 1, "ImageSecondaryURL": "", - "ImageURL": "https://i.imgur.com/vXVWwD0.png", + "ImageURL": "http://cloud-3.steamusercontent.com/ugc/1910115722579978285/38E3156A777396FF8C96D2191720790162749C40/", "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, "GMNotes": "", - "GUID": "181fa2", - "Grid": false, + "GUID": "af7ed7", + "Grid": true, "GridProjection": false, "Hands": false, "HideWhenFaceDown": false, "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": true, - "LuaScript": "require(\"playermat/SkillToken\")", - "LuaScriptState": "[true,0]", + "LuaScriptState": "[1,1,1,1]", + "LuaScript_path": "StatTracker.af7ed7.ttslua", "MeasureMovement": false, "Name": "Custom_Token", - "Nickname": "Agility", - "Snap": false, + "Nickname": "Stat Tracker", + "Snap": true, "Sticky": true, "Tags": [ - "CleanUpHelper_ignore" + "CleanUpHelper_ignore", + "displacement_excluded" ], - "Tooltip": false, + "Tooltip": true, "Transform": { - "posX": -35.602, - "posY": 1.587, - "posZ": 19.236, + "posX": -32, + "posY": 1.531, + "posZ": 19.3, "rotX": 0, "rotY": 0, "rotZ": 0, - "scaleX": 0.429196239, + "scaleX": 0.95, "scaleY": 1, - "scaleZ": 0.429196239 + "scaleZ": 0.95 }, "Value": 0, "XmlUI": "" diff --git a/objects/StatTracker.af7ed7.ttslua b/objects/StatTracker.af7ed7.ttslua new file mode 100644 index 00000000..22be7795 --- /dev/null +++ b/objects/StatTracker.af7ed7.ttslua @@ -0,0 +1 @@ +require("playermat/statTracker") diff --git a/objects/Combat.b661a6.json b/objects/StatTracker.b4a5f7.json similarity index 55% rename from objects/Combat.b661a6.json rename to objects/StatTracker.b4a5f7.json index a6e0a378..5b23a243 100644 --- a/objects/Combat.b661a6.json +++ b/objects/StatTracker.b4a5f7.json @@ -19,41 +19,42 @@ }, "ImageScalar": 1, "ImageSecondaryURL": "", - "ImageURL": "https://i.imgur.com/YBjxze6.png", + "ImageURL": "http://cloud-3.steamusercontent.com/ugc/1910115722579978285/38E3156A777396FF8C96D2191720790162749C40/", "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, "GMNotes": "", - "GUID": "b661a6", - "Grid": false, + "GUID": "b4a5f7", + "Grid": true, "GridProjection": false, "Hands": false, "HideWhenFaceDown": false, "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": true, - "LuaScript": "require(\"playermat/SkillToken\")", - "LuaScriptState": "[true,0]", + "LuaScriptState": "[1,1,1,1]", + "LuaScript_path": "StatTracker.b4a5f7.ttslua", "MeasureMovement": false, "Name": "Custom_Token", - "Nickname": "Combat", - "Snap": false, + "Nickname": "Stat Tracker", + "Snap": true, "Sticky": true, "Tags": [ - "CleanUpHelper_ignore" + "CleanUpHelper_ignore", + "displacement_excluded" ], - "Tooltip": false, + "Tooltip": true, "Transform": { - "posX": -47.641, - "posY": 1.591, - "posZ": -24.179, + "posX": -47.75, + "posY": 1.531, + "posZ": -22, "rotX": 0, "rotY": 270, "rotZ": 0, - "scaleX": 0.429196239, + "scaleX": 0.95, "scaleY": 1, - "scaleZ": 0.429196239 + "scaleZ": 0.95 }, "Value": 0, "XmlUI": "" diff --git a/objects/StatTracker.b4a5f7.ttslua b/objects/StatTracker.b4a5f7.ttslua new file mode 100644 index 00000000..22be7795 --- /dev/null +++ b/objects/StatTracker.b4a5f7.ttslua @@ -0,0 +1 @@ +require("playermat/statTracker") diff --git a/objects/Combat.9136c6.json b/objects/StatTracker.e598c2.json similarity index 55% rename from objects/Combat.9136c6.json rename to objects/StatTracker.e598c2.json index a0b18809..08ca80d9 100644 --- a/objects/Combat.9136c6.json +++ b/objects/StatTracker.e598c2.json @@ -19,41 +19,42 @@ }, "ImageScalar": 1, "ImageSecondaryURL": "", - "ImageURL": "https://i.imgur.com/YBjxze6.png", + "ImageURL": "http://cloud-3.steamusercontent.com/ugc/1910115722579978285/38E3156A777396FF8C96D2191720790162749C40/", "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, "GMNotes": "", - "GUID": "9136c6", - "Grid": false, + "GUID": "e598c2", + "Grid": true, "GridProjection": false, "Hands": false, "HideWhenFaceDown": false, "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": true, - "LuaScript": "require(\"playermat/SkillToken\")", - "LuaScriptState": "[true,0]", + "LuaScriptState": "[1,1,1,1]", + "LuaScript_path": "StatTracker.e598c2.ttslua", "MeasureMovement": false, "Name": "Custom_Token", - "Nickname": "Combat", - "Snap": false, + "Nickname": "Stat Tracker", + "Snap": true, "Sticky": true, "Tags": [ - "CleanUpHelper_ignore" + "CleanUpHelper_ignore", + "displacement_excluded" ], - "Tooltip": false, + "Tooltip": true, "Transform": { - "posX": -47.642, - "posY": 1.6, - "posZ": 7.29, + "posX": -47.75, + "posY": 1.531, + "posZ": 9, "rotX": 0, "rotY": 270, "rotZ": 0, - "scaleX": 0.429196239, + "scaleX": 0.95, "scaleY": 1, - "scaleZ": 0.429196239 + "scaleZ": 0.95 }, "Value": 0, "XmlUI": "" diff --git a/objects/StatTracker.e598c2.ttslua b/objects/StatTracker.e598c2.ttslua new file mode 100644 index 00000000..22be7795 --- /dev/null +++ b/objects/StatTracker.e598c2.ttslua @@ -0,0 +1 @@ +require("playermat/statTracker") diff --git a/objects/Combat.93a48b.json b/objects/StatTracker.e74881.json similarity index 55% rename from objects/Combat.93a48b.json rename to objects/StatTracker.e74881.json index b8e41559..3b288abd 100644 --- a/objects/Combat.93a48b.json +++ b/objects/StatTracker.e74881.json @@ -19,41 +19,42 @@ }, "ImageScalar": 1, "ImageSecondaryURL": "", - "ImageURL": "https://i.imgur.com/YBjxze6.png", + "ImageURL": "http://cloud-3.steamusercontent.com/ugc/1910115722579978285/38E3156A777396FF8C96D2191720790162749C40/", "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, "GMNotes": "", - "GUID": "93a48b", - "Grid": false, + "GUID": "e74881", + "Grid": true, "GridProjection": false, "Hands": false, "HideWhenFaceDown": false, "IgnoreFoW": false, "LayoutGroupSortIndex": 0, "Locked": true, - "LuaScript": "require(\"playermat/SkillToken\")", - "LuaScriptState": "[true,0]", + "LuaScriptState": "[1,1,1,1]", + "LuaScript_path": "StatTracker.e74881.ttslua", "MeasureMovement": false, "Name": "Custom_Token", - "Nickname": "Combat", - "Snap": false, + "Nickname": "Stat Tracker", + "Snap": true, "Sticky": true, "Tags": [ - "CleanUpHelper_ignore" + "CleanUpHelper_ignore", + "displacement_excluded" ], - "Tooltip": false, + "Tooltip": true, "Transform": { - "posX": -17.326, - "posY": 1.55, - "posZ": -19.216, + "posX": -19, + "posY": 1.531, + "posZ": -19.35, "rotX": 0, "rotY": 180, "rotZ": 0, - "scaleX": 0.429196239, + "scaleX": 0.95, "scaleY": 1, - "scaleZ": 0.429196239 + "scaleZ": 0.95 }, "Value": 0, "XmlUI": "" diff --git a/objects/StatTracker.e74881.ttslua b/objects/StatTracker.e74881.ttslua new file mode 100644 index 00000000..22be7795 --- /dev/null +++ b/objects/StatTracker.e74881.ttslua @@ -0,0 +1 @@ +require("playermat/statTracker") diff --git a/objects/Willpower.85a8ed.json b/objects/Willpower.85a8ed.json deleted file mode 100644 index 91d466f2..00000000 --- a/objects/Willpower.85a8ed.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Willpower.8b6743.json b/objects/Willpower.8b6743.json deleted file mode 100644 index 68ae6689..00000000 --- a/objects/Willpower.8b6743.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Willpower.afc290.json b/objects/Willpower.afc290.json deleted file mode 100644 index da9bd821..00000000 --- a/objects/Willpower.afc290.json +++ /dev/null @@ -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": "" -} diff --git a/objects/Willpower.fa6df4.json b/objects/Willpower.fa6df4.json deleted file mode 100644 index 0404e1f7..00000000 --- a/objects/Willpower.fa6df4.json +++ /dev/null @@ -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": "" -} diff --git a/src/playermat/Playmat.ttslua b/src/playermat/Playmat.ttslua index 3d835d44..890a856c 100644 --- a/src/playermat/Playmat.ttslua +++ b/src/playermat/Playmat.ttslua @@ -1,90 +1,67 @@ -local activeInvestigatorId = nil +--------------------------------------------------------- +-- general setup (identical for each playmat) +--------------------------------------------------------- -function log(message) - if DEBUG then - print(message) - end -end +-- set true to enable debug logging and show Physics.cast() +local DEBUG = false --- builds a function that discards things in searchPostion to discardPostition -function makeDiscardHandlerFor(searchPosition, discardPosition) - 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 +-- we use this to turn off collision handling until onLoad() is complete +local COLLISION_ENABLED = false --- build a discard button at position to discard from searchPosition to discardPosition --- number must be unique -function makeDiscardButton(position, searchPosition, discardPosition, number) - 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 +-- position offsets relative to mat [x, y, z] +local DRAWN_ENCOUNTER_CARD_OFFSET = {1.365, 0.5, -0.635} +local DRAWN_CHAOS_TOKEN_OFFSET = {-1.55, 0.5, -0.58} +local DISCARD_BUTTON_OFFSETS = { + {-1.365, 0.1, -0.945}, + {-0.91, 0.1, -0.945}, + {-0.455, 0.1, -0.945}, + {0, 0.1, -0.945}, + {0.455, 0.1, -0.945}, + {0.91, 0.1, -0.945} +} -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 DATA_HELPER = getObjectFromGUID('708279') PLAYER_CARDS = DATA_HELPER.getTable('PLAYER_CARD_DATA') PLAYER_CARD_TOKEN_OFFSETS = DATA_HELPER.getTable('PLAYER_CARD_TOKEN_OFFSETS') - -- positions of encounter card slots - local encounterSlots = { - {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 + for i = 1, 6 do + makeDiscardButton(DISCARD_BUTTON_OFFSETS[i], {-3.85, 3, 10.38}, i) end self.createButton({ - label = " ", click_function = "drawEncountercard", function_owner = self, - position = {-1.88,0,-0.7}, - rotation = {0,-15,0}, - width = 170, - height = 255, - font_size = 50 + position = {-1.84, 0, -0.65}, + rotation = {0, 80, 0}, + width = 265, + height = 190 }) self.createButton({ - label=" ", click_function = "drawChaostokenButton", function_owner = self, - position = {1.84,0.0,-0.74}, - rotation = {0,-45,0}, - width = 125, - height = 125, - font_size = 50 + position = {1.85, 0, -0.74}, + rotation = {0, -45, 0}, + width = 135, + height = 135 }) self.createButton({ - label="Upkeep", + label = "Upkeep", click_function = "doUpkeep", function_owner = self, - position = {1.84,0.1,-0.44}, + position = {1.84, 0.1, -0.44}, scale = {0.12, 0.12, 0.12}, width = 800, height = 280, @@ -93,293 +70,271 @@ function onload(save_state) local state = JSON.decode(save_state) if state ~= nil then - if state.playerColor ~= nil then - PLAYER_COLOR = state.playerColor - end - if state.zoneID ~= nil then - zoneID = state.zoneID - Wait.time(checkDeckZoneExists, 30) - else - spawnDeckZone() - end - else - spawnDeckZone() + zoneID = state.zoneID + PLAYER_COLOR = state.playerColor + activeInvestigatorId = state.activeInvestigatorId end + if getObjectFromGUID(zoneID) == nil then spawnDeckZone() end COLLISION_ENABLED = true end -function onSave() - return JSON.encode({ zoneID=zoneID, playerColor=PLAYER_COLOR }) +--------------------------------------------------------- +-- utility functions +--------------------------------------------------------- + +function log(message) + if DEBUG then print(message) end end +-- send messages to player who clicked button if no seated player found 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 --- 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 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 +function spawnDeckZone() + spawnObject({ + position = self.positionToWorld({-1.4, 0, 0.3 }), + scale = {3, 5, 8 }, + type = 'ScriptingTrigger', + callback = function (zone) zoneID = zone.getGUID() end, + callback_owner = self, + rotation = self.getRotation() + }) end -function doUpkeep(obj, color, alt_click) - -- right-click binds to new player color - if alt_click then - PLAYER_COLOR = color - printToColor("Upkeep button bound to " .. color, color) - return - end +function searchArea(origin, size) + return Physics.cast({ + origin = origin, + direction = {0, 1, 0}, + orientation = PLAY_ZONE_ROTATION, + type = 3, + 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({ - origin = PLAY_ZONE_POSITION, - direction = { x=0, y=1, z=0 }, - type = 3, - size = PLAY_ZONE_SCALE, - orientation = PLAY_ZONE_ROTATION - }) +--------------------------------------------------------- +-- Discard buttons +--------------------------------------------------------- - local y = PLAY_ZONE_ROTATION.y - - investigator = nil - local miniId = nil - local forcedLearning = false - for i,v in ipairs(objs) do - local obj = v.hit_object - local props = obj.getCustomObject() or {} - if obj.tag == "Card" and not obj.is_face_down and not doNotReady(obj) then - local notes = JSON.decode(obj.getGMNotes()) or {} - local name = obj.getName() - if notes.type == "Investigator" and notes.id ~= nil then - miniId = string.match(notes.id, "%d%d%d%d%d%d-") .. "-m" - 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 +-- builds a function that discards things in searchPosition to discardPosition +-- stuff on the card/deck will be put into the local trashcan +function makeDiscardHandlerFor(searchPosition, discardPosition) + return function () + for _, hitObj in ipairs(findObjectsAtPosition(searchPosition)) do + local obj = hitObj.hit_object + if obj.tag == "Deck" or obj.tag == "Card" then + if obj.hasTag("PlayerCard") then + obj.setPositionSmooth(DISCARD_PILE_POSITION, false, true) + obj.setRotation(PLAY_ZONE_ROTATION) + else + obj.setPositionSmooth(discardPosition, false, true) + obj.setRotation({0, -90, 0}) end - end - - -- flip investigator mini-card if found - 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 + -- don't touch the table or this playmat itself + elseif obj.guid ~= "4ee1f2" and obj ~= self then + TRASHCAN.putObject(obj) 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) - setMessageColor(color) - drawCardsWithReshuffle(1) +-- build a discard button to discard from searchPosition to discardPosition (number must be unique) +function makeDiscardButton(position, discardPosition, number) + 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 -function doNotReady(card) - if card.getVar("do_not_ready") == true then - return true - else - return false - end +function findObjectsAtPosition(localPos) + return Physics.cast({ + origin = self.positionToWorld(localPos), + direction = {0, 1, 0}, + orientation = {0, PLAY_ZONE_ROTATION.y + 90, 0}, + type = 3, + size = {3.2, 1, 2}, + max_distance = 0, + debug = DEBUG + }) end --- draw X cards (shuffle discards if necessary) -function drawCardsWithReshuffle(numCards) - if type(numCards) ~= "number" then numCards = 1 end +--------------------------------------------------------- +-- Upkeep button +--------------------------------------------------------- - getDrawDiscardDecks() +function doUpkeep(_, color, alt_click) + setMessageColor(color) - if investigator == "Norman Withers" then - local harbinger = false - if topCard ~= nil and topCard.getName() == "The Harbinger" then - harbinger = true - else - if drawDeck ~= nil and not drawDeck.is_face_down then - local cards = drawDeck.getObjects() - local bottomCard = cards[#cards] - if bottomCard.name == "The Harbinger" then - harbinger = true - end - end + -- right-click binds to new player color + if alt_click then + PLAYER_COLOR = color + printToColor("Upkeep button bound to " .. color, color) + return + end + + local forcedLearning = false + + -- unexhaust cards in play zone, flip action tokens and find forcedLearning + for _, v in ipairs(searchArea(PLAY_ZONE_POSITION, PLAY_ZONE_SCALE)) do + 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 + elseif obj.getDescription() == "Action Token" and obj.is_face_down then + obj.flip() + end + end - if harbinger then - printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) - return -1 - end - - if topCard ~= nil then - topCard.deal(numCards, PLAYER_COLOR) - numCards = numCards - 1 - if numCards == 0 then return end + -- flip investigator mini-card if found + -- flip summoned servitor mini-cards (To-Do: don't flip all of them) + if activeInvestigatorId ~= nil then + local miniId = string.match(activeInvestigatorId, "%d%d%d%d%d") .. "-m" + for _, obj in ipairs(getObjects()) do + if obj.tag == "Card" then + local notes = JSON.decode(obj.getGMNotes()) + if obj.is_face_down and notes ~= nil and notes.type == "Minicard" and (notes.id == miniId or notes.id == "09080-m") then + obj.flip() end + end end + end - local deckSize - if drawDeck == nil then - deckSize = 0 - elseif drawDeck.tag == "Deck" then - deckSize = #drawDeck.getObjects() - else - deckSize = 1 - end + -- gain a resource + RESOURCE_COUNTER.call("add_subtract") - if deckSize >= numCards then - drawCards(numCards) - return - end + -- gain an additional resource for Jenny Barnes + if string.match(activeInvestigatorId, "%d%d%d%d%d") == "02003" then + RESOURCE_COUNTER.call("add_subtract") + printToColor("Gaining 2 resources (Jenny)", messageColor) + 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 - -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() + -- draw a card (with handling for Patrice and Forced Learning) + if activeInvestigatorId == "06005" then local handSize = #Player[PLAYER_COLOR].getHandObjects() if handSize >= 5 then return end local cardsToDraw = 5 - handSize printToColor("Drawing " .. cardsToDraw .. " cards (Patrice)", messageColor) drawCardsWithReshuffle(cardsToDraw) -end - -function forcedLearningDraw() + elseif forcedLearning then printToColor("Drawing 2 cards, discard 1 (Forced Learning)", messageColor) drawCardsWithReshuffle(2) + else + drawCardsWithReshuffle(1) + end end -function checkDeckZoneExists() - if getObjectFromGUID(zoneID) ~= nil then return end - spawnDeckZone() +-- legacy function for "add draw 1 button" +function doDrawOne(_, color) + setMessageColor(color) + drawCardsWithReshuffle(1) end -function spawnDeckZone() - local pos = self.positionToWorld(DECK_POSITION) - local zoneProps = { - position = pos, - scale = DECK_ZONE_SCALE, - type = 'ScriptingTrigger', - callback = 'zoneCallback', - callback_owner = self, - rotation = self.getRotation() - } - spawnObject(zoneProps) -end +-- draw X cards (shuffle discards if necessary) +function drawCardsWithReshuffle(numCards) + if type(numCards) ~= "number" then numCards = 1 end + getDrawDiscardDecks() -function zoneCallback(zone) - zoneID = zone.getGUID() -end - -function findObjectsAtPosition(localPos) - local globalPos = self.positionToWorld(localPos) - local objList = Physics.cast({ - 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 + -- Norman Withers handling + if string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then + local harbinger = false + if topCard ~= nil and topCard.getName() == "The Harbinger" then harbinger = true + elseif drawDeck ~= nil and not drawDeck.is_face_down then + local cards = drawDeck.getObjects() + if cards[#cards].name == "The Harbinger" then harbinger = true 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 function spawnTokenOn(object, offsets, tokenType) @@ -389,32 +344,62 @@ end -- spawn a group of tokens of the given type on the object function spawnTokenGroup(object, tokenType, tokenCount) - if (tokenCount < 1 or tokenCount > 12) then - return - end + if (tokenCount < 1 or tokenCount > 12) then return end local offsets = PLAYER_CARD_TOKEN_OFFSETS[tokenCount] - if offsets == nil then - error("couldn't find offsets for " .. tokenCount .. ' tokens') - end - local i = 0 - while i < tokenCount do - local offset = offsets[i + 1] - spawnTokenOn(object, offset, tokenType) - i = i + 1 + if offsets == nil then error("couldn't find offsets for " .. tokenCount .. ' tokens') end + + for i = 1, tokenCount do + spawnTokenOn(object, offsets[i], tokenType) 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 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 function shouldSpawnTokens(object) - -- we assume we shouldn't spawn tokens if in doubt, this should - -- only ever happen on load and in that case prevents respawns + -- don't spawn tokens if in doubt, this should only ever happen onLoad and prevents respawns local spawned = DATA_HELPER.call('getSpawnedPlayerCardGuid', {object.getGUID()}) local hasDataHelperData = getPlayerCardData(object) local cardMetadata = JSON.decode(object.getGMNotes()) or {} @@ -424,32 +409,54 @@ end function markSpawned(object) local saved = DATA_HELPER.call('setSpawnedPlayerCardGuid', {object.getGUID(), true}) - if not saved then - error('attempt to mark player card spawned before data loaded') - end + if not saved then error('attempt to mark player card spawned before data loaded') 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) local cardMetadata = JSON.decode(object.getGMNotes()) or {} - local token = nil local type = nil + local token = nil local tokenCount = 0 - if (cardMetadata.uses ~= nil) then - for i, useInfo in ipairs(cardMetadata.uses) do - token = useInfo.token + if cardMetadata.uses ~= nil then + for _, useInfo in ipairs(cardMetadata.uses) do type = useInfo.type + token = useInfo.token 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 + + -- 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 local data = getPlayerCardData(object) - if data == nil then - error('attempt to spawn tokens for ' .. object.getName() .. ': no token data') - end + if data == nil then error('attempt to spawn tokens for ' .. object.getName() .. ': no token data') end token = data['tokenType'] tokenCount = data['tokenCount'] log(object.getName() .. '[' .. object.getDescription() .. ']' .. ' : ' .. data['tokenType'] .. ' : ' .. data['tokenCount']) @@ -460,22 +467,19 @@ function spawnTokensFor(object) end function resetSpawnState() - local zone = getObjectFromGUID(zoneID) - if zone == nil then return end + local zone = getObjectFromGUID(zoneID) + if zone == nil then return end - for i,object in ipairs(zone.getObjects()) do - if object.tag == "Card" then - local guid = object.getGUID() - if guid ~= nil then unmarkSpawned(guid, true) end - elseif object.tag == "Deck" then - local cards = object.getObjects() - if (cards ~= nil) then - for i,v in ipairs(cards) do - if v.guid ~= nil then unmarkSpawned(v.guid) end - end - end - end + for _, object in ipairs(zone.getObjects()) do + if object.tag == "Card" then + unmarkSpawned(object.getGUID(), true) + elseif object.tag == "Deck" then + local cards = object.getObjects() + for _, v in ipairs(cards) do + unmarkSpawned(v.guid) + end end + end end function unmarkSpawned(guid, force) @@ -484,68 +488,102 @@ function unmarkSpawned(guid, force) end function onCollisionEnter(collision_info) - if (collision_info.collision_object.name == "Card") then - maybeUpdateActiveInvestigator(collision_info.collision_object) - end - if not COLLISION_ENABLED then - return - end - - local object = collision_info.collision_object + if not COLLISION_ENABLED then return end Wait.time(resetSpawnState, 1) - -- anything to the left of this is legal to spawn - local discardSpawnBoundary = self.positionToWorld({-1.2, 0, 0}) - local boundaryLocalToCard = object.positionToLocal(discardSpawnBoundary) - if boundaryLocalToCard.x > 0 then - log('not checking for token spawn, boundary relative is ' .. boundaryLocalToCard.x) - return - end - if not object.is_face_down and shouldSpawnTokens(object) then + local object = collision_info.collision_object + + -- only continue for cards + if object.name ~= "Card" and object.name ~= "CardCustom" then return end + maybeUpdateActiveInvestigator(object) + + -- don't spawn tokens for cards in discard pile / threat area + 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) end end +--------------------------------------------------------- +-- investigator ID grabbing and stat tracker +--------------------------------------------------------- + function maybeUpdateActiveInvestigator(card) - local cardMetadata = JSON.decode(card.getGMNotes()) or {} - if (cardMetadata.type == "Investigator") then - activeInvestigatorId = cardMetadata.id - updateStatToken(willpowerTokenGuid, cardMetadata.willpowerIcons) - updateStatToken(intellectTokenGuid, cardMetadata.intellectIcons) - updateStatToken(combatTokenGuid, cardMetadata.combatIcons) - updateStatToken(agilityTokenGuid, cardMetadata.agilityIcons) + local notes = JSON.decode(card.getGMNotes()) + if notes ~= nil and notes.type == "Investigator" and notes.id ~= activeInvestigatorId then + activeInvestigatorId = notes.id + STAT_TRACKER.call("updateStats", {notes.willpowerIcons, notes.intellectIcons, notes.combatIcons, notes.agilityIcons}) + + -- change state of action tokens + 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 -function updateStatToken(tokenGuid, val) - local statToken = getObjectFromGUID(tokenGuid) - if (statToken == nil) then - return - end - statToken.call("reset_val") - for i = 1, val do - statToken.call("add_subtract", { alt_click = false }) - end +function objState(obj, stateId) + if obj.getStateId() ~= stateId then obj.setState(stateId) end end --- functions delegated to Global -function drawChaostokenButton(object, player, isRightClick) - -- local toPosition = self.positionToWorld(DRAWN_CHAOS_TOKEN_OFFSET) +--------------------------------------------------------- +-- calls to 'Global' / functions for calls from outside +--------------------------------------------------------- + +function drawChaostokenButton(_, _, isRightClick) Global.call("drawChaostoken", {self, DRAWN_CHAOS_TOKEN_OFFSET, isRightClick}) end -function drawEncountercard(object, player, isRightClick) -local toPosition = self.positionToWorld(DRAWN_ENCOUNTER_CARD_OFFSET) -Global.call("drawEncountercard", {toPosition, self.getRotation(), isRightClick}) +function drawEncountercard(_, _, isRightClick) + Global.call("drawEncountercard", {self.positionToWorld(DRAWN_ENCOUNTER_CARD_OFFSET), self.getRotation(), isRightClick}) end function spawnToken(position, tokenType) - Global.call('spawnToken', {position, tokenType}) + Global.call('spawnToken', {position, tokenType, PLAY_ZONE_ROTATION}) end function updatePlayerCards(args) - local custom_data_helper = getObjectFromGUID(args[1]) - data_player_cards = custom_data_helper.getTable("PLAYER_CARD_DATA") - for k, v in pairs(data_player_cards) do - PLAYER_CARDS[k] = v - end -end + local custom_data_helper = getObjectFromGUID(args[1]) + data_player_cards = custom_data_helper.getTable("PLAYER_CARD_DATA") + for k, v in pairs(data_player_cards) do + PLAYER_CARDS[k] = v + end +end \ No newline at end of file diff --git a/src/playermat/statTracker.ttslua b/src/playermat/statTracker.ttslua new file mode 100644 index 00000000..068c3893 --- /dev/null +++ b/src/playermat/statTracker.ttslua @@ -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