3.9.0
This commit is contained in:
parent
d41b69bf4a
commit
e5aea0cf67
2367
unpacked.ttslua
2367
unpacked.ttslua
File diff suppressed because it is too large
Load Diff
32
unpacked.xml
32
unpacked.xml
@ -628,7 +628,7 @@
|
|||||||
<Panel class="doubleColumn-wrapper"
|
<Panel class="doubleColumn-wrapper"
|
||||||
padding="0 17 3 3"/>
|
padding="0 17 3 3"/>
|
||||||
<Button class="optionToggle"
|
<Button class="optionToggle"
|
||||||
image="option-off"
|
image="option_off"
|
||||||
rectAlignment="MiddleRight"
|
rectAlignment="MiddleRight"
|
||||||
offsetXY="-30 0"
|
offsetXY="-30 0"
|
||||||
colors="#FFFFFF|#dfdfdf"
|
colors="#FFFFFF|#dfdfdf"
|
||||||
@ -727,6 +727,21 @@
|
|||||||
</Cell>
|
</Cell>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
|
<!-- Option: Enable all card helpers -->
|
||||||
|
<Row class="option-text"
|
||||||
|
tooltip="Enable all card helpers (usually enabled via context menu entries).
Examples: False Covenant and Book of Living Myths">
|
||||||
|
<Cell class="option-text">
|
||||||
|
<Panel class="singleColumn-wrapper">
|
||||||
|
<Text class="option-header">Enable all card helpers</Text>
|
||||||
|
</Panel>
|
||||||
|
</Cell>
|
||||||
|
<Cell class="option-button">
|
||||||
|
<Button class="optionToggle"
|
||||||
|
id="enableCardHelpers"
|
||||||
|
onClick="onClick_toggleOption"/>
|
||||||
|
</Cell>
|
||||||
|
</Row>
|
||||||
|
|
||||||
<!-- Group: play area settings -->
|
<!-- Group: play area settings -->
|
||||||
<Row class="group-header">
|
<Row class="group-header">
|
||||||
<Cell class="group-header">
|
<Cell class="group-header">
|
||||||
@ -839,6 +854,21 @@
|
|||||||
</Cell>
|
</Cell>
|
||||||
</Row>
|
</Row>
|
||||||
|
|
||||||
|
<!-- Option: use class-specific texture -->
|
||||||
|
<Row class="option-text"
|
||||||
|
tooltip="Controls whether a class-specific playermat texture should be automatically loaded.">
|
||||||
|
<Cell class="option-text">
|
||||||
|
<Panel class="singleColumn-wrapper">
|
||||||
|
<Text class="option-header">Use class-specific texture</Text>
|
||||||
|
</Panel>
|
||||||
|
</Cell>
|
||||||
|
<Cell class="option-button">
|
||||||
|
<Button class="optionToggle"
|
||||||
|
id="useClassTexture"
|
||||||
|
onClick="onClick_toggleOption"/>
|
||||||
|
</Cell>
|
||||||
|
</Row>
|
||||||
|
|
||||||
<!-- Option: use clickable clue-counters -->
|
<!-- Option: use clickable clue-counters -->
|
||||||
<Row class="option-text"
|
<Row class="option-text"
|
||||||
tooltip="Instead of automatically counting clues in the respective area on your playermat,
this displays a clickable counter for clues.">
|
tooltip="Instead of automatically counting clues in the respective area on your playermat,
this displays a clickable counter for clues.">
|
||||||
|
288
unpacked.yaml
288
unpacked.yaml
@ -71,14 +71,14 @@ ComponentTags:
|
|||||||
normalized: investigator
|
normalized: investigator
|
||||||
- displayed: chaosBag
|
- displayed: chaosBag
|
||||||
normalized: chaosbag
|
normalized: chaosbag
|
||||||
- displayed: ActionToken
|
|
||||||
normalized: actiontoken
|
|
||||||
- displayed: LargeBox
|
- displayed: LargeBox
|
||||||
normalized: largebox
|
normalized: largebox
|
||||||
- displayed: CampaignBox
|
- displayed: CampaignBox
|
||||||
normalized: campaignbox
|
normalized: campaignbox
|
||||||
- displayed: CameraZoom_ignore
|
- displayed: CameraZoom_ignore
|
||||||
normalized: camerazoom_ignore
|
normalized: camerazoom_ignore
|
||||||
|
- displayed: UniversalToken
|
||||||
|
normalized: universaltoken
|
||||||
CustomUIAssets:
|
CustomUIAssets:
|
||||||
- Name: close
|
- Name: close
|
||||||
Type: 0
|
Type: 0
|
||||||
@ -98,10 +98,10 @@ CustomUIAssets:
|
|||||||
- Name: option-gear
|
- Name: option-gear
|
||||||
Type: 0
|
Type: 0
|
||||||
URL: http://cloud-3.steamusercontent.com/ugc/2026086584372569912/5CB461AEAE2E59D3064D90A776EB86C46081EC78/
|
URL: http://cloud-3.steamusercontent.com/ugc/2026086584372569912/5CB461AEAE2E59D3064D90A776EB86C46081EC78/
|
||||||
- Name: option-on
|
- Name: option_on
|
||||||
Type: 0
|
Type: 0
|
||||||
URL: http://cloud-3.steamusercontent.com/ugc/2462982115668997008/2178787B67B3C96F3419EDBAB8420E39893756BC/
|
URL: http://cloud-3.steamusercontent.com/ugc/2462982115668997008/2178787B67B3C96F3419EDBAB8420E39893756BC/
|
||||||
- Name: option-off
|
- Name: option_off
|
||||||
Type: 0
|
Type: 0
|
||||||
URL: http://cloud-3.steamusercontent.com/ugc/2462982115668996901/D6438ECBB11DECC6DB9987589FF526FBAD4D2368/
|
URL: http://cloud-3.steamusercontent.com/ugc/2462982115668996901/D6438ECBB11DECC6DB9987589FF526FBAD4D2368/
|
||||||
- Name: font_arkhamicons
|
- Name: font_arkhamicons
|
||||||
@ -122,12 +122,6 @@ CustomUIAssets:
|
|||||||
- Name: header_olive
|
- Name: header_olive
|
||||||
Type: 0
|
Type: 0
|
||||||
URL: http://cloud-3.steamusercontent.com/ugc/2280574378889753733/F67B7B37FF7AA253B6D697E577DF54A3E76030C2/
|
URL: http://cloud-3.steamusercontent.com/ugc/2280574378889753733/F67B7B37FF7AA253B6D697E577DF54A3E76030C2/
|
||||||
- Name: option_on
|
|
||||||
Type: 0
|
|
||||||
URL: http://cloud-3.steamusercontent.com/ugc/2024962321889555728/22ABD35CBB49A001F3A5318E4AFCFB22D24FEA39/
|
|
||||||
- Name: option_off
|
|
||||||
Type: 0
|
|
||||||
URL: http://cloud-3.steamusercontent.com/ugc/2024962321889555661/6643E5CC9160FF4624672C255D0DF7B313DA00A5/
|
|
||||||
- Name: SpeechBubble
|
- Name: SpeechBubble
|
||||||
Type: 0
|
Type: 0
|
||||||
URL: https://i.imgur.com/6MReiEO.png
|
URL: https://i.imgur.com/6MReiEO.png
|
||||||
@ -227,10 +221,13 @@ CustomUIAssets:
|
|||||||
- Name: token-auto-fail
|
- Name: token-auto-fail
|
||||||
Type: 0
|
Type: 0
|
||||||
URL: http://cloud-3.steamusercontent.com/ugc/2510267932886739653/CB7AA2D73777EF5938A6E6CD664B2ABA52B6E20A/
|
URL: http://cloud-3.steamusercontent.com/ugc/2510267932886739653/CB7AA2D73777EF5938A6E6CD664B2ABA52B6E20A/
|
||||||
|
- Name: token-eldersign
|
||||||
|
Type: 0
|
||||||
|
URL: http://cloud-3.steamusercontent.com/ugc/2540675016035917168/C0D6F531A85FD94C2F54825DFC50781B5B499A1D/
|
||||||
- Name: token-custom-token
|
- Name: token-custom-token
|
||||||
Type: 0
|
Type: 0
|
||||||
URL: http://cloud-3.steamusercontent.com/ugc/2380784374792650571/E4C2B2B69282A4EE15FE290FF6B08BEFC8FCA65C/
|
URL: http://cloud-3.steamusercontent.com/ugc/2380784374792650571/E4C2B2B69282A4EE15FE290FF6B08BEFC8FCA65C/
|
||||||
Date: Sun May 12 13:10:46 CEST 2024
|
Date: Mon Jul 8 20:19:48 CEST 2024
|
||||||
DecalPallet:
|
DecalPallet:
|
||||||
- ImageURL: http://cloud-3.steamusercontent.com/ugc/1474319121424323663/BC5570ECF747F1B30224461B576E8B0FE7FA5F33/
|
- ImageURL: http://cloud-3.steamusercontent.com/ugc/1474319121424323663/BC5570ECF747F1B30224461B576E8B0FE7FA5F33/
|
||||||
Name: Achivement Checkmark
|
Name: Achivement Checkmark
|
||||||
@ -239,7 +236,7 @@ DecalPallet:
|
|||||||
Name: Victory Display
|
Name: Victory Display
|
||||||
Size: 15
|
Size: 15
|
||||||
Decals: []
|
Decals: []
|
||||||
EpochTime: 1715512246
|
EpochTime: 1720462788
|
||||||
GameComplexity: ''
|
GameComplexity: ''
|
||||||
GameMode: Arkham Horror LCG - Super Complete Edition
|
GameMode: Arkham Horror LCG - Super Complete Edition
|
||||||
GameType: ''
|
GameType: ''
|
||||||
@ -290,7 +287,7 @@ Lighting:
|
|||||||
LutIndex: 0
|
LutIndex: 0
|
||||||
ReflectionIntensity: 1
|
ReflectionIntensity: 1
|
||||||
LuaScript: !include 'unpacked.ttslua'
|
LuaScript: !include 'unpacked.ttslua'
|
||||||
LuaScriptState: '{"acknowledgedUpgradeVersions":[],"chaosTokensGUID":[],"optionPanel":{"cardLanguage":"en","changePlayAreaImage":false,"playAreaConnectionColor":{"a":1,"b":0.4,"g":0.4,"r":0.4},"playAreaConnections":true,"playAreaSnapTags":true,"showAttachmentHelper":false,"showCleanUpHelper":false,"showCYOA":false,"showDisplacementTool":false,"showDrawButton":false,"showHandHelper":false,"showSearchAssistant":false,"showTitleSplash":true,"useClueClickers":false,"useResourceCounters":"disabled","useSnapTags":true}}'
|
LuaScriptState: '{"acknowledgedUpgradeVersions":[],"chaosTokensGUID":[],"optionPanel":{"cardLanguage":"en","changePlayAreaImage":false,"enableCardHelpers":true,"playAreaConnectionColor":{"a":1,"b":0.4,"g":0.4,"r":0.4},"playAreaConnections":true,"playAreaSnapTags":true,"showAttachmentHelper":false,"showCleanUpHelper":false,"showCYOA":false,"showDisplacementTool":false,"showDrawButton":false,"showHandHelper":false,"showSearchAssistant":false,"showTitleSplash":true,"useClassTexture":true,"useClueClickers":false,"useResourceCounters":"disabled","useSnapTags":true}}'
|
||||||
MusicPlayer:
|
MusicPlayer:
|
||||||
AudioLibrary:
|
AudioLibrary:
|
||||||
- Item1: http://cloud-3.steamusercontent.com/ugc/784110538847453001/4481D1CC5684FCF04AB143954DEFE09E94BF5CEB/
|
- Item1: http://cloud-3.steamusercontent.com/ugc/784110538847453001/4481D1CC5684FCF04AB143954DEFE09E94BF5CEB/
|
||||||
@ -348,11 +345,14 @@ MusicPlayer:
|
|||||||
Note: ''
|
Note: ''
|
||||||
ObjectStates:
|
ObjectStates:
|
||||||
- !include 'unpacked/go_game_piece_white GUID Reference Handler 123456.yaml'
|
- !include 'unpacked/go_game_piece_white GUID Reference Handler 123456.yaml'
|
||||||
|
- !include 'unpacked/go_game_piece_white Game Key Handler fce69c.yaml'
|
||||||
- !include 'unpacked/Checker_white Token Spawn Tracker e3ffc9.yaml'
|
- !include 'unpacked/Checker_white Token Spawn Tracker e3ffc9.yaml'
|
||||||
- !include 'unpacked/HandTrigger 5fe087.yaml'
|
- !include 'unpacked/HandTrigger 5fe087.yaml'
|
||||||
- !include 'unpacked/HandTrigger be2f17.yaml'
|
- !include 'unpacked/HandTrigger be2f17.yaml'
|
||||||
- !include 'unpacked/HandTrigger 0285cc.yaml'
|
- !include 'unpacked/HandTrigger 0285cc.yaml'
|
||||||
- !include 'unpacked/HandTrigger a70eee.yaml'
|
- !include 'unpacked/HandTrigger a70eee.yaml'
|
||||||
|
- !include 'unpacked/ScriptingTrigger a2f932.yaml'
|
||||||
|
- !include 'unpacked/FogOfWarTrigger 3aab97.yaml'
|
||||||
- !include 'unpacked/Custom_Assetbundle TableLegBottomRight afc863.yaml'
|
- !include 'unpacked/Custom_Assetbundle TableLegBottomRight afc863.yaml'
|
||||||
- !include 'unpacked/Custom_Assetbundle TableLegBottomLeft c8edca.yaml'
|
- !include 'unpacked/Custom_Assetbundle TableLegBottomLeft c8edca.yaml'
|
||||||
- !include 'unpacked/Custom_Assetbundle TableLegTopLeft 393bf7.yaml'
|
- !include 'unpacked/Custom_Assetbundle TableLegTopLeft 393bf7.yaml'
|
||||||
@ -408,7 +408,9 @@ ObjectStates:
|
|||||||
- !include 'unpacked/Custom_Model_Bag Trash 5f896a.yaml'
|
- !include 'unpacked/Custom_Model_Bag Trash 5f896a.yaml'
|
||||||
- !include 'unpacked/Custom_Model_Bag Trash 147e80.yaml'
|
- !include 'unpacked/Custom_Model_Bag Trash 147e80.yaml'
|
||||||
- !include 'unpacked/Custom_Model_Bag Trash f7b6c8.yaml'
|
- !include 'unpacked/Custom_Model_Bag Trash f7b6c8.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Patch Notes f47225.yaml'
|
||||||
- !include 'unpacked/Custom_PDF Rules Reference d99993.yaml'
|
- !include 'unpacked/Custom_PDF Rules Reference d99993.yaml'
|
||||||
|
- !include 'unpacked/Custom_PDF Latest FAQ faqfaq.yaml'
|
||||||
- !include 'unpacked/Custom_Model_Infinite_Bag Doom tokens 16724b.yaml'
|
- !include 'unpacked/Custom_Model_Infinite_Bag Doom tokens 16724b.yaml'
|
||||||
- !include 'unpacked/Custom_Model_Infinite_Bag Clue tokens fae2f6.yaml'
|
- !include 'unpacked/Custom_Model_Infinite_Bag Clue tokens fae2f6.yaml'
|
||||||
- !include 'unpacked/Custom_Model_Infinite_Bag Clue tokens 3b2550.yaml'
|
- !include 'unpacked/Custom_Model_Infinite_Bag Clue tokens 3b2550.yaml'
|
||||||
@ -422,8 +424,6 @@ ObjectStates:
|
|||||||
- !include 'unpacked/Custom_Model_Infinite_Bag Damage tokens 480bda.yaml'
|
- !include 'unpacked/Custom_Model_Infinite_Bag Damage tokens 480bda.yaml'
|
||||||
- !include 'unpacked/Custom_Model_Infinite_Bag Resource tokens 9fadf9.yaml'
|
- !include 'unpacked/Custom_Model_Infinite_Bag Resource tokens 9fadf9.yaml'
|
||||||
- !include 'unpacked/Custom_Model_Infinite_Bag Connection markers 170f10.yaml'
|
- !include 'unpacked/Custom_Model_Infinite_Bag Connection markers 170f10.yaml'
|
||||||
- !include 'unpacked/FogOfWarTrigger 3aab97.yaml'
|
|
||||||
- !include 'unpacked/Custom_Model_Bag Leaked Items 42cd6e.yaml'
|
|
||||||
- !include 'unpacked/Custom_Model_Bag Chaos Token Reserve 106418.yaml'
|
- !include 'unpacked/Custom_Model_Bag Chaos Token Reserve 106418.yaml'
|
||||||
- !include 'unpacked/Custom_Model Clue Counter 37be78.yaml'
|
- !include 'unpacked/Custom_Model Clue Counter 37be78.yaml'
|
||||||
- !include 'unpacked/Custom_Model Clue Counter 1769ed.yaml'
|
- !include 'unpacked/Custom_Model Clue Counter 1769ed.yaml'
|
||||||
@ -432,8 +432,7 @@ ObjectStates:
|
|||||||
- !include 'unpacked/Custom_Token Master Clue Counter 4a3aa4.yaml'
|
- !include 'unpacked/Custom_Token Master Clue Counter 4a3aa4.yaml'
|
||||||
- !include 'unpacked/Custom_Model_Bag Legacy Assets 7165a9.yaml'
|
- !include 'unpacked/Custom_Model_Bag Legacy Assets 7165a9.yaml'
|
||||||
- !include 'unpacked/Custom_Token Play Area 721ba2.yaml'
|
- !include 'unpacked/Custom_Token Play Area 721ba2.yaml'
|
||||||
- !include 'unpacked/Bag Additional Player Cards 2cba6b.yaml'
|
- !include 'unpacked/Custom_Model_Bag Additional Player Cards 2cba6b.yaml'
|
||||||
- !include 'unpacked/Custom_Assetbundle_Bag Barkham Horror 308439.yaml'
|
|
||||||
- !include 'unpacked/Custom_Token Chaos Bag Stat Tracker 766620.yaml'
|
- !include 'unpacked/Custom_Token Chaos Bag Stat Tracker 766620.yaml'
|
||||||
- !include 'unpacked/Checker_white Token Spawn Tool 36b4ee.yaml'
|
- !include 'unpacked/Checker_white Token Spawn Tool 36b4ee.yaml'
|
||||||
- !include 'unpacked/Custom_Model_Bag Standalone Scenarios 77a5f9.yaml'
|
- !include 'unpacked/Custom_Model_Bag Standalone Scenarios 77a5f9.yaml'
|
||||||
@ -454,8 +453,6 @@ ObjectStates:
|
|||||||
- !include 'unpacked/Custom_Model_Bag Chaos Bag fea079.yaml'
|
- !include 'unpacked/Custom_Model_Bag Chaos Bag fea079.yaml'
|
||||||
- !include 'unpacked/Custom_Tile Data Helper 708279.yaml'
|
- !include 'unpacked/Custom_Tile Data Helper 708279.yaml'
|
||||||
- !include 'unpacked/Custom_Token BlessCurse Manager 5933fb.yaml'
|
- !include 'unpacked/Custom_Token BlessCurse Manager 5933fb.yaml'
|
||||||
- !include 'unpacked/Notecard d8d357.yaml'
|
|
||||||
- !include 'unpacked/ScriptingTrigger a2f932.yaml'
|
|
||||||
- !include 'unpacked/Custom_Model Edge of the Earth 895eaa.yaml'
|
- !include 'unpacked/Custom_Model Edge of the Earth 895eaa.yaml'
|
||||||
- !include 'unpacked/Custom_Model The Dream-Eaters a16a1a.yaml'
|
- !include 'unpacked/Custom_Model The Dream-Eaters a16a1a.yaml'
|
||||||
- !include 'unpacked/Custom_Model The Feast of Hemlock Vale c740af.yaml'
|
- !include 'unpacked/Custom_Model The Feast of Hemlock Vale c740af.yaml'
|
||||||
@ -465,27 +462,11 @@ ObjectStates:
|
|||||||
- !include 'unpacked/Custom_Tile Playermat 2 Orange bd0ff4.yaml'
|
- !include 'unpacked/Custom_Tile Playermat 2 Orange bd0ff4.yaml'
|
||||||
- !include 'unpacked/Custom_Tile Playermat 3 Green 383d8b.yaml'
|
- !include 'unpacked/Custom_Tile Playermat 3 Green 383d8b.yaml'
|
||||||
- !include 'unpacked/Custom_Tile Playermat 4 Red 0840d5.yaml'
|
- !include 'unpacked/Custom_Tile Playermat 4 Red 0840d5.yaml'
|
||||||
- !include 'unpacked/Custom_Tile Neutral 2691e1.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 748245.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 271b17.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 5bafdf.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 012577.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 04765b.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral b71036.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 1cb302.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral bbc5d4.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 429bb3.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 183dbe.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral b80db6.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral af1927.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 0329cc.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 5bec40.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Neutral 5825ca.yaml'
|
|
||||||
- !include 'unpacked/Custom_Token Lead Investigator acaa93.yaml'
|
- !include 'unpacked/Custom_Token Lead Investigator acaa93.yaml'
|
||||||
- !include 'unpacked/Custom_Tile ArkhamDB Deck Importer a28140.yaml'
|
- !include 'unpacked/Custom_Tile ArkhamDB Deck Importer a28140.yaml'
|
||||||
- !include 'unpacked/Checker_white Configuration 03804b.yaml'
|
- !include 'unpacked/Checker_white Configuration 03804b.yaml'
|
||||||
- !include 'unpacked/Custom_Token Drawing Tool 280086.yaml'
|
- !include 'unpacked/Custom_Token Drawing Tool 280086.yaml'
|
||||||
- !include 'unpacked/Custom_Token Playmat Image Swapper b7b45b.yaml'
|
- !include 'unpacked/Custom_Token PlayArea Image Swapper b7b45b.yaml'
|
||||||
- !include 'unpacked/Bag All Player Cards 15bb07.yaml'
|
- !include 'unpacked/Bag All Player Cards 15bb07.yaml'
|
||||||
- !include 'unpacked/Custom_Token Investigator Skill Tracker af7ed7.yaml'
|
- !include 'unpacked/Custom_Token Investigator Skill Tracker af7ed7.yaml'
|
||||||
- !include 'unpacked/Custom_Token Investigator Skill Tracker e598c2.yaml'
|
- !include 'unpacked/Custom_Token Investigator Skill Tracker e598c2.yaml'
|
||||||
@ -511,7 +492,6 @@ ObjectStates:
|
|||||||
- !include 'unpacked/ScriptingTrigger TokenDiscardZone 457de5.yaml'
|
- !include 'unpacked/ScriptingTrigger TokenDiscardZone 457de5.yaml'
|
||||||
- !include 'unpacked/ScriptingTrigger TokenDiscardZone 457de6.yaml'
|
- !include 'unpacked/ScriptingTrigger TokenDiscardZone 457de6.yaml'
|
||||||
- !include 'unpacked/Custom_Tile Decoration - Map 6161b4.yaml'
|
- !include 'unpacked/Custom_Tile Decoration - Map 6161b4.yaml'
|
||||||
- !include 'unpacked/Custom_Model_Bag Rulebooks, Guides and Tablets fcfa7f.yaml'
|
|
||||||
- !include 'unpacked/BlockRectangle Table Divider 612072.yaml'
|
- !include 'unpacked/BlockRectangle Table Divider 612072.yaml'
|
||||||
- !include 'unpacked/BlockRectangle Table Divider 975c39.yaml'
|
- !include 'unpacked/BlockRectangle Table Divider 975c39.yaml'
|
||||||
- !include 'unpacked/BlockRectangle Table Divider 75937e.yaml'
|
- !include 'unpacked/BlockRectangle Table Divider 75937e.yaml'
|
||||||
@ -524,7 +504,6 @@ ObjectStates:
|
|||||||
- !include 'unpacked/Custom_Tile Fan-Made Expansion Overview de7cae.yaml'
|
- !include 'unpacked/Custom_Tile Fan-Made Expansion Overview de7cae.yaml'
|
||||||
- !include 'unpacked/Bag OptionPanel Source 830bd0.yaml'
|
- !include 'unpacked/Bag OptionPanel Source 830bd0.yaml'
|
||||||
- !include 'unpacked/Custom_Assetbundle SoundCube 3c988f.yaml'
|
- !include 'unpacked/Custom_Assetbundle SoundCube 3c988f.yaml'
|
||||||
- !include 'unpacked/go_game_piece_white Game Key Handler fce69c.yaml'
|
|
||||||
- !include 'unpacked/Custom_Tile Token Spawning Reference f8b3a7.yaml'
|
- !include 'unpacked/Custom_Tile Token Spawning Reference f8b3a7.yaml'
|
||||||
- !include 'unpacked/3DText d628cc.yaml'
|
- !include 'unpacked/3DText d628cc.yaml'
|
||||||
- !include 'unpacked/go_game_piece_black Navigation Overlay Handler 797ede.yaml'
|
- !include 'unpacked/go_game_piece_black Navigation Overlay Handler 797ede.yaml'
|
||||||
@ -532,7 +511,7 @@ ObjectStates:
|
|||||||
- !include 'unpacked/Custom_Token Token Arranger 022907.yaml'
|
- !include 'unpacked/Custom_Token Token Arranger 022907.yaml'
|
||||||
- !include 'unpacked/Custom_Tile Chaos Bag Manager 023240.yaml'
|
- !include 'unpacked/Custom_Tile Chaos Bag Manager 023240.yaml'
|
||||||
- !include 'unpacked/BlockRectangle Placeholder Box Dummy a93466.yaml'
|
- !include 'unpacked/BlockRectangle Placeholder Box Dummy a93466.yaml'
|
||||||
- !include 'unpacked/Custom_Model The Matter of Britain 194cc5.yaml'
|
- !include 'unpacked/Custom_Model Lovecrafter 3077 b08d20.yaml'
|
||||||
- !include 'unpacked/Custom_Tile Tokencache_+1 a15273.yaml'
|
- !include 'unpacked/Custom_Tile Tokencache_+1 a15273.yaml'
|
||||||
- !include 'unpacked/Custom_Tile Tokencache_0 0a8592.yaml'
|
- !include 'unpacked/Custom_Tile Tokencache_0 0a8592.yaml'
|
||||||
- !include 'unpacked/Custom_Tile Tokencache_-1 b644d2.yaml'
|
- !include 'unpacked/Custom_Tile Tokencache_-1 b644d2.yaml'
|
||||||
@ -553,7 +532,18 @@ ObjectStates:
|
|||||||
- !include 'unpacked/Custom_Tile Tokencache_Curse 16a9a7.yaml'
|
- !include 'unpacked/Custom_Tile Tokencache_Curse 16a9a7.yaml'
|
||||||
- !include 'unpacked/Custom_Tile Tokencache_Frost b2b7be.yaml'
|
- !include 'unpacked/Custom_Tile Tokencache_Frost b2b7be.yaml'
|
||||||
- !include 'unpacked/BlockSquare Physics Detector b300d8.yaml'
|
- !include 'unpacked/BlockSquare Physics Detector b300d8.yaml'
|
||||||
- !include 'unpacked/Notecard Arkham SCE 3.8.0 - 5122024 - Page 1 bd6b3e.yaml'
|
- !include 'unpacked/Custom_Tile Neutral 834ad5.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral a84ae4.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral 762df8.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral 589c7d.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral 642585.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral 6441b3.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral f2d25a.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral a5476b.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral 06ee01.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral 88d9ff.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral 42ec66.yaml'
|
||||||
|
- !include 'unpacked/Custom_Tile Neutral f94579.yaml'
|
||||||
PlayArea: 1
|
PlayArea: 1
|
||||||
PlayerCounts:
|
PlayerCounts:
|
||||||
- 0
|
- 0
|
||||||
@ -561,7 +551,7 @@ PlayerCounts:
|
|||||||
PlayingTime:
|
PlayingTime:
|
||||||
- 0
|
- 0
|
||||||
- 0
|
- 0
|
||||||
SaveName: Arkham SCE - 3.8.0
|
SaveName: Arkham SCE - 3.9.0
|
||||||
Sky: Sky_Museum
|
Sky: Sky_Museum
|
||||||
SkyURL: https://i.imgur.com/GkQqaOF.jpg
|
SkyURL: https://i.imgur.com/GkQqaOF.jpg
|
||||||
SnapPoints:
|
SnapPoints:
|
||||||
@ -749,182 +739,80 @@ SnapPoints:
|
|||||||
x: -26
|
x: -26
|
||||||
y: 1.48
|
y: 1.48
|
||||||
z: -87
|
z: -87
|
||||||
|
- Position:
|
||||||
|
x: 60
|
||||||
|
y: 1.48
|
||||||
|
z: 48
|
||||||
|
- Position:
|
||||||
|
x: -42
|
||||||
|
y: 1.48
|
||||||
|
z: 89
|
||||||
|
- Position:
|
||||||
|
x: -42
|
||||||
|
y: 1.48
|
||||||
|
z: 71
|
||||||
|
- Position:
|
||||||
|
x: -62
|
||||||
|
y: 1.48
|
||||||
|
z: 71
|
||||||
|
- Position:
|
||||||
|
x: -62
|
||||||
|
y: 1.48
|
||||||
|
z: 89
|
||||||
TabStates:
|
TabStates:
|
||||||
'10':
|
'1':
|
||||||
body: "Created by Whimsical\n\nAnything that passes over the remover that isn't
|
body: 'Welcome to Arkham Horror LCG - Super Complete Edition!
|
||||||
a card, deck or chaos token will be deleted.\r\nTo use the remover, right click
|
|
||||||
on it, choose the \"Enable\" option, and take your card with resources/horror/damage
|
|
||||||
and swipe it over the remover. You may wish to unlock and/or copy the remover
|
Make sure to take the tour that can be started with the token in the middle
|
||||||
to your play area first."
|
of the main playarea. Some basic notes:
|
||||||
|
|
||||||
|
|
||||||
|
DECKBUILDING
|
||||||
|
|
||||||
|
- All currently existing investigators and player cards are accessible via the
|
||||||
|
player card panel in the upper left corner of the table.
|
||||||
|
|
||||||
|
|
||||||
|
- On the leftside underneath the Investigators, you will find the ArkhamDB Deckimporter.
|
||||||
|
Insert your deck ID and it will build the deck automatically for you.
|
||||||
|
|
||||||
|
|
||||||
|
SCENARIOS & SETUP
|
||||||
|
|
||||||
|
- Arkham Horror LCG comes with a core campaign (Night of the Zealot) and several
|
||||||
|
expansions. Within each box you will find all the cards required for each scenario
|
||||||
|
setup, as well as a the official campaign guide PDF.
|
||||||
|
|
||||||
|
|
||||||
|
2. Each scenario is setup differently, and while some of the work has been prepared
|
||||||
|
beforehand (such as building encounter decks), you will have to refer to the
|
||||||
|
Campaign Guide for specific instructions on how to set up each scenario.
|
||||||
|
|
||||||
|
|
||||||
|
INVESTIGATOR PLAYMAT AND GAMEPLAY
|
||||||
|
|
||||||
|
- Playermats are scripted to automate most of the gameplay for you.'
|
||||||
color: Grey
|
color: Grey
|
||||||
id: 10
|
id: 1
|
||||||
title: Token Remover
|
title: Basic Intro
|
||||||
visibleColor:
|
visibleColor:
|
||||||
b: 0.5
|
b: 0.5
|
||||||
g: 0.5
|
g: 0.5
|
||||||
r: 0.5
|
r: 0.5
|
||||||
'11':
|
'2':
|
||||||
body: 'By Whimsical. Requires Numlock set to On.
|
|
||||||
|
|
||||||
Numpad 1: Cut top 3 cards of deck
|
|
||||||
|
|
||||||
Numpad 2: Cut top 6 cards of deck
|
|
||||||
|
|
||||||
Numpad 3: Cut top 9 cards of deck
|
|
||||||
|
|
||||||
Numpad 4: Spawn Damage
|
|
||||||
|
|
||||||
Numpad 5: Spawn Connection Marker
|
|
||||||
|
|
||||||
Numpad 6: Spawn Horror
|
|
||||||
|
|
||||||
Numpad 7: Spawn Doom
|
|
||||||
|
|
||||||
Numpad 8: Spawn Clue
|
|
||||||
|
|
||||||
Numpad 9: Spawn Resource
|
|
||||||
|
|
||||||
Numpad 0: Draw lines between selected objects. Hold to draw lines from mouseover
|
|
||||||
object to other selected objects.'
|
|
||||||
color: Grey
|
|
||||||
id: 11
|
|
||||||
title: Numpad Hotkeys
|
|
||||||
visibleColor:
|
|
||||||
b: 0.5
|
|
||||||
g: 0.5
|
|
||||||
r: 0.5
|
|
||||||
'7':
|
|
||||||
body: The server host can enable or disable cards in hands being hidden from other
|
body: The server host can enable or disable cards in hands being hidden from other
|
||||||
players by going to the menu at the top of the TTS screen, clicking options,
|
players by going to the menu at the top of the TTS screen, clicking options,
|
||||||
and choosing Hands. The "Disable" setting reveals all player hands to all players,
|
and choosing Hands. The "Disable" setting reveals all player hands to all players,
|
||||||
while the "Default" setting means that each player can only see the cards in
|
while the "Default" setting means that each player can only see the cards in
|
||||||
their own hand.
|
their own hand.
|
||||||
color: Grey
|
color: Grey
|
||||||
id: 7
|
id: 2
|
||||||
title: How to Hide Hands
|
title: How to Hide Hands
|
||||||
visibleColor:
|
visibleColor:
|
||||||
b: 0.5
|
b: 0.5
|
||||||
g: 0.5
|
g: 0.5
|
||||||
r: 0.5
|
r: 0.5
|
||||||
'8':
|
|
||||||
body: "Welcome to Arkham Horror LCG - Super Complete Edition!\r\n\r\nBelow you
|
|
||||||
will find all the features and instructions this mod is loaded with, that will
|
|
||||||
make your AH LCG experience easier.\r\n\r\nDECKBUILDING\r\n1. All current existing
|
|
||||||
investigators are on the right-hand side, and within each chest you will find
|
|
||||||
their investigator-specific assets and weaknesses. Also included is a basic
|
|
||||||
starter deck which only requires you to add a basic random weakness to get going.\r\n\r\n2.
|
|
||||||
On the left-hand side you will find both the weakness decks as well as lvl 0
|
|
||||||
cards sorted by class. To reveal the cards, click on each corresponding token
|
|
||||||
to deal the cards onto the table. Cards are sorted by order of Skill, event
|
|
||||||
and Asset cards top-down and increasing resource cost, left to right. \r\n\r\n3.
|
|
||||||
On the upper side you have the upgrade cards. Similarly, click each token to
|
|
||||||
deal the cards out onto the table. Cards are arranged both in increasing xp
|
|
||||||
cost and resource cost, left to right. Typically, these are the cards you will
|
|
||||||
be spending XP on between scenarios to purchase and improve your deck.\r\n4.
|
|
||||||
On the right-hand side underneath the Investigators, you will find the automated
|
|
||||||
ArkhamDB Deckbuilder (coded and maintained by Grabben). Click the load cards
|
|
||||||
button to activate the Deckbuilder, check ArkhamDB for your chosen deck\u2019s
|
|
||||||
URL and insert its number code following the instructions on the deckbuilder,
|
|
||||||
and it will build the deck automatically for you.\r\n\r\nSCENARIOS & SETUP\r\n1.
|
|
||||||
\tArkham Horror LCG comes with a core campaign (Night of the Zealot) and several
|
|
||||||
expansions (The Dunwich Legacy, The Path to Carcosa & The Forgotten Age). Within
|
|
||||||
each box you will find the volumes that contain all the cards required for each
|
|
||||||
scenario setup, as well as a tablet linking to the official campaign guide PDF.
|
|
||||||
Also included are chaos token cards and a Campaign Log.\r\n\r\n2. \tEach scenario
|
|
||||||
is setup differently, and while some of the work has been prepared beforehand
|
|
||||||
(such as building encounter decks), you will have to refer to the Campaign Guide
|
|
||||||
for specific instructions on how to set up each scenario.\r\n\r\n3. \tThe chaos
|
|
||||||
bag is always placed on the scenario setup mat in the upper right-hand corner
|
|
||||||
onto a snap point that tilts it at a 45-degree angle. Each scenario volume will
|
|
||||||
contain a difficulty card, where you will have the choice of four difficulties.
|
|
||||||
Press the button on the card according to the difficulty of your choosing and
|
|
||||||
the chaos bag will automatically be configured with the tokens specific to that
|
|
||||||
difficulty. In campaign play it is recommended to save your decks and chaos
|
|
||||||
bag at the end of your scenario to carry over onto the next, as often tokens
|
|
||||||
are added or removed from the chaos bag depending on actions or decisions made
|
|
||||||
during the game. These additional tokens can be drawn from the token reserve
|
|
||||||
book resting next to the newspaper in the middle of the main table \u2013 right
|
|
||||||
click it and search for the token you need.\n\r\n4. \tWhen placing location
|
|
||||||
cards, always place them face down on the main play area (the dark map of Arkham,
|
|
||||||
Massachusetts) with the number of clues per location unrevealed. The mod is
|
|
||||||
scripted so that when you flip said location cards (usually when entering the
|
|
||||||
location with an investigator), if it contains clues, the number of clues specific
|
|
||||||
to that location will automatically spawn. Note, that the mod only spawns tokens
|
|
||||||
in relation to the number of players currently set on the playmat player settings.
|
|
||||||
To set the number of players, left-click on the \"Investigators Playing\" number
|
|
||||||
to increase, or right-click to decrease.\r\n\n5. To make location mapping easier,
|
|
||||||
you can draw location connector tokens from the arrow-shaped container below
|
|
||||||
the main play area. Each token has three states (one way, two way and four way)
|
|
||||||
to use them accordingly to better visualize how your locations connect.\n\r\n6.
|
|
||||||
\tIf you require additional doom or clue tokens, these are located on the scenario
|
|
||||||
playmat in their corresponding containers. A handy Doom counter has been also
|
|
||||||
been added to track the doom on the agenda \u2013 left-click to add to add,
|
|
||||||
and right-click to deduct. Keep in mind that any doom spawned on enemies, locations
|
|
||||||
or assets needs to be mentally added to the doom in play on the agenda to account
|
|
||||||
for total doom.\r\n\r\nINVESTIGATOR PLAYMAT AND GAMEPLAY\r\n1. \tInvestigator
|
|
||||||
mats are scripted to automate most of the gameplay for you. wdw\n\r\n2. \tEach
|
|
||||||
mat has slots for inventory, where if you play an asset (for example you put
|
|
||||||
a gun that has 4 ammo into your right-hand slot), the mod will automatically
|
|
||||||
spawn the 4 resource tokens onto your equipped card.\n\r\n3.\tThe draw encounter
|
|
||||||
button on the left-hand side will draw the topmost card from the encounter deck
|
|
||||||
and put it in your threat area. Left-clicking will draw the card face-down,
|
|
||||||
and right-clicking will draw the card face-up. When you draw a weakness, or
|
|
||||||
engage an enemy, it is recommended you put it in your threat area, and once
|
|
||||||
you defeat the enemy or treachery, you can send it to the encounter discard
|
|
||||||
pile by clicking the discard button. If you defeat an enemy with a victory point,
|
|
||||||
make sure not to discard to the discard pile, but pick the card up and drop
|
|
||||||
it at the victory display.\n\r\n4. \tThe Click for Chaos button does just that,
|
|
||||||
draw a random chaos token from your chaos bag. Clicking a second time, sends
|
|
||||||
your chaos token back into the bag, which is then shuffled. If one player clicks
|
|
||||||
to draw a token and doesn\u2019t click a second time to send it back, the click
|
|
||||||
from another player on his personal mat will send the token back first, and
|
|
||||||
the next click will draw the token. Additionally, right-clicking the button
|
|
||||||
will continue drawing tokens and line them up next to each other, which is useful
|
|
||||||
for specific draw conditions the game may require from you. Left-clicking again
|
|
||||||
will send all drawn tokens back to the bag.\n\nADDITIONAL FEATURES:\n1. Over
|
|
||||||
20 Fan-made scenarios created by the thriving community of Arkham Horror LCG
|
|
||||||
have been included. Some of these are one-scenario missions, others are long
|
|
||||||
involved campaigns spanning multiple scenarios. These are all contained in \"The
|
|
||||||
Side Missions\". This boxset also includes the official FFG-created sidemissions
|
|
||||||
Curse of the Rougarou, Carnevale of Horrors, Labrynths of Lunacy and The Eternal
|
|
||||||
Slumber. Read the rulebook on including a side-mission into an ongoing campaign,
|
|
||||||
or play it as a one-off adventure! Setup instructions are included in each
|
|
||||||
volume.\n\n2. If you are not a fan of the dark themed Arkham map for the playmat,
|
|
||||||
you can change the image on it to any you like. At the top left hand side of
|
|
||||||
the playmat is an image icon, which when clicked will reveal a image swap panel.
|
|
||||||
Input the URL for the image you want to repalce the playmat with, and the panel
|
|
||||||
will apply the image for you. Keep in mind this will not change the existing
|
|
||||||
snap points on the current playmat.\n\r\nAs a final comment, please be sure
|
|
||||||
to let me know on the mod page in steam workshop if you find any bugs, issues
|
|
||||||
or have any suggestions for improvement!\r\n\r\n\r\n \r\n\r\n"
|
|
||||||
color: Grey
|
|
||||||
id: 8
|
|
||||||
title: Basic Intro
|
|
||||||
visibleColor:
|
|
||||||
b: 0.5
|
|
||||||
g: 0.5
|
|
||||||
r: 0.5
|
|
||||||
'9':
|
|
||||||
body: "Implemented by Tikatoy\nIdea conceived by Cadentia\n\nVersion 3.3\n\nTop
|
|
||||||
buttons manage bless tokens, bottom buttons manage curse tokens\nADD - creates
|
|
||||||
a new token and adds it to the chaos bag\nREMOVE - removes a token from the
|
|
||||||
chaos bag and destroys it\nTAKE - takes a token from the chaos bag and places
|
|
||||||
it below the manager (for sealing)\nRETURN - returns the last token taken from
|
|
||||||
the chaos bag to the chaos bag\n\nTo use Parallel Wendy, go to Options -> Game
|
|
||||||
Keys, then bind a key or mouse button to Wendy's Menu. Hover over any card (won't
|
|
||||||
work on decks) then press the bound key. Right-click seal/release options will
|
|
||||||
be added to the card.\n\n---Other Notes---\n\nOnly use ONE token manager at
|
|
||||||
a time\nTokens are limited to 10 of each type in play\nBless and curse tokens
|
|
||||||
should be in the chaos bag before trying to REMOVE or TAKE them\nEach action
|
|
||||||
logs a message which ends with (# in bag/# taken); hit enter to view log\n**WARNING**:
|
|
||||||
Tracking # of tokens in bag and in play will NOT persist between saves\n\r"
|
|
||||||
color: Grey
|
|
||||||
id: 9
|
|
||||||
title: Bless / Curse Manager
|
|
||||||
visibleColor:
|
|
||||||
b: 0.5
|
|
||||||
g: 0.5
|
|
||||||
r: 0.5
|
|
||||||
Table: Table_None
|
Table: Table_None
|
||||||
Tags: []
|
Tags: []
|
||||||
Turns:
|
Turns:
|
||||||
|
@ -1,55 +0,0 @@
|
|||||||
AltLookAngle:
|
|
||||||
x: 0
|
|
||||||
y: 0
|
|
||||||
z: 0
|
|
||||||
Autoraise: true
|
|
||||||
Bag:
|
|
||||||
Order: 0
|
|
||||||
ColorDiffuse:
|
|
||||||
b: 0
|
|
||||||
g: 0.36652
|
|
||||||
r: 0.70588
|
|
||||||
Description: 'Put any cards in here to add them to the indices for the player card
|
|
||||||
panel and deck importer.
|
|
||||||
|
|
||||||
|
|
||||||
Select the ''update index'' entry in the context menu of this bag once you''ve added
|
|
||||||
all cards.
|
|
||||||
|
|
||||||
|
|
||||||
This can be used for custom cards too.'
|
|
||||||
DragSelectable: true
|
|
||||||
GMNotes: ''
|
|
||||||
GUID: 2cba6b
|
|
||||||
Grid: true
|
|
||||||
GridProjection: false
|
|
||||||
Hands: false
|
|
||||||
HideWhenFaceDown: false
|
|
||||||
IgnoreFoW: false
|
|
||||||
LayoutGroupSortIndex: 0
|
|
||||||
Locked: true
|
|
||||||
LuaScript: !include 'Bag Additional Player Cards 2cba6b.ttslua'
|
|
||||||
LuaScriptState: ''
|
|
||||||
MaterialIndex: -1
|
|
||||||
MeasureMovement: false
|
|
||||||
MeshIndex: -1
|
|
||||||
Name: Bag
|
|
||||||
Nickname: Additional Player Cards
|
|
||||||
Number: 0
|
|
||||||
Snap: true
|
|
||||||
Sticky: true
|
|
||||||
Tags:
|
|
||||||
- AllCardsHotfix
|
|
||||||
Tooltip: true
|
|
||||||
Transform:
|
|
||||||
posX: 60
|
|
||||||
posY: 1.2
|
|
||||||
posZ: 48
|
|
||||||
rotX: 0
|
|
||||||
rotY: 0
|
|
||||||
rotZ: 0
|
|
||||||
scaleX: 1.5
|
|
||||||
scaleY: 1.5
|
|
||||||
scaleZ: 1.5
|
|
||||||
Value: 0
|
|
||||||
XmlUI: ''
|
|
@ -45,6 +45,8 @@ __bundle_register("__root", function(require, _LOADED, __bundle_register, __bund
|
|||||||
require("playercards/AllCardsBag")
|
require("playercards/AllCardsBag")
|
||||||
end)
|
end)
|
||||||
__bundle_register("playercards/AllCardsBag", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("playercards/AllCardsBag", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
local guidReferenceApi = require("core/GUIDReferenceApi")
|
||||||
|
|
||||||
local cardIdIndex = {}
|
local cardIdIndex = {}
|
||||||
local classAndLevelIndex = {}
|
local classAndLevelIndex = {}
|
||||||
local basicWeaknessList = {}
|
local basicWeaknessList = {}
|
||||||
@ -52,6 +54,7 @@ local uniqueWeaknessList = { }
|
|||||||
local cycleIndex = {}
|
local cycleIndex = {}
|
||||||
|
|
||||||
local indexingDone = false
|
local indexingDone = false
|
||||||
|
local otherCardsDetected = false
|
||||||
|
|
||||||
function onLoad()
|
function onLoad()
|
||||||
self.addContextMenuItem("Rebuild Index", startIndexBuild)
|
self.addContextMenuItem("Rebuild Index", startIndexBuild)
|
||||||
@ -65,7 +68,7 @@ end
|
|||||||
-- called once indexing is complete it means the hotfix bag has been added
|
-- called once indexing is complete it means the hotfix bag has been added
|
||||||
-- later, and we should rebuild the index to integrate the hotfix bag.
|
-- later, and we should rebuild the index to integrate the hotfix bag.
|
||||||
function rebuildIndexForHotfix()
|
function rebuildIndexForHotfix()
|
||||||
if (indexingDone) then
|
if indexingDone then
|
||||||
startIndexBuild()
|
startIndexBuild()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -110,6 +113,7 @@ end
|
|||||||
function buildIndex()
|
function buildIndex()
|
||||||
local cardCount = 0
|
local cardCount = 0
|
||||||
indexingDone = false
|
indexingDone = false
|
||||||
|
otherCardsDetected = false
|
||||||
|
|
||||||
-- process the allcardsbag itself
|
-- process the allcardsbag itself
|
||||||
for _, cardData in ipairs(self.getData().ContainedObjects) do
|
for _, cardData in ipairs(self.getData().ContainedObjects) do
|
||||||
@ -124,11 +128,15 @@ function buildIndex()
|
|||||||
-- process hotfix bags (and the additional playercards bag)
|
-- process hotfix bags (and the additional playercards bag)
|
||||||
for _, hotfixBag in ipairs(getObjectsWithTag("AllCardsHotfix")) do
|
for _, hotfixBag in ipairs(getObjectsWithTag("AllCardsHotfix")) do
|
||||||
local hotfixData = hotfixBag.getData()
|
local hotfixData = hotfixBag.getData()
|
||||||
if not hotfixData.ContainedObjects then break end
|
|
||||||
|
-- if the bag is empty, continue with the next bag
|
||||||
|
if not hotfixData.ContainedObjects then
|
||||||
|
goto nextBag
|
||||||
|
end
|
||||||
|
|
||||||
for _, cardData in ipairs(hotfixData.ContainedObjects) do
|
for _, cardData in ipairs(hotfixData.ContainedObjects) do
|
||||||
-- process containers
|
|
||||||
if cardData.ContainedObjects then
|
if cardData.ContainedObjects then
|
||||||
|
-- process containers
|
||||||
for _, deepCardData in ipairs(cardData.ContainedObjects) do
|
for _, deepCardData in ipairs(cardData.ContainedObjects) do
|
||||||
addCardToIndex(deepCardData)
|
addCardToIndex(deepCardData)
|
||||||
cardCount = cardCount + 1
|
cardCount = cardCount + 1
|
||||||
@ -137,8 +145,8 @@ function buildIndex()
|
|||||||
coroutine.yield(0)
|
coroutine.yield(0)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- process single cards
|
|
||||||
else
|
else
|
||||||
|
-- process single cards
|
||||||
addCardToIndex(cardData)
|
addCardToIndex(cardData)
|
||||||
cardCount = cardCount + 1
|
cardCount = cardCount + 1
|
||||||
if cardCount > 19 then
|
if cardCount > 19 then
|
||||||
@ -147,9 +155,11 @@ function buildIndex()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
::nextBag::
|
||||||
end
|
end
|
||||||
|
|
||||||
buildSupplementalIndexes()
|
buildSupplementalIndexes()
|
||||||
|
updatePlayerCardPanel()
|
||||||
indexingDone = true
|
indexingDone = true
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
@ -158,11 +168,23 @@ end
|
|||||||
---@param cardData table TTS object data for the card
|
---@param cardData table TTS object data for the card
|
||||||
function addCardToIndex(cardData)
|
function addCardToIndex(cardData)
|
||||||
-- using the more efficient 'json.parse()' to speed this process up
|
-- using the more efficient 'json.parse()' to speed this process up
|
||||||
local cardMetadata = json.parse(cardData.GMNotes)
|
local status, cardMetadata = pcall(function() return json.parse(cardData.GMNotes) end)
|
||||||
if not cardMetadata then return end
|
|
||||||
|
-- if an error happens, fallback to the regular parser
|
||||||
|
if status ~= true or cardMetadata == nil then
|
||||||
|
log("Fast parser failed for " .. cardData.Nickname .. ", using old parser instead.")
|
||||||
|
cardMetadata = JSON.decode(cardData.GMNotes)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- if metadata was not valid JSON or empty, don't add the card
|
||||||
|
if not cardMetadata == nil then
|
||||||
|
log("Error parsing " .. cardData.Nickname)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- use the ZoopGuid as fallback if no id present
|
-- use the ZoopGuid as fallback if no id present
|
||||||
cardIdIndex[cardMetadata.id or cardMetadata.TtsZoopGuid] = { data = cardData, metadata = cardMetadata }
|
cardMetadata.id = cardMetadata.id or cardMetadata.TtsZoopGuid
|
||||||
|
cardIdIndex[cardMetadata.id] = { data = cardData, metadata = cardMetadata }
|
||||||
|
|
||||||
-- also add data for alternate ids
|
-- also add data for alternate ids
|
||||||
if cardMetadata.alternate_ids ~= nil then
|
if cardMetadata.alternate_ids ~= nil then
|
||||||
@ -172,37 +194,35 @@ function addCardToIndex(cardData)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Creates the supplemental indexes for classes, weaknesses etc.
|
||||||
function buildSupplementalIndexes()
|
function buildSupplementalIndexes()
|
||||||
for cardId, card in pairs(cardIdIndex) do
|
for cardId, card in pairs(cardIdIndex) do
|
||||||
local cardMetadata = card.metadata
|
|
||||||
-- If the ID key and the metadata ID don't match this is a duplicate card created by an alternate_id, and we should skip it
|
-- If the ID key and the metadata ID don't match this is a duplicate card created by an alternate_id, and we should skip it
|
||||||
if cardId == cardMetadata.id then
|
if cardId == card.metadata.id then
|
||||||
-- Add card to the basic weakness list, if appropriate. Some weaknesses have multiple copies, and are added multiple times
|
-- Add card to the basic weakness list, if appropriate. Some weaknesses have multiple copies, and are added multiple times
|
||||||
if cardMetadata.weakness then
|
if card.metadata.weakness then
|
||||||
table.insert(uniqueWeaknessList, cardMetadata.id)
|
table.insert(uniqueWeaknessList, card.metadata.id)
|
||||||
if cardMetadata.basicWeaknessCount ~= nil then
|
if card.metadata.basicWeaknessCount ~= nil then
|
||||||
for i = 1, cardMetadata.basicWeaknessCount do
|
for i = 1, card.metadata.basicWeaknessCount do
|
||||||
table.insert(basicWeaknessList, cardMetadata.id)
|
table.insert(basicWeaknessList, card.metadata.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Excludes signature cards (which have no class or level)
|
-- Excludes signature cards (which have no class or level)
|
||||||
if cardMetadata.class ~= nil and cardMetadata.level ~= nil then
|
if card.metadata.class ~= nil and card.metadata.level ~= nil then
|
||||||
local upgradeKey
|
local upgradeKey = "-level0"
|
||||||
if cardMetadata.level > 0 then
|
if card.metadata.level > 0 then
|
||||||
upgradeKey = "-upgrade"
|
upgradeKey = "-upgrade"
|
||||||
else
|
|
||||||
upgradeKey = "-level0"
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- parse classes (separated by "|") and add the card to the appropriate class and level indices
|
-- parse classes (separated by "|") and add the card to the appropriate class and level indices
|
||||||
for str in cardMetadata.class:gmatch("([^|]+)") do
|
for str in card.metadata.class:gmatch("([^|]+)") do
|
||||||
table.insert(classAndLevelIndex[str .. upgradeKey], cardMetadata.id)
|
table.insert(classAndLevelIndex[str .. upgradeKey], card.metadata.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- add to cycle index
|
-- add to cycle index
|
||||||
local cycleName = cardMetadata.cycle
|
local cycleName = card.metadata.cycle
|
||||||
if cycleName ~= nil then
|
if cycleName ~= nil then
|
||||||
cycleName = string.lower(cycleName)
|
cycleName = string.lower(cycleName)
|
||||||
|
|
||||||
@ -211,12 +231,17 @@ function buildSupplementalIndexes()
|
|||||||
|
|
||||||
-- override cycle name for night of the zealot
|
-- override cycle name for night of the zealot
|
||||||
cycleName = cycleName:gsub("the night of the zealot", "core")
|
cycleName = cycleName:gsub("the night of the zealot", "core")
|
||||||
|
else
|
||||||
|
-- track cards without defined cycle (should only be fan-made cards)
|
||||||
|
cycleName = "other"
|
||||||
|
otherCardsDetected = true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- maybe initialize table
|
||||||
if cycleIndex[cycleName] == nil then
|
if cycleIndex[cycleName] == nil then
|
||||||
cycleIndex[cycleName] = {}
|
cycleIndex[cycleName] = {}
|
||||||
end
|
end
|
||||||
table.insert(cycleIndex[cycleName], cardMetadata.id)
|
table.insert(cycleIndex[cycleName], card.metadata.id)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -250,64 +275,131 @@ function cardComparator(id1, id2)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- inform the player card panel about the presence of other cards (no cycle -> fan-made)
|
||||||
|
function updatePlayerCardPanel()
|
||||||
|
local panel = guidReferenceApi.getObjectByOwnerAndType("Mythos", "PlayerCardPanel")
|
||||||
|
panel.call("createXML", otherCardsDetected)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return boolean: If true, the bag is currently not indexing and ready to be accessed
|
||||||
function isIndexReady()
|
function isIndexReady()
|
||||||
|
if not indexingDone then
|
||||||
|
broadcastToAll("Still loading player cards, please try again in a few seconds", { 0.9, 0.2, 0.2 })
|
||||||
|
end
|
||||||
return indexingDone
|
return indexingDone
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns a specific card from the bag, based on ArkhamDB ID
|
-- Returns a specific card from the bag, based on ArkhamDB ID
|
||||||
-- Params table:
|
---@param params table ID of the card to retrieve
|
||||||
-- id: String ID of the card to retrieve
|
---@return table: If the indexes are still being constructed, returns an empty table.
|
||||||
-- Return: If the indexes are still being constructed, an empty table is
|
-- Otherwise, a single table with the following fields
|
||||||
-- returned. Otherwise, a single table with the following fields
|
-- data: TTS object data, suitable for spawning the card
|
||||||
-- cardData: TTS object data, suitable for spawning the card
|
-- metadata: Table of parsed metadata
|
||||||
-- cardMetadata: Table of parsed metadata
|
|
||||||
function getCardById(params)
|
function getCardById(params)
|
||||||
if (not indexingDone) then
|
if not isIndexReady() then return {} end
|
||||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
|
||||||
return { }
|
|
||||||
end
|
|
||||||
return cardIdIndex[params.id]
|
return cardIdIndex[params.id]
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns a list of cards from the bag matching a class and level (0 or upgraded)
|
-- Returns a list of cards from the bag matching a class and level (0 or upgraded)
|
||||||
-- Params table:
|
---@param params table
|
||||||
-- class: String class to retrieve ("Guardian", "Seeker", etc)
|
-- class: String class to retrieve ("Guardian", "Seeker", etc)
|
||||||
-- isUpgraded: true for upgraded cards (Level 1-5), false for Level 0
|
-- isUpgraded: true for upgraded cards (Level 1-5), false for Level 0
|
||||||
-- Return: If the indexes are still being constructed, returns an empty table.
|
---@return table: If the indexes are still being constructed, returns an empty table.
|
||||||
-- Otherwise, a list of tables, each with the following fields
|
-- Otherwise, a list of tables, each with the following fields
|
||||||
-- cardData: TTS object data, suitable for spawning the card
|
-- data: TTS object data, suitable for spawning the card
|
||||||
-- cardMetadata: Table of parsed metadata
|
-- metadata: Table of parsed metadata
|
||||||
function getCardsByClassAndLevel(params)
|
function getCardsByClassAndLevel(params)
|
||||||
if (not indexingDone) then
|
if not isIndexReady() then return {} end
|
||||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
|
||||||
return { }
|
local upgradeKey = "-level0"
|
||||||
end
|
if params.upgraded then
|
||||||
local upgradeKey
|
|
||||||
if (params.upgraded) then
|
|
||||||
upgradeKey = "-upgrade"
|
upgradeKey = "-upgrade"
|
||||||
else
|
|
||||||
upgradeKey = "-level0"
|
|
||||||
end
|
end
|
||||||
return classAndLevelIndex[params.class..upgradeKey];
|
return classAndLevelIndex[params.class .. upgradeKey]
|
||||||
end
|
end
|
||||||
|
|
||||||
function getCardsByCycle(cycleName)
|
-- Returns a list of cards from the bag matching a cycle
|
||||||
if (not indexingDone) then
|
---@param params table
|
||||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
-- cycle: String cycle to retrieve ("The Scarlet Keys" etc.)
|
||||||
return { }
|
-- sortByMetadata: true to sort the table by metadata instead of ID
|
||||||
|
---@return table: If the indexes are still being constructed, returns an empty table.
|
||||||
|
-- Otherwise, a list of tables, each with the following fields
|
||||||
|
-- data: TTS object data, suitable for spawning the card
|
||||||
|
-- metadata: Table of parsed metadata
|
||||||
|
function getCardsByCycle(params)
|
||||||
|
if not isIndexReady() then return {} end
|
||||||
|
|
||||||
|
if not params.sortByMetadata then
|
||||||
|
return cycleIndex[string.lower(params.cycle)]
|
||||||
end
|
end
|
||||||
return cycleIndex[string.lower(cycleName)]
|
|
||||||
|
-- sort list by metadata (useful for custom cards without proper IDs)
|
||||||
|
local cardList = {}
|
||||||
|
for _, id in ipairs(cycleIndex[string.lower(params.cycle)]) do
|
||||||
|
table.insert(cardList, id)
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(cardList, metadataSortFunction)
|
||||||
|
return cardList
|
||||||
|
end
|
||||||
|
|
||||||
|
-- sorts cards by metadata: class, type, level, name and then description
|
||||||
|
function metadataSortFunction(id1, id2)
|
||||||
|
local card1 = cardIdIndex[id1]
|
||||||
|
local card2 = cardIdIndex[id2]
|
||||||
|
|
||||||
|
-- extract class per card
|
||||||
|
local classValue1 = getClassValueFromString(card1.metadata.class)
|
||||||
|
local classValue2 = getClassValueFromString(card2.metadata.class)
|
||||||
|
|
||||||
|
-- conversion tables to simplify type sorting
|
||||||
|
local typeConversion = {
|
||||||
|
Asset = 1,
|
||||||
|
Event = 2,
|
||||||
|
Skill = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
if classValue1 ~= classValue2 then
|
||||||
|
return classValue1 < classValue2
|
||||||
|
elseif typeConversion[card1.metadata.type] ~= typeConversion[card2.metadata.type] then
|
||||||
|
return typeConversion[card1.metadata.type] < typeConversion[card2.metadata.type]
|
||||||
|
elseif card1.metadata.level ~= card2.metadata.level then
|
||||||
|
return card1.metadata.level < card2.metadata.level
|
||||||
|
elseif card1.data.Nickname ~= card2.data.Nickname then
|
||||||
|
return card1.data.Nickname < card2.data.Nickname
|
||||||
|
else
|
||||||
|
return card1.data.Description < card2.data.Description
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- helper function to calculate the class value for sorting from the "|" separated string
|
||||||
|
function getClassValueFromString(s)
|
||||||
|
local classValueList = {
|
||||||
|
Guardian = 1,
|
||||||
|
Seeker = 2,
|
||||||
|
Rogue = 3,
|
||||||
|
Mystic = 4,
|
||||||
|
Survivor = 5,
|
||||||
|
Neutral = 6
|
||||||
|
}
|
||||||
|
local classValue = 0
|
||||||
|
for str in s:gmatch("([^|]+)") do
|
||||||
|
-- this sorts multiclass cards
|
||||||
|
classValue = classValue * 10 + classValueList[str]
|
||||||
|
end
|
||||||
|
return classValue
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Searches the bag for cards which match the given name and returns a list. Note that this is
|
-- Searches the bag for cards which match the given name and returns a list. Note that this is
|
||||||
-- an O(n) search without index support. It may be slow.
|
-- an O(n) search without index support. It may be slow.
|
||||||
-- Parameter array must contain these fields to define the search:
|
-- Parameter array must contain these fields to define the search:
|
||||||
-- name String or string fragment to search for names
|
-- name: String or string fragment to search for names
|
||||||
-- exact Whether the name match should be exact
|
-- exact: Whether the name match should be exact
|
||||||
function getCardsByName(params)
|
function getCardsByName(params)
|
||||||
local name = params.name
|
local name = params.name
|
||||||
local exact = params.exact
|
local exact = params.exact
|
||||||
local results = {}
|
local results = {}
|
||||||
|
|
||||||
-- Track cards (by ID) that we've added to avoid duplicates that may come from alternate IDs
|
-- Track cards (by ID) that we've added to avoid duplicates that may come from alternate IDs
|
||||||
local addedCards = {}
|
local addedCards = {}
|
||||||
for _, cardData in pairs(cardIdIndex) do
|
for _, cardData in pairs(cardIdIndex) do
|
||||||
@ -322,33 +414,31 @@ function getCardsByName(params)
|
|||||||
return results
|
return results
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Gets a random basic weakness from the bag. Once a given ID has been returned
|
-- Gets a random basic weakness from the bag. Once a given ID has been returned it will be
|
||||||
-- it will be removed from the list and cannot be selected again until a reload
|
-- removed from the list and cannot be selected again until a reload occurs or the indexes
|
||||||
-- occurs or the indexes are rebuilt, which will refresh the list to include all
|
-- are rebuilt, which will refresh the list to include all weaknesses.
|
||||||
-- weaknesses.
|
---@return string: ID of the selected weakness
|
||||||
-- Return: String ID of the selected weakness.
|
|
||||||
function getRandomWeaknessId()
|
function getRandomWeaknessId()
|
||||||
local availableWeaknesses = buildAvailableWeaknesses()
|
local availableWeaknesses = buildAvailableWeaknesses()
|
||||||
if (#availableWeaknesses > 0) then
|
if #availableWeaknesses > 0 then
|
||||||
return availableWeaknesses[math.random(#availableWeaknesses)]
|
return availableWeaknesses[math.random(#availableWeaknesses)]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Constructs a list of available basic weaknesses by starting with the full pool of basic
|
-- Constructs a list of available basic weaknesses by starting with the full pool of basic
|
||||||
-- weaknesses then removing any which are currently in the play or deck construction areas
|
-- weaknesses then removing any which are currently in the play or deck construction areas
|
||||||
-- Return: Table array of weakness IDs which are valid to choose from
|
---@param traits? string Trait(s) to use as filter
|
||||||
function buildAvailableWeaknesses()
|
---@return table: Array of weakness IDs which are valid to choose from
|
||||||
|
function buildAvailableWeaknesses(traits)
|
||||||
local weaknessesInPlay = {}
|
local weaknessesInPlay = {}
|
||||||
local allObjects = getAllObjects()
|
local allObjects = getAllObjects()
|
||||||
for _, object in ipairs(allObjects) do
|
for _, object in ipairs(allObjects) do
|
||||||
if (object.name == "Deck") then
|
if object.type == "Deck" then
|
||||||
for _, cardData in ipairs(object.getData().ContainedObjects) do
|
for _, cardData in ipairs(object.getData().ContainedObjects) do
|
||||||
local cardMetadata = JSON.decode(cardData.GMNotes)
|
incrementWeaknessCount(weaknessesInPlay, JSON.decode(cardData.GMNotes))
|
||||||
incrementWeaknessCount(weaknessesInPlay, cardMetadata)
|
|
||||||
end
|
end
|
||||||
elseif (object.name == "Card") then
|
elseif object.type == "Card" then
|
||||||
local cardMetadata = JSON.decode(object.getGMNotes())
|
incrementWeaknessCount(weaknessesInPlay, JSON.decode(object.getGMNotes()))
|
||||||
incrementWeaknessCount(weaknessesInPlay, cardMetadata)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -357,7 +447,32 @@ function buildAvailableWeaknesses()
|
|||||||
if (weaknessesInPlay[weaknessId] ~= nil and weaknessesInPlay[weaknessId] > 0) then
|
if (weaknessesInPlay[weaknessId] ~= nil and weaknessesInPlay[weaknessId] > 0) then
|
||||||
weaknessesInPlay[weaknessId] = weaknessesInPlay[weaknessId] - 1
|
weaknessesInPlay[weaknessId] = weaknessesInPlay[weaknessId] - 1
|
||||||
else
|
else
|
||||||
|
if traits then
|
||||||
|
-- split the string into separate traits (separated by "|")
|
||||||
|
local allowedTraits = {}
|
||||||
|
for str in traits:gmatch("([^|]+)") do
|
||||||
|
-- remove dots
|
||||||
|
str = str:gsub("[%.]", "")
|
||||||
|
|
||||||
|
-- remove leading and trailing whitespace
|
||||||
|
str = str:match("^%s*(.-)%s*$")
|
||||||
|
|
||||||
|
-- make sure string ends with a dot
|
||||||
|
str = string.lower(str .. ".")
|
||||||
|
table.insert(allowedTraits, str)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- make sure the trait is present on the weakness
|
||||||
|
local card = cardIdIndex[weaknessId]
|
||||||
|
for _, allowedTrait in ipairs(allowedTraits) do
|
||||||
|
if string.contains(string.lower(card.metadata.traits), allowedTrait) then
|
||||||
table.insert(availableWeaknesses, weaknessId)
|
table.insert(availableWeaknesses, weaknessId)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
table.insert(availableWeaknesses, weaknessId)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return availableWeaknesses
|
return availableWeaknesses
|
||||||
@ -373,8 +488,8 @@ end
|
|||||||
|
|
||||||
-- Helper function that adds one to the table entry for the number of weaknesses in play
|
-- Helper function that adds one to the table entry for the number of weaknesses in play
|
||||||
function incrementWeaknessCount(table, cardMetadata)
|
function incrementWeaknessCount(table, cardMetadata)
|
||||||
if (isBasicWeakness(cardMetadata)) then
|
if isBasicWeakness(cardMetadata) then
|
||||||
if (table[cardMetadata.id] == nil) then
|
if table[cardMetadata.id] == nil then
|
||||||
table[cardMetadata.id] = 1
|
table[cardMetadata.id] = 1
|
||||||
else
|
else
|
||||||
table[cardMetadata.id] = table[cardMetadata.id] + 1
|
table[cardMetadata.id] = table[cardMetadata.id] + 1
|
||||||
@ -389,4 +504,56 @@ function isBasicWeakness(cardMetadata)
|
|||||||
and cardMetadata.basicWeaknessCount > 0
|
and cardMetadata.basicWeaknessCount > 0
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
do
|
||||||
|
local GUIDReferenceApi = {}
|
||||||
|
|
||||||
|
local function getGuidHandler()
|
||||||
|
return getObjectFromGUID("123456")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns the matching object
|
||||||
|
---@param owner string Parent object for this search
|
||||||
|
---@param type string Type of object to search for
|
||||||
|
---@return any: Object reference to the matching object
|
||||||
|
GUIDReferenceApi.getObjectByOwnerAndType = function(owner, type)
|
||||||
|
return getGuidHandler().call("getObjectByOwnerAndType", { owner = owner, type = type })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns all matching objects as a table with references
|
||||||
|
---@param type string Type of object to search for
|
||||||
|
---@return table: List of object references to matching objects
|
||||||
|
GUIDReferenceApi.getObjectsByType = function(type)
|
||||||
|
return getGuidHandler().call("getObjectsByType", type)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns all matching objects as a table with references
|
||||||
|
---@param owner string Parent object for this search
|
||||||
|
---@return table: List of object references to matching objects
|
||||||
|
GUIDReferenceApi.getObjectsByOwner = function(owner)
|
||||||
|
return getGuidHandler().call("getObjectsByOwner", owner)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Sends new information to the reference handler to edit the main index
|
||||||
|
---@param owner string Parent of the object
|
||||||
|
---@param type string Type of the object
|
||||||
|
---@param guid string GUID of the object
|
||||||
|
GUIDReferenceApi.editIndex = function(owner, type, guid)
|
||||||
|
return getGuidHandler().call("editIndex", {
|
||||||
|
owner = owner,
|
||||||
|
type = type,
|
||||||
|
guid = guid
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Returns the owner of an object or the object it's located on
|
||||||
|
---@param object tts__GameObject Object for this search
|
||||||
|
---@return string: Parent of the object or object it's located on
|
||||||
|
GUIDReferenceApi.getOwnerOfObject = function(object)
|
||||||
|
return getGuidHandler().call("getOwnerOfObject", object)
|
||||||
|
end
|
||||||
|
|
||||||
|
return GUIDReferenceApi
|
||||||
|
end
|
||||||
|
end)
|
||||||
return __bundle_require("__root")
|
return __bundle_require("__root")
|
@ -20,7 +20,7 @@ CustomDeck:
|
|||||||
Description: Advanced
|
Description: Advanced
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90040\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"90040\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"traits\": \"Madness.\",\n \"weakness\": true,\n \"cycle\": \"Standalone\"\n}"
|
\ \"traits\": \"Madness.\",\n \"weakness\": true,\n \"cycle\": \"Red Tide Rising\"\n}"
|
||||||
GUID: 89fe92
|
GUID: 89fe92
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -20,8 +20,9 @@ CustomDeck:
|
|||||||
Description: ''
|
Description: ''
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"02266-t\",\n \"type\": \"Event\",\n \"class\": \"Rogue\",\n
|
GMNotes: "{\n \"id\": \"02266-t\",\n \"type\": \"Event\",\n \"class\": \"Rogue\",\n
|
||||||
\ \"cost\": 0,\n \"level\": 3,\n \"traits\": \"Trick.\",\n \"cycle\": \"The Dunwich
|
\ \"cost\": 0,\n \"level\": 3,\n \"traits\": \"Trick.\",\n \"uses\": [\n {\n
|
||||||
Legacy\"\n}"
|
\ \"count\": 3,\n \"type\": \"Universal\",\n \"token\": \"universalActionAbility\"\n
|
||||||
|
\ }\n ],\n \"cycle\": \"The Dunwich Legacy\"\n}"
|
||||||
GUID: e92f21
|
GUID: e92f21
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -20,8 +20,9 @@ CustomDeck:
|
|||||||
Description: ''
|
Description: ''
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"02266\",\n \"type\": \"Event\",\n \"class\": \"Rogue\",\n
|
GMNotes: "{\n \"id\": \"02266\",\n \"type\": \"Event\",\n \"class\": \"Rogue\",\n
|
||||||
\ \"cost\": 0,\n \"level\": 3,\n \"traits\": \"Trick.\",\n \"cycle\": \"The Dunwich
|
\ \"cost\": 0,\n \"level\": 3,\n \"traits\": \"Trick.\",\n \"uses\": [\n {\n
|
||||||
Legacy\"\n}"
|
\ \"count\": 3,\n \"type\": \"Universal\",\n \"token\": \"universalActionAbility\"\n
|
||||||
|
\ }\n ],\n \"cycle\": \"The Dunwich Legacy\"\n}"
|
||||||
GUID: 074858
|
GUID: 074858
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,14 +21,15 @@ Description: The Waitress
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"01004-pb\",\n \"type\": \"Investigator\",\n \"class\":
|
GMNotes: "{\n \"id\": \"01004-pb\",\n \"type\": \"Investigator\",\n \"class\":
|
||||||
\"Mystic\",\n \"traits\": \"Sorcerer.\",\n \"willpowerIcons\": 5,\n \"intellectIcons\":
|
\"Mystic\",\n \"traits\": \"Sorcerer.\",\n \"willpowerIcons\": 5,\n \"intellectIcons\":
|
||||||
2,\n \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"Core\",\n \"deck_requirements\":
|
2,\n \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"Bad Blood\",\n
|
||||||
{\n \"size\": 30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\":
|
\ \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
[\n {\n \"01012\": 1,\n \"90018\": 1\n },\n {\n \"01013\":
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"01012\":
|
||||||
1,\n \"90019\": 1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\":
|
1,\n \"90018\": 1\n },\n {\n \"01013\": 1,\n \"90019\":
|
||||||
[\n \"mystic\",\n \"neutral\"\n ],\n \"level\": {\n \"min\":
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
||||||
0,\n \"max\": 5\n }\n },\n {\n \"faction\": [\n \"spell\",\n
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ \"occult\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
5\n }\n },\n {\n \"faction\": [\n \"spell\",\n \"occult\"\n
|
||||||
3\n }\n }\n ]\n}"
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 3\n }\n
|
||||||
|
\ }\n ]\n}"
|
||||||
GUID: 909f30
|
GUID: 909f30
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,14 +21,14 @@ Description: The Waitress
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"01004-pf\",\n \"type\": \"Investigator\",\n \"class\":
|
GMNotes: "{\n \"id\": \"01004-pf\",\n \"type\": \"Investigator\",\n \"class\":
|
||||||
\"Mystic\",\n \"traits\": \"Sorcerer.\",\n \"willpowerIcons\": 5,\n \"intellectIcons\":
|
\"Mystic\",\n \"traits\": \"Sorcerer.\",\n \"willpowerIcons\": 5,\n \"intellectIcons\":
|
||||||
2,\n \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"Core\",\n \"deck_requirements\":
|
2,\n \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"Bad Blood\",\n
|
||||||
{\n \"size\": 30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\":
|
\ \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
[\n {\n \"01012\": 1,\n \"90018\": 1\n },\n {\n \"01013\":
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"01012\":
|
||||||
1,\n \"90019\": 1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\":
|
1,\n \"90018\": 1\n },\n {\n \"01013\": 1,\n \"90019\":
|
||||||
[\n \"mystic\",\n \"neutral\"\n ],\n \"level\": {\n \"min\":
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
||||||
0,\n \"max\": 5\n }\n },\n {\n \"faction\": [\n \"survivor\"\n
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 2\n }\n
|
5\n }\n },\n {\n \"faction\": [\n \"survivor\"\n ],\n
|
||||||
\ }\n ]\n}"
|
\ \"level\": {\n \"min\": 0,\n \"max\": 2\n }\n }\n ]\n}"
|
||||||
GUID: 02db0a
|
GUID: 02db0a
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,14 +21,15 @@ Description: The Waitress
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"01004-p\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
GMNotes: "{\n \"id\": \"01004-p\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
||||||
\ \"traits\": \"Sorcerer.\",\n \"willpowerIcons\": 5,\n \"intellectIcons\": 2,\n
|
\ \"traits\": \"Sorcerer.\",\n \"willpowerIcons\": 5,\n \"intellectIcons\": 2,\n
|
||||||
\ \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"Core\",\n \"deck_requirements\":
|
\ \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"Bad Blood\",\n \"extraToken\":
|
||||||
{\n \"size\": 30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\":
|
\"None\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
[\n {\n \"01012\": 1,\n \"90018\": 1\n },\n {\n \"01013\":
|
1,\n \"signatures\": [\n {\n \"01012\": 1,\n \"90018\": 1\n
|
||||||
1,\n \"90019\": 1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\":
|
\ },\n {\n \"01013\": 1,\n \"90019\": 1\n }\n ]\n
|
||||||
[\n \"mystic\",\n \"neutral\"\n ],\n \"level\": {\n \"min\":
|
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
||||||
0,\n \"max\": 5\n }\n },\n {\n \"faction\": [\n \"spell\",\n
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ \"occult\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
5\n }\n },\n {\n \"faction\": [\n \"spell\",\n \"occult\"\n
|
||||||
3\n }\n }\n ]\n}"
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 3\n }\n
|
||||||
|
\ }\n ]\n}"
|
||||||
GUID: 01b6ef
|
GUID: 01b6ef
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,10 +22,10 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"01004\",\n \"alternate_ids\": [\n \"01504\"\n ],\n \"type\":
|
GMNotes: "{\n \"id\": \"01004\",\n \"alternate_ids\": [\n \"01504\"\n ],\n \"type\":
|
||||||
\"Investigator\",\n \"class\": \"Mystic\",\n \"traits\": \"Sorcerer.\",\n \"willpowerIcons\":
|
\"Investigator\",\n \"class\": \"Mystic\",\n \"traits\": \"Sorcerer.\",\n \"willpowerIcons\":
|
||||||
5,\n \"intellectIcons\": 2,\n \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\":
|
5,\n \"intellectIcons\": 2,\n \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\":
|
||||||
\"Core\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\"Core\",\n \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\":
|
||||||
1,\n \"signatures\": [\n {\n \"01012\": 1,\n \"90018\": 1\n
|
30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"01012\":
|
||||||
\ },\n {\n \"01013\": 1,\n \"90019\": 1\n }\n ]\n
|
1,\n \"90018\": 1\n },\n {\n \"01013\": 1,\n \"90019\":
|
||||||
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
5\n }\n },\n {\n \"faction\": [\n \"survivor\"\n ],\n
|
5\n }\n },\n {\n \"faction\": [\n \"survivor\"\n ],\n
|
||||||
\ \"level\": {\n \"min\": 0,\n \"max\": 2\n }\n }\n ]\n}"
|
\ \"level\": {\n \"min\": 0,\n \"max\": 2\n }\n }\n ]\n}"
|
||||||
@ -70,15 +70,15 @@ States:
|
|||||||
GMNotes: "{\r\n \"id\": \"01004\",\r\n \"alternate_ids\": [\r\n \"01504\"\r\n
|
GMNotes: "{\r\n \"id\": \"01004\",\r\n \"alternate_ids\": [\r\n \"01504\"\r\n
|
||||||
\ ],\r\n \"type\": \"Investigator\",\r\n \"class\": \"Mystic\",\r\n \"traits\":
|
\ ],\r\n \"type\": \"Investigator\",\r\n \"class\": \"Mystic\",\r\n \"traits\":
|
||||||
\"Sorcerer.\",\r\n \"willpowerIcons\": 5,\r\n \"intellectIcons\": 2,\r\n \"combatIcons\":
|
\"Sorcerer.\",\r\n \"willpowerIcons\": 5,\r\n \"intellectIcons\": 2,\r\n \"combatIcons\":
|
||||||
2,\r\n \"agilityIcons\": 3,\r\n \"cycle\": \"Core\",\r\n \"deck_requirements\":
|
2,\r\n \"agilityIcons\": 3,\r\n \"cycle\": \"Core\",\r\n \"extraToken\":
|
||||||
{\r\n \"size\": 30,\r\n \"randomBasicWeaknessCount\": 1,\r\n \"signatures\":
|
\"Reaction\", \r\n \"deck_requirements\": {\r\n \"size\": 30,\r\n \"randomBasicWeaknessCount\":
|
||||||
[\r\n {\r\n \"01012\": 1,\r\n \"90018\": 1\r\n },\r\n
|
1,\r\n \"signatures\": [\r\n {\r\n \"01012\": 1,\r\n \"90018\":
|
||||||
\ {\r\n \"01013\": 1,\r\n \"90019\": 1\r\n }\r\n ]\r\n
|
1\r\n },\r\n {\r\n \"01013\": 1,\r\n \"90019\": 1\r\n
|
||||||
\ },\r\n \"deck_options\": [\r\n {\r\n \"faction\": [\r\n \"mystic\",\r\n
|
\ }\r\n ]\r\n },\r\n \"deck_options\": [\r\n {\r\n \"faction\":
|
||||||
\ \"neutral\"\r\n ],\r\n \"level\": {\r\n \"min\": 0,\r\n
|
[\r\n \"mystic\",\r\n \"neutral\"\r\n ],\r\n \"level\":
|
||||||
\ \"max\": 5\r\n }\r\n },\r\n {\r\n \"faction\": [\r\n
|
{\r\n \"min\": 0,\r\n \"max\": 5\r\n }\r\n },\r\n {\r\n
|
||||||
\ \"survivor\"\r\n ],\r\n \"level\": {\r\n \"min\": 0,\r\n
|
\ \"faction\": [\r\n \"survivor\"\r\n ],\r\n \"level\":
|
||||||
\ \"max\": 2\r\n }\r\n }\r\n ]\r\n}\r\n"
|
{\r\n \"min\": 0,\r\n \"max\": 2\r\n }\r\n }\r\n ]\r\n}\r\n"
|
||||||
GUID: 6797bb
|
GUID: 6797bb
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -81,12 +81,12 @@ States:
|
|||||||
- Minicard
|
- Minicard
|
||||||
Tooltip: true
|
Tooltip: true
|
||||||
Transform:
|
Transform:
|
||||||
posX: 40.7253036
|
posX: 40
|
||||||
posY: 1.29860592
|
posY: 1.3
|
||||||
posZ: 66.7765656
|
posZ: 66
|
||||||
rotX: 1.697304e-07
|
rotX: 0
|
||||||
rotY: 270.0102
|
rotY: 270
|
||||||
rotZ: 2.00479718e-07
|
rotZ: 0
|
||||||
scaleX: 0.6
|
scaleX: 0.6
|
||||||
scaleY: 1
|
scaleY: 1
|
||||||
scaleZ: 0.6
|
scaleZ: 0.6
|
||||||
|
@ -22,7 +22,7 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"03004\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
GMNotes: "{\n \"id\": \"03004\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
||||||
\ \"traits\": \"Sorcerer.\",\n \"willpowerIcons\": 5,\n \"intellectIcons\": 2,\n
|
\ \"traits\": \"Sorcerer.\",\n \"willpowerIcons\": 5,\n \"intellectIcons\": 2,\n
|
||||||
\ \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"The Path to Carcosa\",\n
|
\ \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"The Path to Carcosa\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
1,\n \"signatures\": [\n {\n \"03014\": 1\n },\n {\n \"03015\":
|
1,\n \"signatures\": [\n {\n \"03014\": 1\n },\n {\n \"03015\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
|
@ -22,12 +22,13 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"10009\",\n \"type\": \"Investigator\",\n \"class\": \"Rogue\",\n
|
GMNotes: "{\n \"id\": \"10009\",\n \"type\": \"Investigator\",\n \"class\": \"Rogue\",\n
|
||||||
\ \"traits\": \"Drifter. Socialite.\",\n \"willpowerIcons\": 3,\n \"intellectIcons\":
|
\ \"traits\": \"Drifter. Socialite.\",\n \"willpowerIcons\": 3,\n \"intellectIcons\":
|
||||||
4,\n \"combatIcons\": 2,\n \"agilityIcons\": 4,\n \"cycle\": \"The Feast of Hemlock
|
4,\n \"combatIcons\": 2,\n \"agilityIcons\": 4,\n \"cycle\": \"The Feast of Hemlock
|
||||||
Vale\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
Vale\",\n \"extraToken\": \"Parley\",\n \"deck_requirements\": {\n \"size\":
|
||||||
1,\n \"signatures\": [\n {\n \"10010\": 3\n },\n {\n \"10011\":
|
30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"10010\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"rogue\",\n
|
3\n },\n {\n \"10011\": 1\n }\n ]\n },\n \"deck_options\":
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
[\n {\n \"faction\": [\n \"rogue\",\n \"neutral\"\n ],\n
|
||||||
5\n }\n },\n {\n \"special\": [\n \"parley\"\n ],\n
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
||||||
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n }\n ]\n}"
|
\ \"special\": [\n \"parley\"\n ],\n \"level\": {\n \"min\":
|
||||||
|
0,\n \"max\": 5\n }\n }\n ]\n}"
|
||||||
GUID: 54eaa5
|
GUID: 54eaa5
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,13 +22,14 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"07002\",\n \"type\": \"Investigator\",\n \"class\": \"Seeker\",\n
|
GMNotes: "{\n \"id\": \"07002\",\n \"type\": \"Investigator\",\n \"class\": \"Seeker\",\n
|
||||||
\ \"traits\": \"Miskatonic. Scholar.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\":
|
\ \"traits\": \"Miskatonic. Scholar.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\":
|
||||||
2,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"The Innsmouth
|
2,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"The Innsmouth
|
||||||
Conspiracy\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
Conspiracy\",\n \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\":
|
||||||
1,\n \"signatures\": [\n {\n \"07008\": 1\n },\n {\n \"07009\":
|
30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"07008\":
|
||||||
1\n }\n ]\n \n },\n \"deck_options\": [\n {\n \"faction\":
|
1\n },\n {\n \"07009\": 1\n }\n ]\n \n },\n \"deck_options\":
|
||||||
[\n \"seeker\",\n \"neutral\"\n ],\n \"level\": {\n \"min\":
|
[\n {\n \"faction\": [\n \"seeker\",\n \"neutral\"\n ],\n
|
||||||
0,\n \"max\": 5\n }\n },\n {\n \"trait\": [\n \"practiced\"\n
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
||||||
\ ],\n \"type\": [\n \"skill\"\n ],\n \"level\": {\n \"min\":
|
\ \"trait\": [\n \"practiced\"\n ],\n \"type\": [\n \"skill\"\n
|
||||||
0,\n \"max\": 3\n }\n }\n ]\n}"
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 3\n }\n
|
||||||
|
\ }\n ]\n}"
|
||||||
GUID: 05b950
|
GUID: 05b950
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,13 +22,13 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"09011\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
GMNotes: "{\n \"id\": \"09011\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
||||||
\ \"traits\": \"Chosen. Cursed.\",\n \"willpowerIcons\": 3,\n \"intellectIcons\":
|
\ \"traits\": \"Chosen. Cursed.\",\n \"willpowerIcons\": 3,\n \"intellectIcons\":
|
||||||
3,\n \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"The Scarlet Keys\",\n
|
3,\n \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"The Scarlet Keys\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"09012\": 1,\n \"09013\": 1\n
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"09012\":
|
||||||
\ },\n {\n \"09014\": 1\n }\n ]\n },\n \"deck_options\":
|
1,\n \"09013\": 1\n },\n {\n \"09014\": 1\n }\n ]\n
|
||||||
[\n {\n \"faction\": [\n \"mystic\",\n \"neutral\"\n ],\n
|
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
||||||
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ \"trait\": [\n \"charm\"\n ],\n \"level\": {\n \"min\":
|
5\n }\n },\n {\n \"trait\": [\n \"charm\"\n ],\n \"level\":
|
||||||
0,\n \"max\": 4\n }\n }\n ]\n}"
|
{\n \"min\": 0,\n \"max\": 4\n }\n }\n ]\n}"
|
||||||
GUID: 4c2a3d
|
GUID: 4c2a3d
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
238
unpacked/Bag All Player Cards 15bb07/Card Analysis 80285f.ttslua
Normal file
238
unpacked/Bag All Player Cards 15bb07/Card Analysis 80285f.ttslua
Normal file
@ -0,0 +1,238 @@
|
|||||||
|
-- Bundled by luabundle {"version":"1.6.0"}
|
||||||
|
local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)
|
||||||
|
local loadingPlaceholder = {[{}] = true}
|
||||||
|
|
||||||
|
local register
|
||||||
|
local modules = {}
|
||||||
|
|
||||||
|
local require
|
||||||
|
local loaded = {}
|
||||||
|
|
||||||
|
register = function(name, body)
|
||||||
|
if not modules[name] then
|
||||||
|
modules[name] = body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require = function(name)
|
||||||
|
local loadedModule = loaded[name]
|
||||||
|
|
||||||
|
if loadedModule then
|
||||||
|
if loadedModule == loadingPlaceholder then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not modules[name] then
|
||||||
|
if not superRequire then
|
||||||
|
local identifier = type(name) == 'string' and '\"' .. name .. '\"' or tostring(name)
|
||||||
|
error('Tried to require ' .. identifier .. ', but no such module has been registered')
|
||||||
|
else
|
||||||
|
return superRequire(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
loaded[name] = loadingPlaceholder
|
||||||
|
loadedModule = modules[name](require, loaded, register, modules)
|
||||||
|
loaded[name] = loadedModule
|
||||||
|
end
|
||||||
|
|
||||||
|
return loadedModule
|
||||||
|
end
|
||||||
|
|
||||||
|
return require, loaded, register, modules
|
||||||
|
end)(nil)
|
||||||
|
__bundle_register("playercards/CardsWithHelper", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
--[[ Library for cards that have helpers
|
||||||
|
This file is used to share code between cards with helpers.
|
||||||
|
It syncs the visibility of the helper with the option panel and
|
||||||
|
makes sure the card has the respective tag.
|
||||||
|
Additionally, it will call 'initiliaze()' and 'shutOff()'
|
||||||
|
in the parent file if they are present.
|
||||||
|
|
||||||
|
Instructions:
|
||||||
|
1) Define the global variables before requiring this file:
|
||||||
|
hasXML = true (whether the card has an XML display)
|
||||||
|
isHelperEnabled = false (default state of the helper, should be 'false')
|
||||||
|
|
||||||
|
2) In 'onLoad()'', call 'syncDisplayWithOptionPanel()'
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
local optionPanelApi = require("core/OptionPanelApi")
|
||||||
|
|
||||||
|
-- if the respective option is enabled in onLoad(), enable the helper
|
||||||
|
function syncDisplayWithOptionPanel()
|
||||||
|
self.addTag("CardWithHelper")
|
||||||
|
local options = optionPanelApi.getOptions()
|
||||||
|
if options.enableCardHelpers then
|
||||||
|
setHelperState(true)
|
||||||
|
else
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- forces a new state
|
||||||
|
function setHelperState(newState)
|
||||||
|
isHelperEnabled = newState
|
||||||
|
updateSave()
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- toggles the current state
|
||||||
|
function toggleHelper()
|
||||||
|
isHelperEnabled = not isHelperEnabled
|
||||||
|
updateSave()
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- updates the visibility and calls events (after a small delay to allow XML being set)
|
||||||
|
function updateDisplay()
|
||||||
|
Wait.frames(actualDisplayUpdate, 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
function actualDisplayUpdate()
|
||||||
|
if isHelperEnabled then
|
||||||
|
self.clearContextMenu()
|
||||||
|
self.addContextMenuItem("Disable Helper", toggleHelper)
|
||||||
|
if hasXML then self.UI.show("Helper") end
|
||||||
|
if initialize then initialize() end
|
||||||
|
else
|
||||||
|
self.clearContextMenu()
|
||||||
|
self.addContextMenuItem("Enable Helper", toggleHelper)
|
||||||
|
if hasXML then self.UI.hide("Helper") end
|
||||||
|
if shutOff then shutOff() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
do
|
||||||
|
local OptionPanelApi = {}
|
||||||
|
|
||||||
|
-- loads saved options
|
||||||
|
---@param options table Set a new state for the option table
|
||||||
|
OptionPanelApi.loadSettings = function(options)
|
||||||
|
return Global.call("loadSettings", options)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return any: Table of option panel state
|
||||||
|
OptionPanelApi.getOptions = function()
|
||||||
|
return Global.getTable("optionPanel")
|
||||||
|
end
|
||||||
|
|
||||||
|
return OptionPanelApi
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
require("playercards/cards/Analysis")
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/cards/Analysis", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
require("playercards/CardsWithHelper")
|
||||||
|
require("playercards/CardsThatRedrawTokens")
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/CardsThatRedrawTokens", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
--[[ Library for cards that return and redraw tokens
|
||||||
|
This file is used to add an XML button to a card, turned on via context menu.
|
||||||
|
Valid options modify the appearance of the XML button, as well as the
|
||||||
|
behavior of the return and redraw function. Set options before requiring this file.
|
||||||
|
|
||||||
|
Parameters for the return and redraw functions. Typically set VALID_TOKENS or INVALID_TOKENS, not both.
|
||||||
|
If there are no restrictions on which tokens can be redrawn (e.g. Wendy Adams), keep both empty.
|
||||||
|
* VALID_TOKENS --@type table
|
||||||
|
- keyed table which lists all tokens that can be redrawn by the card
|
||||||
|
- example usage: "False Covenant"
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Curse"] = true
|
||||||
|
> }
|
||||||
|
|
||||||
|
* INVALID_TOKENS --@type table
|
||||||
|
- keyed table which lists all tokens that cannot be redrawn by the card
|
||||||
|
- example usage: "Custom Ammunition"
|
||||||
|
> INVALID_TOKENS = {
|
||||||
|
> ["Auto-fail"] = true
|
||||||
|
> }
|
||||||
|
|
||||||
|
* DRAW_SPECIFIC_TOKEN --@type string (name of token or nil)
|
||||||
|
- if set, will attempt to draw that specific token
|
||||||
|
|
||||||
|
* RETURN_TO_POOL --@type string
|
||||||
|
- allows for the name of the card to be passed onto Global for any special handling
|
||||||
|
|
||||||
|
The following parameters modify the appearence of the XML button and are not listed as part of a table.
|
||||||
|
- buttonHeight (default is 450)
|
||||||
|
- buttonWidth (default is 1400)
|
||||||
|
- buttonPosition (default is "0 -55 -22")
|
||||||
|
- buttonFontSize (default is 250)
|
||||||
|
- buttonRotation (change if button is placed on an investigator cards)
|
||||||
|
- buttonLabel (default is "Redraw Token")
|
||||||
|
- buttonIcon (to add an icon to the right)
|
||||||
|
- buttonColor (default is "#77674DE6")
|
||||||
|
|
||||||
|
----------------------------------------------------------
|
||||||
|
EXAMPLE: Claypool's Furs
|
||||||
|
This card can only redraw the Frost token, and is replaced with a random token from the bag.
|
||||||
|
As a nice reminder the XML button takes on the Frost color and icon with the text "Cancel".
|
||||||
|
> buttonValue = "Cancel"
|
||||||
|
> buttonIcon = "token-frost"
|
||||||
|
> buttonColor = "#404450E6"
|
||||||
|
> buttonFontSize = 300
|
||||||
|
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Frost"] = true
|
||||||
|
> }
|
||||||
|
>
|
||||||
|
> require...
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
-- intentionally global
|
||||||
|
hasXML = true
|
||||||
|
isHelperEnabled = false
|
||||||
|
|
||||||
|
function updateSave()
|
||||||
|
self.script_state = JSON.encode({ isHelperEnabled = isHelperEnabled })
|
||||||
|
end
|
||||||
|
|
||||||
|
function onLoad(savedData)
|
||||||
|
if savedData and savedData ~= "" then
|
||||||
|
local loadedData = JSON.decode(savedData)
|
||||||
|
isHelperEnabled = loadedData.isHelperEnabled
|
||||||
|
end
|
||||||
|
createHelperXML()
|
||||||
|
syncDisplayWithOptionPanel()
|
||||||
|
end
|
||||||
|
|
||||||
|
function createHelperXML()
|
||||||
|
local xmlTable = { {
|
||||||
|
tag = "Button",
|
||||||
|
attributes = {
|
||||||
|
active = "false",
|
||||||
|
id = "Helper",
|
||||||
|
height = buttonHeight or 450,
|
||||||
|
width = buttonWidth or 1400,
|
||||||
|
rotation = buttonRotation or "0 0 180",
|
||||||
|
scale = "0.1 0.1 1",
|
||||||
|
position = buttonPosition or "0 -55 -22",
|
||||||
|
padding = "50 50 50 50",
|
||||||
|
font = "font_teutonic-arkham",
|
||||||
|
fontSize = buttonFontSize or 250,
|
||||||
|
onClick = "triggerXMLTokenLabelCreation",
|
||||||
|
color = buttonColor or "#77674DE6",
|
||||||
|
textColor = "White"
|
||||||
|
},
|
||||||
|
value = buttonLabel or "Redraw Token"
|
||||||
|
} }
|
||||||
|
if buttonIcon then
|
||||||
|
xmlTable[1].attributes.iconWidth = "400"
|
||||||
|
xmlTable[1].attributes.iconAlignment = "Right"
|
||||||
|
xmlTable[1].attributes.icon = buttonIcon
|
||||||
|
end
|
||||||
|
self.UI.setXmlTable(xmlTable)
|
||||||
|
end
|
||||||
|
|
||||||
|
function triggerXMLTokenLabelCreation()
|
||||||
|
Global.call("activeRedrawEffect", {
|
||||||
|
VALID_TOKENS = VALID_TOKENS,
|
||||||
|
INVALID_TOKENS = INVALID_TOKENS,
|
||||||
|
RETURN_TO_POOL = RETURN_TO_POOL
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
return __bundle_require("__root")
|
@ -30,7 +30,7 @@ HideWhenFaceDown: true
|
|||||||
IgnoreFoW: false
|
IgnoreFoW: false
|
||||||
LayoutGroupSortIndex: 0
|
LayoutGroupSortIndex: 0
|
||||||
Locked: false
|
Locked: false
|
||||||
LuaScript: ''
|
LuaScript: !include 'Card Analysis 80285f.ttslua'
|
||||||
LuaScriptState: ''
|
LuaScriptState: ''
|
||||||
MeasureMovement: false
|
MeasureMovement: false
|
||||||
Name: Card
|
Name: Card
|
||||||
|
@ -21,11 +21,11 @@ Description: The Drifter
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"02005-pb\",\n \"type\": \"Investigator\",\n \"class\":
|
GMNotes: "{\n \"id\": \"02005-pb\",\n \"type\": \"Investigator\",\n \"class\":
|
||||||
\"Survivor\",\n \"traits\": \"Drifter.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
\"Survivor\",\n \"traits\": \"Drifter.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
||||||
2,\n \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"The Dunwich Legacy\",\n
|
2,\n \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"On the Road Again\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"FreeTrigger\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"90047\": 1,\n \"02014\": 1\n
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"90047\":
|
||||||
\ },\n {\n \"90048\": 1,\n \"02015\": 1\n }\n ]\n
|
1,\n \"02014\": 1\n },\n {\n \"90048\": 1,\n \"02015\":
|
||||||
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\"\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\"\n
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 3\n }\n
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 3\n }\n
|
||||||
\ },\n {\n \"faction\": [\n \"neutral\"\n ],\n \"level\":
|
\ },\n {\n \"faction\": [\n \"neutral\"\n ],\n \"level\":
|
||||||
{\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n \"trait\":
|
{\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n \"trait\":
|
||||||
|
@ -21,11 +21,11 @@ Description: The Drifter
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"02005-pf\",\n \"type\": \"Investigator\",\n \"class\":
|
GMNotes: "{\n \"id\": \"02005-pf\",\n \"type\": \"Investigator\",\n \"class\":
|
||||||
\"Survivor\",\n \"traits\": \"Drifter.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
\"Survivor\",\n \"traits\": \"Drifter.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
||||||
2,\n \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"The Dunwich Legacy\",\n
|
2,\n \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"On the Road Again\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"90047\": 1,\n \"02014\": 1\n
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"90047\":
|
||||||
\ },\n {\n \"90048\": 1,\n \"02015\": 1\n }\n ]\n
|
1,\n \"02014\": 1\n },\n {\n \"90048\": 1,\n \"02015\":
|
||||||
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\",\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\",\n
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
5\n }\n },\n {\n \"level\": {\n \"min\": 0,\n \"max\":
|
5\n }\n },\n {\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
0\n },\n \"limit\": 5,\n \"error\": \"You cannot have more than 5
|
0\n },\n \"limit\": 5,\n \"error\": \"You cannot have more than 5
|
||||||
|
@ -21,11 +21,11 @@ Description: The Drifter
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"02005-p\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n
|
GMNotes: "{\n \"id\": \"02005-p\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n
|
||||||
\ \"traits\": \"Drifter.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": 2,\n
|
\ \"traits\": \"Drifter.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": 2,\n
|
||||||
\ \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"The Dunwich Legacy\",\n
|
\ \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"On the Road Again\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"90047\": 1,\n \"02014\": 1\n
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"90047\":
|
||||||
\ },\n {\n \"90048\": 1,\n \"02015\": 1\n }\n ]\n
|
1,\n \"02014\": 1\n },\n {\n \"90048\": 1,\n \"02015\":
|
||||||
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\"\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\"\n
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 3\n }\n
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 3\n }\n
|
||||||
\ },\n {\n \"faction\": [\n \"neutral\"\n ],\n \"level\":
|
\ },\n {\n \"faction\": [\n \"neutral\"\n ],\n \"level\":
|
||||||
{\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n \"trait\":
|
{\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n \"trait\":
|
||||||
|
@ -22,10 +22,10 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"02005\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n
|
GMNotes: "{\n \"id\": \"02005\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n
|
||||||
\ \"traits\": \"Drifter.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": 2,\n
|
\ \"traits\": \"Drifter.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": 2,\n
|
||||||
\ \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"The Dunwich Legacy\",\n
|
\ \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"The Dunwich Legacy\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"FreeTrigger\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"90047\": 1,\n \"02014\": 1\n
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"90047\":
|
||||||
\ },\n {\n \"90048\": 1,\n \"02015\": 1\n }\n ]\n
|
1,\n \"02014\": 1\n },\n {\n \"90048\": 1,\n \"02015\":
|
||||||
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\",\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\",\n
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
5\n }\n },\n {\n \"level\": {\n \"min\": 0,\n \"max\":
|
5\n }\n },\n {\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
0\n },\n \"limit\": 5,\n \"error\": \"You cannot have more than 5
|
0\n },\n \"limit\": 5,\n \"error\": \"You cannot have more than 5
|
||||||
|
@ -21,7 +21,9 @@ Description: ''
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"09091\",\n \"type\": \"Asset\",\n \"slot\": \"Body\",\n
|
GMNotes: "{\n \"id\": \"09091\",\n \"type\": \"Asset\",\n \"slot\": \"Body\",\n
|
||||||
\ \"class\": \"Mystic\",\n \"cost\": 3,\n \"level\": 2,\n \"traits\": \"Ritual.\",\n
|
\ \"class\": \"Mystic\",\n \"cost\": 3,\n \"level\": 2,\n \"traits\": \"Ritual.\",\n
|
||||||
\ \"combatIcons\": 1,\n \"cycle\": \"The Scarlet Keys\"\n}"
|
\ \"combatIcons\": 1,\n \"uses\": [\n {\n \"count\": 1,\n \"type\":
|
||||||
|
\"PlayItem\",\n \"token\": \"universalActionAbility\"\n }\n ],\n \"cycle\":
|
||||||
|
\"The Scarlet Keys\"\n}"
|
||||||
GUID: b5d894
|
GUID: b5d894
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -39,7 +39,7 @@ SidewaysCard: false
|
|||||||
Snap: true
|
Snap: true
|
||||||
Sticky: true
|
Sticky: true
|
||||||
Tags:
|
Tags:
|
||||||
- ScenarioCard
|
- PlayerCard
|
||||||
Tooltip: true
|
Tooltip: true
|
||||||
Transform:
|
Transform:
|
||||||
posX: 48.98
|
posX: 48.98
|
||||||
|
@ -21,7 +21,8 @@ Description: ''
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"10129\",\n \"type\": \"Event\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"10129\",\n \"type\": \"Event\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"cost\": 0,\n \"level\": 0,\n \"traits\": \"Double.\",\n \"wildIcons\": 1,\n
|
\ \"cost\": 0,\n \"level\": 0,\n \"traits\": \"Double.\",\n \"wildIcons\": 1,\n
|
||||||
\ \"cycle\": \"The Feast of Hemlock Vale\"\n}"
|
\ \"uses\": [\n {\n \"count\": 2,\n \"type\": \"Universal\",\n \"token\":
|
||||||
|
\"universalActionAbility\"\n }\n ],\n \"cycle\": \"The Feast of Hemlock Vale\"\n}"
|
||||||
GUID: 24d3b3
|
GUID: 24d3b3
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,16 +22,17 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"08016\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n
|
GMNotes: "{\n \"id\": \"08016\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n
|
||||||
\ \"traits\": \"Entrepreneur.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\":
|
\ \"traits\": \"Entrepreneur.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\":
|
||||||
4,\n \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"Edge of the Earth\",\n
|
4,\n \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"Edge of the Earth\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"PlayItem\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"08017\": 1\n },\n {\n \"08018\":
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"08017\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\"\n
|
1\n },\n {\n \"08018\": 1\n }\n ]\n },\n \"deck_options\":
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 0\n }\n
|
[\n {\n \"faction\": [\n \"survivor\"\n ],\n \"level\":
|
||||||
\ },\n {\n \"faction\": [\n \"neutral\"\n ],\n \"level\":
|
{\n \"min\": 0,\n \"max\": 0\n }\n },\n {\n \"faction\":
|
||||||
{\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n \"faction\":
|
[\n \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
[\n \"rogue\"\n ],\n \"level\": {\n \"min\": 1,\n \"max\":
|
|
||||||
5\n }\n },\n {\n \"faction\": [\n \"rogue\"\n ],\n \"level\":
|
5\n }\n },\n {\n \"faction\": [\n \"rogue\"\n ],\n \"level\":
|
||||||
{\n \"min\": 0,\n \"max\": 0\n },\n \"limit\": 5,\n \"error\":
|
{\n \"min\": 1,\n \"max\": 5\n }\n },\n {\n \"faction\":
|
||||||
\"You cannot have more than 5 level 0 Rogue cards\"\n }\n ]\n}"
|
[\n \"rogue\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
|
0\n },\n \"limit\": 5,\n \"error\": \"You cannot have more than 5
|
||||||
|
level 0 Rogue cards\"\n }\n ]\n}"
|
||||||
GUID: 419b0c
|
GUID: 419b0c
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -14,18 +14,18 @@
|
|||||||
onClick="resolveToken"
|
onClick="resolveToken"
|
||||||
textColor="white"
|
textColor="white"
|
||||||
active="false"/>
|
active="false"/>
|
||||||
<Panel position="0 -55 -22"
|
<TableLayout position="0 -55 -22"
|
||||||
rotation="0 0 180"
|
rotation="0 0 180"
|
||||||
height="900"
|
height="900"
|
||||||
width="1400"
|
width="1400"
|
||||||
scale="0.1 0.1 1"/>
|
scale="0.1 0.1 1"
|
||||||
<TableLayout active="false"
|
|
||||||
cellSpacing="80"
|
cellSpacing="80"
|
||||||
cellBackgroundColor="rgba(1,1,1,0)"/>
|
cellBackgroundColor="rgba(1,1,1,0)"/>
|
||||||
</Defaults>
|
</Defaults>
|
||||||
|
|
||||||
<Panel>
|
<Panel id="Helper"
|
||||||
<TableLayout id="actives">
|
active="false">
|
||||||
|
<TableLayout>
|
||||||
<Row>
|
<Row>
|
||||||
<Cell>
|
<Cell>
|
||||||
<Button id="Bless"
|
<Button id="Bless"
|
||||||
@ -43,10 +43,7 @@
|
|||||||
</Cell>
|
</Cell>
|
||||||
</Row>
|
</Row>
|
||||||
</TableLayout>
|
</TableLayout>
|
||||||
</Panel>
|
<TableLayout>
|
||||||
|
|
||||||
<Panel>
|
|
||||||
<TableLayout id="inactives">
|
|
||||||
<Row>
|
<Row>
|
||||||
<Cell>
|
<Cell>
|
||||||
<Button id="inactiveBless"
|
<Button id="inactiveBless"
|
||||||
|
@ -22,12 +22,13 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"04005\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n
|
GMNotes: "{\n \"id\": \"04005\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n
|
||||||
\ \"traits\": \"Cursed. Drifter.\",\n \"willpowerIcons\": 0,\n \"intellectIcons\":
|
\ \"traits\": \"Cursed. Drifter.\",\n \"willpowerIcons\": 0,\n \"intellectIcons\":
|
||||||
0,\n \"combatIcons\": 0,\n \"agilityIcons\": 0,\n \"cycle\": \"The Forgotten
|
0,\n \"combatIcons\": 0,\n \"agilityIcons\": 0,\n \"cycle\": \"The Forgotten
|
||||||
Age\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
Age\",\n \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"04015\": 1\n },\n {\n \"04016\":
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"04015\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\",\n
|
1\n },\n {\n \"04016\": 1\n }\n ]\n },\n \"deck_options\":
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
[\n {\n \"faction\": [\n \"survivor\",\n \"neutral\"\n ],\n
|
||||||
5\n }\n },\n {\n \"trait\": [\n \"spirit\"\n ],\n \"level\":
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
||||||
{\n \"min\": 0,\n \"max\": 3\n }\n }\n ]\n}"
|
\ \"trait\": [\n \"spirit\"\n ],\n \"level\": {\n \"min\":
|
||||||
|
0,\n \"max\": 3\n }\n }\n ]\n}"
|
||||||
GUID: b02a1e
|
GUID: b02a1e
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,20 +22,20 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"05001\",\n \"alternate_ids\": [\n \"98010\"\n ],\n \"type\":
|
GMNotes: "{\n \"id\": \"05001\",\n \"alternate_ids\": [\n \"98010\"\n ],\n \"type\":
|
||||||
\"Investigator\",\n \"class\": \"Guardian\",\n \"traits\": \"Medic.\",\n \"willpowerIcons\":
|
\"Investigator\",\n \"class\": \"Guardian\",\n \"traits\": \"Medic.\",\n \"willpowerIcons\":
|
||||||
3,\n \"intellectIcons\": 4,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\":
|
3,\n \"intellectIcons\": 4,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\":
|
||||||
\"The Circle Undone\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\"The Circle Undone\",\n \"extraToken\": \"None\",\n \"deck_requirements\": {\n
|
||||||
1,\n \"signatures\": [\n {\n \"05007\": 1,\n \"98011\": 1\n },\n
|
\ \"size\": 30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n
|
||||||
\ {\n \"05008\": 1,\n \"98012\": 1\n }\n ]\n },\n \"deck_options\":
|
\ {\n \"05007\": 1,\n \"98011\": 1\n },\n {\n \"05008\":
|
||||||
[\n {\n \"not\": true,\n \"trait\": [\n \"weapon\"\n ],\n
|
1,\n \"98012\": 1\n }\n ]\n },\n \"deck_options\": [\n {\n \"not\":
|
||||||
\ \"level\": {\n \"min\": 1,\n \"max\": 5\n }\n },\n {\n
|
true,\n \"trait\": [\n \"weapon\"\n ],\n \"level\": {\n \"min\":
|
||||||
\ \"faction\": [\n \"guardian\"\n ],\n \"level\": {\n \"min\":
|
1,\n \"max\": 5\n }\n },\n {\n \"faction\": [\n \"guardian\"\n
|
||||||
0,\n \"max\": 3\n }\n },\n {\n \"faction\": [\n \"neutral\"\n
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 3\n }\n
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n
|
\ },\n {\n \"faction\": [\n \"neutral\"\n ],\n \"level\":
|
||||||
\ },\n {\n \"special\": [\n \"heals_horror\"\n ],\n \"tag\":
|
{\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n \"special\":
|
||||||
[\n \"hh\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
[\n \"heals_horror\"\n ],\n \"tag\": [\n \"hh\"\n ],\n
|
||||||
5\n }\n },\n {\n \"faction\": [\n \"seeker\",\n \"mystic\"\n
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 1\n },\n
|
\ \"faction\": [\n \"seeker\",\n \"mystic\"\n ],\n \"level\":
|
||||||
\ \"limit\": 15,\n \"error\": \"You cannot have more than 15 level 0-1
|
{\n \"min\": 0,\n \"max\": 1\n },\n \"limit\": 15,\n \"error\":
|
||||||
Seeker and/or Mystic cards\"\n }\n ]\n}"
|
\"You cannot have more than 15 level 0-1 Seeker and/or Mystic cards\"\n }\n ]\n}"
|
||||||
GUID: b03b12
|
GUID: b03b12
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
@ -77,23 +77,24 @@ States:
|
|||||||
GMNotes: "{\r\n \"id\": \"05001\",\r\n \"alternate_ids\": [\r\n \"98010\"\r\n
|
GMNotes: "{\r\n \"id\": \"05001\",\r\n \"alternate_ids\": [\r\n \"98010\"\r\n
|
||||||
\ ],\r\n \"type\": \"Investigator\",\r\n \"class\": \"Guardian\",\r\n \"traits\":
|
\ ],\r\n \"type\": \"Investigator\",\r\n \"class\": \"Guardian\",\r\n \"traits\":
|
||||||
\"Medic.\",\r\n \"willpowerIcons\": 3,\r\n \"intellectIcons\": 4,\r\n \"combatIcons\":
|
\"Medic.\",\r\n \"willpowerIcons\": 3,\r\n \"intellectIcons\": 4,\r\n \"combatIcons\":
|
||||||
2,\r\n \"agilityIcons\": 2,\r\n \"cycle\": \"The Circle Undone\",\r\n \"deck_requirements\":
|
2,\r\n \"agilityIcons\": 2,\r\n \"cycle\": \"The Circle Undone\",\r\n \"extraToken\":
|
||||||
{\r\n \"size\": 30,\r\n \"randomBasicWeaknessCount\": 1,\r\n \"signatures\":
|
\"None\",\r\n \"deck_requirements\": {\r\n \"size\": 30,\r\n \"randomBasicWeaknessCount\":
|
||||||
[\r\n {\r\n \"05007\": 1,\r\n \"98011\": 1\r\n },\r\n {\r\n
|
1,\r\n \"signatures\": [\r\n {\r\n \"05007\": 1,\r\n \"98011\":
|
||||||
\ \"05008\": 1,\r\n \"98012\": 1\r\n }\r\n ]\r\n },\r\n \"deck_options\":
|
1\r\n },\r\n {\r\n \"05008\": 1,\r\n \"98012\": 1\r\n }\r\n
|
||||||
[\r\n {\r\n \"not\": true,\r\n \"trait\": [\r\n \"weapon\"\r\n
|
\ ]\r\n },\r\n \"deck_options\": [\r\n {\r\n \"not\": true,\r\n
|
||||||
\ ],\r\n \"level\": {\r\n \"min\": 1,\r\n \"max\": 5\r\n
|
\ \"trait\": [\r\n \"weapon\"\r\n ],\r\n \"level\": {\r\n
|
||||||
\ }\r\n },\r\n {\r\n \"faction\": [\r\n \"guardian\"\r\n
|
\ \"min\": 1,\r\n \"max\": 5\r\n }\r\n },\r\n {\r\n
|
||||||
\ ],\r\n \"level\": {\r\n \"min\": 0,\r\n \"max\": 3\r\n
|
\ \"faction\": [\r\n \"guardian\"\r\n ],\r\n \"level\":
|
||||||
\ }\r\n },\r\n {\r\n \"faction\": [\r\n \"neutral\"\r\n
|
{\r\n \"min\": 0,\r\n \"max\": 3\r\n }\r\n },\r\n {\r\n
|
||||||
\ ],\r\n \"level\": {\r\n \"min\": 0,\r\n \"max\": 5\r\n
|
\ \"faction\": [\r\n \"neutral\"\r\n ],\r\n \"level\":
|
||||||
\ }\r\n },\r\n {\r\n \"special\": [\r\n \"heals_horror\"\r\n
|
|
||||||
\ ],\r\n \"tag\": [\r\n \"hh\"\r\n ],\r\n \"level\":
|
|
||||||
{\r\n \"min\": 0,\r\n \"max\": 5\r\n }\r\n },\r\n {\r\n
|
{\r\n \"min\": 0,\r\n \"max\": 5\r\n }\r\n },\r\n {\r\n
|
||||||
\ \"faction\": [\r\n \"seeker\",\r\n \"mystic\"\r\n ],\r\n
|
\ \"special\": [\r\n \"heals_horror\"\r\n ],\r\n \"tag\":
|
||||||
\ \"level\": {\r\n \"min\": 0,\r\n \"max\": 1\r\n },\r\n
|
[\r\n \"hh\"\r\n ],\r\n \"level\": {\r\n \"min\": 0,\r\n
|
||||||
\ \"limit\": 15,\r\n \"error\": \"You cannot have more than 15 level
|
\ \"max\": 5\r\n }\r\n },\r\n {\r\n \"faction\": [\r\n
|
||||||
0-1 Seeker and/or Mystic cards\"\r\n }\r\n ]\r\n}\r\n"
|
\ \"seeker\",\r\n \"mystic\"\r\n ],\r\n \"level\": {\r\n
|
||||||
|
\ \"min\": 0,\r\n \"max\": 1\r\n },\r\n \"limit\": 15,\r\n
|
||||||
|
\ \"error\": \"You cannot have more than 15 level 0-1 Seeker and/or Mystic
|
||||||
|
cards\"\r\n }\r\n ]\r\n}\r\n"
|
||||||
GUID: 9900a3
|
GUID: 9900a3
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,20 +22,21 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"09001\",\n \"type\": \"Investigator\",\n \"class\": \"Guardian\",\n
|
GMNotes: "{\n \"id\": \"09001\",\n \"type\": \"Investigator\",\n \"class\": \"Guardian\",\n
|
||||||
\ \"traits\": \"Assistant.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\": 2,\n
|
\ \"traits\": \"Assistant.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\": 2,\n
|
||||||
\ \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"The Scarlet Keys\",\n
|
\ \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"The Scarlet Keys\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Activate\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"09002\": 2\n },\n {\n \"09003\":
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"09002\":
|
||||||
1\n }\n ],\n \"choices\": 1\n },\n \"deck_options\": [\n {\n \"faction\":
|
2\n },\n {\n \"09003\": 1\n }\n ],\n \"choices\": 1\n
|
||||||
[\n \"guardian\",\n \"neutral\"\n ],\n \"level\": {\n \"min\":
|
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"guardian\",\n
|
||||||
0,\n \"max\": 5\n }\n },\n {\n \"choiceName\": \"Seeker\",\n
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ \"faction\": [\n \"seeker\"\n ],\n \"level\": {\n \"min\":
|
5\n }\n },\n {\n \"choiceName\": \"Seeker\",\n \"faction\":
|
||||||
0,\n \"max\": 1\n },\n \"type\": [\n \"event\",\n \"skill\"\n
|
[\n \"seeker\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ ],\n \"limit\": 10\n },\n {\n \"choiceName\": \"Mystic\",\n
|
1\n },\n \"type\": [\n \"event\",\n \"skill\"\n ],\n
|
||||||
\ \"faction\": [\n \"mystic\"\n ],\n \"level\": {\n \"min\":
|
\ \"limit\": 10\n },\n {\n \"choiceName\": \"Mystic\",\n \"faction\":
|
||||||
0,\n \"max\": 1\n },\n \"type\": [\n \"event\",\n \"skill\"\n
|
[\n \"mystic\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ ],\n \"limit\": 10\n },\n {\n \"choiceName\": \"Survivor\",\n
|
1\n },\n \"type\": [\n \"event\",\n \"skill\"\n ],\n
|
||||||
\ \"faction\": [\n \"survivor\"\n ],\n \"level\": {\n \"min\":
|
\ \"limit\": 10\n },\n {\n \"choiceName\": \"Survivor\",\n \"faction\":
|
||||||
0,\n \"max\": 1\n },\n \"type\": [\n \"event\",\n \"skill\"\n
|
[\n \"survivor\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ ],\n \"limit\": 10\n }\n ]\n}"
|
1\n },\n \"type\": [\n \"event\",\n \"skill\"\n ],\n
|
||||||
|
\ \"limit\": 10\n }\n ]\n}"
|
||||||
GUID: dc96d1
|
GUID: dc96d1
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,7 +22,7 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"09018\",\n \"type\": \"Investigator\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"09018\",\n \"type\": \"Investigator\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"traits\": \"Civic. Socialite.\",\n \"willpowerIcons\": 1,\n \"intellectIcons\":
|
\ \"traits\": \"Civic. Socialite.\",\n \"willpowerIcons\": 1,\n \"intellectIcons\":
|
||||||
1,\n \"combatIcons\": 1,\n \"agilityIcons\": 1,\n \"cycle\": \"The Scarlet Keys\",\n
|
1,\n \"combatIcons\": 1,\n \"agilityIcons\": 1,\n \"cycle\": \"The Scarlet Keys\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
1,\n \"signatures\": [\n {\n \"09019\": 1\n },\n {\n \"09020\":
|
1,\n \"signatures\": [\n {\n \"09019\": 1\n },\n {\n \"09020\":
|
||||||
1\n }\n ],\n \"choices\": 2\n },\n \"deck_options\": [\n {\n \"faction\":
|
1\n }\n ],\n \"choices\": 2\n },\n \"deck_options\": [\n {\n \"faction\":
|
||||||
[\n \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
[\n \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
|
@ -0,0 +1,247 @@
|
|||||||
|
-- Bundled by luabundle {"version":"1.6.0"}
|
||||||
|
local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)
|
||||||
|
local loadingPlaceholder = {[{}] = true}
|
||||||
|
|
||||||
|
local register
|
||||||
|
local modules = {}
|
||||||
|
|
||||||
|
local require
|
||||||
|
local loaded = {}
|
||||||
|
|
||||||
|
register = function(name, body)
|
||||||
|
if not modules[name] then
|
||||||
|
modules[name] = body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require = function(name)
|
||||||
|
local loadedModule = loaded[name]
|
||||||
|
|
||||||
|
if loadedModule then
|
||||||
|
if loadedModule == loadingPlaceholder then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not modules[name] then
|
||||||
|
if not superRequire then
|
||||||
|
local identifier = type(name) == 'string' and '\"' .. name .. '\"' or tostring(name)
|
||||||
|
error('Tried to require ' .. identifier .. ', but no such module has been registered')
|
||||||
|
else
|
||||||
|
return superRequire(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
loaded[name] = loadingPlaceholder
|
||||||
|
loadedModule = modules[name](require, loaded, register, modules)
|
||||||
|
loaded[name] = loadedModule
|
||||||
|
end
|
||||||
|
|
||||||
|
return loadedModule
|
||||||
|
end
|
||||||
|
|
||||||
|
return require, loaded, register, modules
|
||||||
|
end)(nil)
|
||||||
|
__bundle_register("playercards/CardsThatRedrawTokens", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
--[[ Library for cards that return and redraw tokens
|
||||||
|
This file is used to add an XML button to a card, turned on via context menu.
|
||||||
|
Valid options modify the appearance of the XML button, as well as the
|
||||||
|
behavior of the return and redraw function. Set options before requiring this file.
|
||||||
|
|
||||||
|
Parameters for the return and redraw functions. Typically set VALID_TOKENS or INVALID_TOKENS, not both.
|
||||||
|
If there are no restrictions on which tokens can be redrawn (e.g. Wendy Adams), keep both empty.
|
||||||
|
* VALID_TOKENS --@type table
|
||||||
|
- keyed table which lists all tokens that can be redrawn by the card
|
||||||
|
- example usage: "False Covenant"
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Curse"] = true
|
||||||
|
> }
|
||||||
|
|
||||||
|
* INVALID_TOKENS --@type table
|
||||||
|
- keyed table which lists all tokens that cannot be redrawn by the card
|
||||||
|
- example usage: "Custom Ammunition"
|
||||||
|
> INVALID_TOKENS = {
|
||||||
|
> ["Auto-fail"] = true
|
||||||
|
> }
|
||||||
|
|
||||||
|
* DRAW_SPECIFIC_TOKEN --@type string (name of token or nil)
|
||||||
|
- if set, will attempt to draw that specific token
|
||||||
|
|
||||||
|
* RETURN_TO_POOL --@type string
|
||||||
|
- allows for the name of the card to be passed onto Global for any special handling
|
||||||
|
|
||||||
|
The following parameters modify the appearence of the XML button and are not listed as part of a table.
|
||||||
|
- buttonHeight (default is 450)
|
||||||
|
- buttonWidth (default is 1400)
|
||||||
|
- buttonPosition (default is "0 -55 -22")
|
||||||
|
- buttonFontSize (default is 250)
|
||||||
|
- buttonRotation (change if button is placed on an investigator cards)
|
||||||
|
- buttonLabel (default is "Redraw Token")
|
||||||
|
- buttonIcon (to add an icon to the right)
|
||||||
|
- buttonColor (default is "#77674DE6")
|
||||||
|
|
||||||
|
----------------------------------------------------------
|
||||||
|
EXAMPLE: Claypool's Furs
|
||||||
|
This card can only redraw the Frost token, and is replaced with a random token from the bag.
|
||||||
|
As a nice reminder the XML button takes on the Frost color and icon with the text "Cancel".
|
||||||
|
> buttonValue = "Cancel"
|
||||||
|
> buttonIcon = "token-frost"
|
||||||
|
> buttonColor = "#404450E6"
|
||||||
|
> buttonFontSize = 300
|
||||||
|
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Frost"] = true
|
||||||
|
> }
|
||||||
|
>
|
||||||
|
> require...
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
-- intentionally global
|
||||||
|
hasXML = true
|
||||||
|
isHelperEnabled = false
|
||||||
|
|
||||||
|
function updateSave()
|
||||||
|
self.script_state = JSON.encode({ isHelperEnabled = isHelperEnabled })
|
||||||
|
end
|
||||||
|
|
||||||
|
function onLoad(savedData)
|
||||||
|
if savedData and savedData ~= "" then
|
||||||
|
local loadedData = JSON.decode(savedData)
|
||||||
|
isHelperEnabled = loadedData.isHelperEnabled
|
||||||
|
end
|
||||||
|
createHelperXML()
|
||||||
|
syncDisplayWithOptionPanel()
|
||||||
|
end
|
||||||
|
|
||||||
|
function createHelperXML()
|
||||||
|
local xmlTable = { {
|
||||||
|
tag = "Button",
|
||||||
|
attributes = {
|
||||||
|
active = "false",
|
||||||
|
id = "Helper",
|
||||||
|
height = buttonHeight or 450,
|
||||||
|
width = buttonWidth or 1400,
|
||||||
|
rotation = buttonRotation or "0 0 180",
|
||||||
|
scale = "0.1 0.1 1",
|
||||||
|
position = buttonPosition or "0 -55 -22",
|
||||||
|
padding = "50 50 50 50",
|
||||||
|
font = "font_teutonic-arkham",
|
||||||
|
fontSize = buttonFontSize or 250,
|
||||||
|
onClick = "triggerXMLTokenLabelCreation",
|
||||||
|
color = buttonColor or "#77674DE6",
|
||||||
|
textColor = "White"
|
||||||
|
},
|
||||||
|
value = buttonLabel or "Redraw Token"
|
||||||
|
} }
|
||||||
|
if buttonIcon then
|
||||||
|
xmlTable[1].attributes.iconWidth = "400"
|
||||||
|
xmlTable[1].attributes.iconAlignment = "Right"
|
||||||
|
xmlTable[1].attributes.icon = buttonIcon
|
||||||
|
end
|
||||||
|
self.UI.setXmlTable(xmlTable)
|
||||||
|
end
|
||||||
|
|
||||||
|
function triggerXMLTokenLabelCreation()
|
||||||
|
Global.call("activeRedrawEffect", {
|
||||||
|
VALID_TOKENS = VALID_TOKENS,
|
||||||
|
INVALID_TOKENS = INVALID_TOKENS,
|
||||||
|
RETURN_TO_POOL = RETURN_TO_POOL
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/CardsWithHelper", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
--[[ Library for cards that have helpers
|
||||||
|
This file is used to share code between cards with helpers.
|
||||||
|
It syncs the visibility of the helper with the option panel and
|
||||||
|
makes sure the card has the respective tag.
|
||||||
|
Additionally, it will call 'initiliaze()' and 'shutOff()'
|
||||||
|
in the parent file if they are present.
|
||||||
|
|
||||||
|
Instructions:
|
||||||
|
1) Define the global variables before requiring this file:
|
||||||
|
hasXML = true (whether the card has an XML display)
|
||||||
|
isHelperEnabled = false (default state of the helper, should be 'false')
|
||||||
|
|
||||||
|
2) In 'onLoad()'', call 'syncDisplayWithOptionPanel()'
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
local optionPanelApi = require("core/OptionPanelApi")
|
||||||
|
|
||||||
|
-- if the respective option is enabled in onLoad(), enable the helper
|
||||||
|
function syncDisplayWithOptionPanel()
|
||||||
|
self.addTag("CardWithHelper")
|
||||||
|
local options = optionPanelApi.getOptions()
|
||||||
|
if options.enableCardHelpers then
|
||||||
|
setHelperState(true)
|
||||||
|
else
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- forces a new state
|
||||||
|
function setHelperState(newState)
|
||||||
|
isHelperEnabled = newState
|
||||||
|
updateSave()
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- toggles the current state
|
||||||
|
function toggleHelper()
|
||||||
|
isHelperEnabled = not isHelperEnabled
|
||||||
|
updateSave()
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- updates the visibility and calls events (after a small delay to allow XML being set)
|
||||||
|
function updateDisplay()
|
||||||
|
Wait.frames(actualDisplayUpdate, 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
function actualDisplayUpdate()
|
||||||
|
if isHelperEnabled then
|
||||||
|
self.clearContextMenu()
|
||||||
|
self.addContextMenuItem("Disable Helper", toggleHelper)
|
||||||
|
if hasXML then self.UI.show("Helper") end
|
||||||
|
if initialize then initialize() end
|
||||||
|
else
|
||||||
|
self.clearContextMenu()
|
||||||
|
self.addContextMenuItem("Enable Helper", toggleHelper)
|
||||||
|
if hasXML then self.UI.hide("Helper") end
|
||||||
|
if shutOff then shutOff() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
do
|
||||||
|
local OptionPanelApi = {}
|
||||||
|
|
||||||
|
-- loads saved options
|
||||||
|
---@param options table Set a new state for the option table
|
||||||
|
OptionPanelApi.loadSettings = function(options)
|
||||||
|
return Global.call("loadSettings", options)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return any: Table of option panel state
|
||||||
|
OptionPanelApi.getOptions = function()
|
||||||
|
return Global.getTable("optionPanel")
|
||||||
|
end
|
||||||
|
|
||||||
|
return OptionPanelApi
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
require("playercards/cards/ClaypoolsFurs")
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/cards/ClaypoolsFurs", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
buttonLabel = "Cancel"
|
||||||
|
buttonIcon = "token-frost"
|
||||||
|
buttonColor = "#404450E6"
|
||||||
|
buttonFontSize = 300
|
||||||
|
|
||||||
|
VALID_TOKENS = {
|
||||||
|
["Frost"] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
require("playercards/CardsWithHelper")
|
||||||
|
require("playercards/CardsThatRedrawTokens")
|
||||||
|
end)
|
||||||
|
return __bundle_require("__root")
|
@ -30,7 +30,7 @@ HideWhenFaceDown: true
|
|||||||
IgnoreFoW: false
|
IgnoreFoW: false
|
||||||
LayoutGroupSortIndex: 0
|
LayoutGroupSortIndex: 0
|
||||||
Locked: false
|
Locked: false
|
||||||
LuaScript: ''
|
LuaScript: !include 'Card Claypool''s Furs c1f999.ttslua'
|
||||||
LuaScriptState: ''
|
LuaScriptState: ''
|
||||||
MeasureMovement: false
|
MeasureMovement: false
|
||||||
Name: Card
|
Name: Card
|
||||||
|
@ -22,7 +22,7 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"90031\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"90031\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"traits\": \"Task.\",\n \"weakness\": true,\n \"uses\": [\n {\n \"count\":
|
\ \"traits\": \"Task.\",\n \"weakness\": true,\n \"uses\": [\n {\n \"count\":
|
||||||
4,\n \"type\": \"Clue\",\n \"token\": \"clue\"\n }\n ],\n \"cycle\":
|
4,\n \"type\": \"Clue\",\n \"token\": \"clue\"\n }\n ],\n \"cycle\":
|
||||||
\"Standalone\"\n}"
|
\"By the Book\"\n}"
|
||||||
GUID: f802e3
|
GUID: f802e3
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,242 @@
|
|||||||
|
-- Bundled by luabundle {"version":"1.6.0"}
|
||||||
|
local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)
|
||||||
|
local loadingPlaceholder = {[{}] = true}
|
||||||
|
|
||||||
|
local register
|
||||||
|
local modules = {}
|
||||||
|
|
||||||
|
local require
|
||||||
|
local loaded = {}
|
||||||
|
|
||||||
|
register = function(name, body)
|
||||||
|
if not modules[name] then
|
||||||
|
modules[name] = body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require = function(name)
|
||||||
|
local loadedModule = loaded[name]
|
||||||
|
|
||||||
|
if loadedModule then
|
||||||
|
if loadedModule == loadingPlaceholder then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not modules[name] then
|
||||||
|
if not superRequire then
|
||||||
|
local identifier = type(name) == 'string' and '\"' .. name .. '\"' or tostring(name)
|
||||||
|
error('Tried to require ' .. identifier .. ', but no such module has been registered')
|
||||||
|
else
|
||||||
|
return superRequire(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
loaded[name] = loadingPlaceholder
|
||||||
|
loadedModule = modules[name](require, loaded, register, modules)
|
||||||
|
loaded[name] = loadedModule
|
||||||
|
end
|
||||||
|
|
||||||
|
return loadedModule
|
||||||
|
end
|
||||||
|
|
||||||
|
return require, loaded, register, modules
|
||||||
|
end)(nil)
|
||||||
|
__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
require("playercards/cards/CustomModifications")
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/cards/CustomModifications", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
INVALID_TOKENS = {
|
||||||
|
["Auto-fail"] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
require("playercards/CardsWithHelper")
|
||||||
|
require("playercards/CardsThatRedrawTokens")
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/CardsThatRedrawTokens", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
--[[ Library for cards that return and redraw tokens
|
||||||
|
This file is used to add an XML button to a card, turned on via context menu.
|
||||||
|
Valid options modify the appearance of the XML button, as well as the
|
||||||
|
behavior of the return and redraw function. Set options before requiring this file.
|
||||||
|
|
||||||
|
Parameters for the return and redraw functions. Typically set VALID_TOKENS or INVALID_TOKENS, not both.
|
||||||
|
If there are no restrictions on which tokens can be redrawn (e.g. Wendy Adams), keep both empty.
|
||||||
|
* VALID_TOKENS --@type table
|
||||||
|
- keyed table which lists all tokens that can be redrawn by the card
|
||||||
|
- example usage: "False Covenant"
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Curse"] = true
|
||||||
|
> }
|
||||||
|
|
||||||
|
* INVALID_TOKENS --@type table
|
||||||
|
- keyed table which lists all tokens that cannot be redrawn by the card
|
||||||
|
- example usage: "Custom Ammunition"
|
||||||
|
> INVALID_TOKENS = {
|
||||||
|
> ["Auto-fail"] = true
|
||||||
|
> }
|
||||||
|
|
||||||
|
* DRAW_SPECIFIC_TOKEN --@type string (name of token or nil)
|
||||||
|
- if set, will attempt to draw that specific token
|
||||||
|
|
||||||
|
* RETURN_TO_POOL --@type string
|
||||||
|
- allows for the name of the card to be passed onto Global for any special handling
|
||||||
|
|
||||||
|
The following parameters modify the appearence of the XML button and are not listed as part of a table.
|
||||||
|
- buttonHeight (default is 450)
|
||||||
|
- buttonWidth (default is 1400)
|
||||||
|
- buttonPosition (default is "0 -55 -22")
|
||||||
|
- buttonFontSize (default is 250)
|
||||||
|
- buttonRotation (change if button is placed on an investigator cards)
|
||||||
|
- buttonLabel (default is "Redraw Token")
|
||||||
|
- buttonIcon (to add an icon to the right)
|
||||||
|
- buttonColor (default is "#77674DE6")
|
||||||
|
|
||||||
|
----------------------------------------------------------
|
||||||
|
EXAMPLE: Claypool's Furs
|
||||||
|
This card can only redraw the Frost token, and is replaced with a random token from the bag.
|
||||||
|
As a nice reminder the XML button takes on the Frost color and icon with the text "Cancel".
|
||||||
|
> buttonValue = "Cancel"
|
||||||
|
> buttonIcon = "token-frost"
|
||||||
|
> buttonColor = "#404450E6"
|
||||||
|
> buttonFontSize = 300
|
||||||
|
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Frost"] = true
|
||||||
|
> }
|
||||||
|
>
|
||||||
|
> require...
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
-- intentionally global
|
||||||
|
hasXML = true
|
||||||
|
isHelperEnabled = false
|
||||||
|
|
||||||
|
function updateSave()
|
||||||
|
self.script_state = JSON.encode({ isHelperEnabled = isHelperEnabled })
|
||||||
|
end
|
||||||
|
|
||||||
|
function onLoad(savedData)
|
||||||
|
if savedData and savedData ~= "" then
|
||||||
|
local loadedData = JSON.decode(savedData)
|
||||||
|
isHelperEnabled = loadedData.isHelperEnabled
|
||||||
|
end
|
||||||
|
createHelperXML()
|
||||||
|
syncDisplayWithOptionPanel()
|
||||||
|
end
|
||||||
|
|
||||||
|
function createHelperXML()
|
||||||
|
local xmlTable = { {
|
||||||
|
tag = "Button",
|
||||||
|
attributes = {
|
||||||
|
active = "false",
|
||||||
|
id = "Helper",
|
||||||
|
height = buttonHeight or 450,
|
||||||
|
width = buttonWidth or 1400,
|
||||||
|
rotation = buttonRotation or "0 0 180",
|
||||||
|
scale = "0.1 0.1 1",
|
||||||
|
position = buttonPosition or "0 -55 -22",
|
||||||
|
padding = "50 50 50 50",
|
||||||
|
font = "font_teutonic-arkham",
|
||||||
|
fontSize = buttonFontSize or 250,
|
||||||
|
onClick = "triggerXMLTokenLabelCreation",
|
||||||
|
color = buttonColor or "#77674DE6",
|
||||||
|
textColor = "White"
|
||||||
|
},
|
||||||
|
value = buttonLabel or "Redraw Token"
|
||||||
|
} }
|
||||||
|
if buttonIcon then
|
||||||
|
xmlTable[1].attributes.iconWidth = "400"
|
||||||
|
xmlTable[1].attributes.iconAlignment = "Right"
|
||||||
|
xmlTable[1].attributes.icon = buttonIcon
|
||||||
|
end
|
||||||
|
self.UI.setXmlTable(xmlTable)
|
||||||
|
end
|
||||||
|
|
||||||
|
function triggerXMLTokenLabelCreation()
|
||||||
|
Global.call("activeRedrawEffect", {
|
||||||
|
VALID_TOKENS = VALID_TOKENS,
|
||||||
|
INVALID_TOKENS = INVALID_TOKENS,
|
||||||
|
RETURN_TO_POOL = RETURN_TO_POOL
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/CardsWithHelper", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
--[[ Library for cards that have helpers
|
||||||
|
This file is used to share code between cards with helpers.
|
||||||
|
It syncs the visibility of the helper with the option panel and
|
||||||
|
makes sure the card has the respective tag.
|
||||||
|
Additionally, it will call 'initiliaze()' and 'shutOff()'
|
||||||
|
in the parent file if they are present.
|
||||||
|
|
||||||
|
Instructions:
|
||||||
|
1) Define the global variables before requiring this file:
|
||||||
|
hasXML = true (whether the card has an XML display)
|
||||||
|
isHelperEnabled = false (default state of the helper, should be 'false')
|
||||||
|
|
||||||
|
2) In 'onLoad()'', call 'syncDisplayWithOptionPanel()'
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
local optionPanelApi = require("core/OptionPanelApi")
|
||||||
|
|
||||||
|
-- if the respective option is enabled in onLoad(), enable the helper
|
||||||
|
function syncDisplayWithOptionPanel()
|
||||||
|
self.addTag("CardWithHelper")
|
||||||
|
local options = optionPanelApi.getOptions()
|
||||||
|
if options.enableCardHelpers then
|
||||||
|
setHelperState(true)
|
||||||
|
else
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- forces a new state
|
||||||
|
function setHelperState(newState)
|
||||||
|
isHelperEnabled = newState
|
||||||
|
updateSave()
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- toggles the current state
|
||||||
|
function toggleHelper()
|
||||||
|
isHelperEnabled = not isHelperEnabled
|
||||||
|
updateSave()
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- updates the visibility and calls events (after a small delay to allow XML being set)
|
||||||
|
function updateDisplay()
|
||||||
|
Wait.frames(actualDisplayUpdate, 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
function actualDisplayUpdate()
|
||||||
|
if isHelperEnabled then
|
||||||
|
self.clearContextMenu()
|
||||||
|
self.addContextMenuItem("Disable Helper", toggleHelper)
|
||||||
|
if hasXML then self.UI.show("Helper") end
|
||||||
|
if initialize then initialize() end
|
||||||
|
else
|
||||||
|
self.clearContextMenu()
|
||||||
|
self.addContextMenuItem("Enable Helper", toggleHelper)
|
||||||
|
if hasXML then self.UI.hide("Helper") end
|
||||||
|
if shutOff then shutOff() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
do
|
||||||
|
local OptionPanelApi = {}
|
||||||
|
|
||||||
|
-- loads saved options
|
||||||
|
---@param options table Set a new state for the option table
|
||||||
|
OptionPanelApi.loadSettings = function(options)
|
||||||
|
return Global.call("loadSettings", options)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return any: Table of option panel state
|
||||||
|
OptionPanelApi.getOptions = function()
|
||||||
|
return Global.getTable("optionPanel")
|
||||||
|
end
|
||||||
|
|
||||||
|
return OptionPanelApi
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
return __bundle_require("__root")
|
@ -44,7 +44,7 @@ HideWhenFaceDown: true
|
|||||||
IgnoreFoW: false
|
IgnoreFoW: false
|
||||||
LayoutGroupSortIndex: 0
|
LayoutGroupSortIndex: 0
|
||||||
Locked: false
|
Locked: false
|
||||||
LuaScript: ''
|
LuaScript: !include 'Card Custom Modifications d2252d.ttslua'
|
||||||
LuaScriptState: ''
|
LuaScriptState: ''
|
||||||
MeasureMovement: false
|
MeasureMovement: false
|
||||||
Name: Card
|
Name: Card
|
||||||
|
@ -21,18 +21,19 @@ Description: The Librarian
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"01002-pb\",\n \"type\": \"Investigator\",\n \"class\":
|
GMNotes: "{\n \"id\": \"01002-pb\",\n \"type\": \"Investigator\",\n \"class\":
|
||||||
\"Seeker\",\n \"traits\": \"Miskatonic.\",\n \"willpowerIcons\": 3,\n \"intellectIcons\":
|
\"Seeker\",\n \"traits\": \"Miskatonic.\",\n \"willpowerIcons\": 3,\n \"intellectIcons\":
|
||||||
5,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"Core\",\n \"deck_requirements\":
|
5,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"Read or Die\",\n
|
||||||
{\n \"size\": 30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\":
|
\ \"extraToken\": \"Tome\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
[\n {\n \"90002\": 1,\n \"01008\": 1\n },\n {\n \"90003\":
|
1,\n \"signatures\": [\n {\n \"90002\": 1,\n \"01008\": 1\n
|
||||||
1,\n \"01009\": 1\n }\n ]\n },\n \"deck_options\": [\n {\n \"trait\":
|
\ },\n {\n \"90003\": 1,\n \"01009\": 1\n }\n ]\n
|
||||||
[\n \"tome\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ },\n \"deck_options\": [\n {\n \"trait\": [\n \"tome\"\n ],\n
|
||||||
5\n }\n },\n {\n \"faction\": [\n \"neutral\"\n ],\n
|
|
||||||
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
||||||
\ \"faction\": [\n \"seeker\"\n ],\n \"level\": {\n \"min\":
|
\ \"faction\": [\n \"neutral\"\n ],\n \"level\": {\n \"min\":
|
||||||
0,\n \"max\": 3\n }\n },\n {\n \"faction\": [\n \"guardian\",\n
|
0,\n \"max\": 5\n }\n },\n {\n \"faction\": [\n \"seeker\"\n
|
||||||
\ \"mystic\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 3\n }\n
|
||||||
0\n },\n \"limit\": 5,\n \"error\": \"You cannot have more than 5
|
\ },\n {\n \"faction\": [\n \"guardian\",\n \"mystic\"\n
|
||||||
Guardian and/or Mystic cards\"\n }\n ]\n}"
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 0\n },\n
|
||||||
|
\ \"limit\": 5,\n \"error\": \"You cannot have more than 5 Guardian and/or
|
||||||
|
Mystic cards\"\n }\n ]\n}"
|
||||||
GUID: 2f2e0d
|
GUID: 2f2e0d
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,14 +21,14 @@ Description: The Librarian
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"01002-pf\",\n \"type\": \"Investigator\",\n \"class\":
|
GMNotes: "{\n \"id\": \"01002-pf\",\n \"type\": \"Investigator\",\n \"class\":
|
||||||
\"Seeker\",\n \"traits\": \"Miskatonic.\",\n \"willpowerIcons\": 1,\n \"intellectIcons\":
|
\"Seeker\",\n \"traits\": \"Miskatonic.\",\n \"willpowerIcons\": 1,\n \"intellectIcons\":
|
||||||
5,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"Core\",\n \"deck_requirements\":
|
5,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"Read or Die\",\n
|
||||||
{\n \"size\": 30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\":
|
\ \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
[\n {\n \"90002\": 1,\n \"01008\": 1\n },\n {\n \"90003\":
|
1,\n \"signatures\": [\n {\n \"90002\": 1,\n \"01008\": 1\n
|
||||||
1,\n \"01009\": 1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\":
|
\ },\n {\n \"90003\": 1,\n \"01009\": 1\n }\n ]\n
|
||||||
[\n \"seeker\",\n \"neutral\"\n ],\n \"level\": {\n \"min\":
|
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"seeker\",\n
|
||||||
0,\n \"max\": 5\n }\n },\n {\n \"faction\": [\n \"mystic\"\n
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 2\n }\n
|
5\n }\n },\n {\n \"faction\": [\n \"mystic\"\n ],\n
|
||||||
\ }\n ]\n}"
|
\ \"level\": {\n \"min\": 0,\n \"max\": 2\n }\n }\n ]\n}"
|
||||||
GUID: e8cafc
|
GUID: e8cafc
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,18 +21,19 @@ Description: The Librarian
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"01002-p\",\n \"type\": \"Investigator\",\n \"class\": \"Seeker\",\n
|
GMNotes: "{\n \"id\": \"01002-p\",\n \"type\": \"Investigator\",\n \"class\": \"Seeker\",\n
|
||||||
\ \"traits\": \"Miskatonic.\",\n \"willpowerIcons\": 1,\n \"intellectIcons\":
|
\ \"traits\": \"Miskatonic.\",\n \"willpowerIcons\": 1,\n \"intellectIcons\":
|
||||||
5,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"Core\",\n \"deck_requirements\":
|
5,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"Read or Die\",\n
|
||||||
{\n \"size\": 30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\":
|
\ \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
[\n {\n \"90002\": 1,\n \"01008\": 1\n },\n {\n \"90003\":
|
1,\n \"signatures\": [\n {\n \"90002\": 1,\n \"01008\": 1\n
|
||||||
1,\n \"01009\": 1\n }\n ]\n },\n \"deck_options\": [\n {\n \"trait\":
|
\ },\n {\n \"90003\": 1,\n \"01009\": 1\n }\n ]\n
|
||||||
[\n \"tome\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ },\n \"deck_options\": [\n {\n \"trait\": [\n \"tome\"\n ],\n
|
||||||
5\n }\n },\n {\n \"faction\": [\n \"neutral\"\n ],\n
|
|
||||||
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
||||||
\ \"faction\": [\n \"seeker\"\n ],\n \"level\": {\n \"min\":
|
\ \"faction\": [\n \"neutral\"\n ],\n \"level\": {\n \"min\":
|
||||||
0,\n \"max\": 3\n }\n },\n {\n \"faction\": [\n \"guardian\",\n
|
0,\n \"max\": 5\n }\n },\n {\n \"faction\": [\n \"seeker\"\n
|
||||||
\ \"mystic\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 3\n }\n
|
||||||
0\n },\n \"limit\": 5,\n \"error\": \"You cannot have more than 5
|
\ },\n {\n \"faction\": [\n \"guardian\",\n \"mystic\"\n
|
||||||
Guardian and/or Mystic cards\"\n }\n ]\n}"
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 0\n },\n
|
||||||
|
\ \"limit\": 5,\n \"error\": \"You cannot have more than 5 Guardian and/or
|
||||||
|
Mystic cards\"\n }\n ]\n}"
|
||||||
GUID: '282857'
|
GUID: '282857'
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,10 +22,10 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"01002\",\n \"alternate_ids\": [\n \"01502\"\n ],\n \"type\":
|
GMNotes: "{\n \"id\": \"01002\",\n \"alternate_ids\": [\n \"01502\"\n ],\n \"type\":
|
||||||
\"Investigator\",\n \"class\": \"Seeker\",\n \"traits\": \"Miskatonic.\",\n \"willpowerIcons\":
|
\"Investigator\",\n \"class\": \"Seeker\",\n \"traits\": \"Miskatonic.\",\n \"willpowerIcons\":
|
||||||
3,\n \"intellectIcons\": 5,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\":
|
3,\n \"intellectIcons\": 5,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\":
|
||||||
\"Core\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\"Core\",\n \"extraToken\": \"Tome\",\n \"deck_requirements\": {\n \"size\":
|
||||||
1,\n \"signatures\": [\n {\n \"90002\": 1,\n \"01008\": 1\n
|
30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"90002\":
|
||||||
\ },\n {\n \"90003\": 1,\n \"01009\": 1\n }\n ]\n
|
1,\n \"01008\": 1\n },\n {\n \"90003\": 1,\n \"01009\":
|
||||||
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"seeker\",\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"seeker\",\n
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
5\n }\n },\n {\n \"faction\": [\n \"mystic\"\n ],\n
|
5\n }\n },\n {\n \"faction\": [\n \"mystic\"\n ],\n
|
||||||
\ \"level\": {\n \"min\": 0,\n \"max\": 2\n }\n }\n ]\n}"
|
\ \"level\": {\n \"min\": 0,\n \"max\": 2\n }\n }\n ]\n}"
|
||||||
@ -71,14 +71,15 @@ States:
|
|||||||
\ ],\r\n \"type\": \"Investigator\",\r\n \"class\": \"Seeker\",\r\n \"traits\":
|
\ ],\r\n \"type\": \"Investigator\",\r\n \"class\": \"Seeker\",\r\n \"traits\":
|
||||||
\"Miskatonic.\",\r\n \"willpowerIcons\": 3,\r\n \"intellectIcons\": 5,\r\n
|
\"Miskatonic.\",\r\n \"willpowerIcons\": 3,\r\n \"intellectIcons\": 5,\r\n
|
||||||
\ \"combatIcons\": 2,\r\n \"agilityIcons\": 2,\r\n \"cycle\": \"Core\",\r\n
|
\ \"combatIcons\": 2,\r\n \"agilityIcons\": 2,\r\n \"cycle\": \"Core\",\r\n
|
||||||
\ \"deck_requirements\": {\r\n \"size\": 30,\r\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Tome\",\r\n \"deck_requirements\": {\r\n \"size\": 30,\r\n
|
||||||
1,\r\n \"signatures\": [\r\n {\r\n \"90002\": 1,\r\n \"01008\":
|
\ \"randomBasicWeaknessCount\": 1,\r\n \"signatures\": [\r\n {\r\n
|
||||||
1\r\n },\r\n {\r\n \"90003\": 1,\r\n \"01009\": 1\r\n
|
\ \"90002\": 1,\r\n \"01008\": 1\r\n },\r\n {\r\n \"90003\":
|
||||||
\ }\r\n ]\r\n },\r\n \"deck_options\": [\r\n {\r\n \"faction\":
|
1,\r\n \"01009\": 1\r\n }\r\n ]\r\n },\r\n \"deck_options\":
|
||||||
[\r\n \"seeker\",\r\n \"neutral\"\r\n ],\r\n \"level\":
|
[\r\n {\r\n \"faction\": [\r\n \"seeker\",\r\n \"neutral\"\r\n
|
||||||
{\r\n \"min\": 0,\r\n \"max\": 5\r\n }\r\n },\r\n {\r\n
|
\ ],\r\n \"level\": {\r\n \"min\": 0,\r\n \"max\": 5\r\n
|
||||||
\ \"faction\": [\r\n \"mystic\"\r\n ],\r\n \"level\": {\r\n
|
\ }\r\n },\r\n {\r\n \"faction\": [\r\n \"mystic\"\r\n
|
||||||
\ \"min\": 0,\r\n \"max\": 2\r\n }\r\n }\r\n ]\r\n}\r\n"
|
\ ],\r\n \"level\": {\r\n \"min\": 0,\r\n \"max\": 2\r\n
|
||||||
|
\ }\r\n }\r\n ]\r\n}\r\n"
|
||||||
GUID: ac7047
|
GUID: ac7047
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,7 +22,7 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"08001\",\n \"type\": \"Investigator\",\n \"class\": \"Guardian\",\n
|
GMNotes: "{\n \"id\": \"08001\",\n \"type\": \"Investigator\",\n \"class\": \"Guardian\",\n
|
||||||
\ \"traits\": \"Entrepreneur.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
\ \"traits\": \"Entrepreneur.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
||||||
1,\n \"combatIcons\": 5,\n \"agilityIcons\": 2,\n \"cycle\": \"Edge of the Earth\",\n
|
1,\n \"combatIcons\": 5,\n \"agilityIcons\": 2,\n \"cycle\": \"Edge of the Earth\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
1,\n \"signatures\": [\n {\n \"08002\": 1\n },\n {\n \"08003\":
|
1,\n \"signatures\": [\n {\n \"08002\": 1\n },\n {\n \"08003\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"guardian\"\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"guardian\"\n
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 0\n }\n
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 0\n }\n
|
||||||
|
@ -20,7 +20,8 @@ CustomDeck:
|
|||||||
Description: Advanced
|
Description: Advanced
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90019\",\n \"type\": \"Event\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"90019\",\n \"type\": \"Event\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"cost\": 4,\n \"traits\": \"Spell.\",\n \"weakness\": true,\n \"cycle\": \"Standalone\"\n}"
|
\ \"cost\": 4,\n \"traits\": \"Spell.\",\n \"weakness\": true,\n \"cycle\": \"Bad
|
||||||
|
Blood\"\n}"
|
||||||
GUID: 580a4d
|
GUID: 580a4d
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"09015\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n
|
GMNotes: "{\n \"id\": \"09015\",\n \"type\": \"Investigator\",\n \"class\": \"Survivor\",\n
|
||||||
\ \"traits\": \"Reporter.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\": 5,\n
|
\ \"traits\": \"Reporter.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\": 5,\n
|
||||||
\ \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"The Scarlet Keys\",\n
|
\ \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"The Scarlet Keys\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
1,\n \"signatures\": [\n {\n \"09016\": 1\n },\n {\n \"09017\":
|
1,\n \"signatures\": [\n {\n \"09016\": 1\n },\n {\n \"09017\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\",\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"survivor\",\n
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -22,10 +22,11 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"07004\",\n \"alternate_ids\": [\n \"98016\"\n ],\n \"type\":
|
GMNotes: "{\n \"id\": \"07004\",\n \"alternate_ids\": [\n \"98016\"\n ],\n \"type\":
|
||||||
\"Investigator\",\n \"class\": \"Mystic\",\n \"traits\": \"Sorcerer. Veteran.\",\n
|
\"Investigator\",\n \"class\": \"Mystic\",\n \"traits\": \"Sorcerer. Veteran.\",\n
|
||||||
\ \"willpowerIcons\": 5,\n \"intellectIcons\": 2,\n \"combatIcons\": 3,\n \"agilityIcons\":
|
\ \"willpowerIcons\": 5,\n \"intellectIcons\": 2,\n \"combatIcons\": 3,\n \"agilityIcons\":
|
||||||
2,\n \"cycle\": \"The Innsmouth Conspiracy\",\n \"deck_requirements\": {\n \"size\":
|
2,\n \"cycle\": \"The Innsmouth Conspiracy\",\n \"extraToken\": \"FreeTrigger\",\n
|
||||||
30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"98017\":
|
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
1,\n \"07012\": 1\n },\n {\n \"98018\": 1,\n \"07013\":
|
1,\n \"signatures\": [\n {\n \"98017\": 1,\n \"07012\": 1\n
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
\ },\n {\n \"98018\": 1,\n \"07013\": 1\n }\n ]\n
|
||||||
|
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
5\n }\n },\n {\n \"faction\": [\n \"rogue\"\n ],\n \"level\":
|
5\n }\n },\n {\n \"faction\": [\n \"rogue\"\n ],\n \"level\":
|
||||||
{\n \"min\": 0,\n \"max\": 2\n }\n }\n ]\n}"
|
{\n \"min\": 0,\n \"max\": 2\n }\n }\n ]\n}"
|
||||||
@ -71,15 +72,15 @@ States:
|
|||||||
\ ],\r\n \"type\": \"Investigator\",\r\n \"class\": \"Mystic\",\r\n \"traits\":
|
\ ],\r\n \"type\": \"Investigator\",\r\n \"class\": \"Mystic\",\r\n \"traits\":
|
||||||
\"Sorcerer. Veteran.\",\r\n \"willpowerIcons\": 5,\r\n \"intellectIcons\":
|
\"Sorcerer. Veteran.\",\r\n \"willpowerIcons\": 5,\r\n \"intellectIcons\":
|
||||||
2,\r\n \"combatIcons\": 3,\r\n \"agilityIcons\": 2,\r\n \"cycle\": \"The
|
2,\r\n \"combatIcons\": 3,\r\n \"agilityIcons\": 2,\r\n \"cycle\": \"The
|
||||||
Innsmouth Conspiracy\",\r\n \"deck_requirements\": {\r\n \"size\": 30,\r\n
|
Innsmouth Conspiracy\",\r\n \"extraToken\": \"Lightning\",\r\n \"deck_requirements\":
|
||||||
\ \"randomBasicWeaknessCount\": 1,\r\n \"signatures\": [\r\n {\r\n
|
{\r\n \"size\": 30,\r\n \"randomBasicWeaknessCount\": 1,\r\n \"signatures\":
|
||||||
\ \"98017\": 1,\r\n \"07012\": 1\r\n },\r\n {\r\n \"98018\":
|
[\r\n {\r\n \"98017\": 1,\r\n \"07012\": 1\r\n },\r\n
|
||||||
1,\r\n \"07013\": 1\r\n }\r\n ]\r\n },\r\n \"deck_options\":
|
\ {\r\n \"98018\": 1,\r\n \"07013\": 1\r\n }\r\n ]\r\n
|
||||||
[\r\n {\r\n \"faction\": [\r\n \"mystic\",\r\n \"neutral\"\r\n
|
\ },\r\n \"deck_options\": [\r\n {\r\n \"faction\": [\r\n \"mystic\",\r\n
|
||||||
\ ],\r\n \"level\": {\r\n \"min\": 0,\r\n \"max\": 5\r\n
|
\ \"neutral\"\r\n ],\r\n \"level\": {\r\n \"min\": 0,\r\n
|
||||||
\ }\r\n },\r\n {\r\n \"faction\": [\r\n \"rogue\"\r\n
|
\ \"max\": 5\r\n }\r\n },\r\n {\r\n \"faction\": [\r\n
|
||||||
\ ],\r\n \"level\": {\r\n \"min\": 0,\r\n \"max\": 2\r\n
|
\ \"rogue\"\r\n ],\r\n \"level\": {\r\n \"min\": 0,\r\n
|
||||||
\ }\r\n }\r\n ]\r\n}\r\n"
|
\ \"max\": 2\r\n }\r\n }\r\n ]\r\n}\r\n"
|
||||||
GUID: 3925ce
|
GUID: 3925ce
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,13 +22,13 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"05004\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
GMNotes: "{\n \"id\": \"05004\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
||||||
\ \"traits\": \"Cultist. Silver Twilight.\",\n \"willpowerIcons\": 1,\n \"intellectIcons\":
|
\ \"traits\": \"Cultist. Silver Twilight.\",\n \"willpowerIcons\": 1,\n \"intellectIcons\":
|
||||||
3,\n \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"The Circle Undone\",\n
|
3,\n \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\": \"The Circle Undone\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 35,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\": 35,\n
|
||||||
1,\n \"signatures\": [\n {\n \"05013\": 1\n },\n {\n \"05014\":
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"05013\":
|
||||||
1\n },\n {\n \"05015\": 1\n }\n ]\n },\n \"deck_options\":
|
1\n },\n {\n \"05014\": 1\n },\n {\n \"05015\":
|
||||||
[\n {\n \"faction\": [\n \"mystic\",\n \"neutral\"\n ],\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
||||||
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ \"faction\": [\n \"guardian\"\n ],\n \"level\": {\n \"min\":
|
5\n }\n },\n {\n \"faction\": [\n \"guardian\"\n ],\n
|
||||||
0,\n \"max\": 2\n }\n }\n ]\n}"
|
\ \"level\": {\n \"min\": 0,\n \"max\": 2\n }\n }\n ]\n}"
|
||||||
GUID: 32b091
|
GUID: 32b091
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -20,7 +20,7 @@ CustomDeck:
|
|||||||
Description: Leave No Doubt
|
Description: Leave No Doubt
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90029\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"90029\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"startsInPlay\": true,\n \"permanent\": true,\n \"cycle\": \"Standalone\"\n}"
|
\ \"startsInPlay\": true,\n \"permanent\": true,\n \"cycle\": \"By the Book\"\n}"
|
||||||
GUID: 07e7bd
|
GUID: 07e7bd
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -20,7 +20,7 @@ CustomDeck:
|
|||||||
Description: Seek the Truth
|
Description: Seek the Truth
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90028\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"90028\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"startsInPlay\": true,\n \"permanent\": true,\n \"cycle\": \"Standalone\"\n}"
|
\ \"startsInPlay\": true,\n \"permanent\": true,\n \"cycle\": \"By the Book\"\n}"
|
||||||
GUID: 0994c9
|
GUID: 0994c9
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -20,7 +20,7 @@ CustomDeck:
|
|||||||
Description: Due Diligence
|
Description: Due Diligence
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90025\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"90025\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"startsInPlay\": true,\n \"permanent\": true,\n \"cycle\": \"Standalone\"\n}"
|
\ \"startsInPlay\": true,\n \"permanent\": true,\n \"cycle\": \"By the Book\"\n}"
|
||||||
GUID: '133521'
|
GUID: '133521'
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -20,7 +20,7 @@ CustomDeck:
|
|||||||
Description: Consult Experts
|
Description: Consult Experts
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90027\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"90027\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"startsInPlay\": true,\n \"permanent\": true,\n \"cycle\": \"Standalone\"\n}"
|
\ \"startsInPlay\": true,\n \"permanent\": true,\n \"cycle\": \"By the Book\"\n}"
|
||||||
GUID: 2d9256
|
GUID: 2d9256
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -20,7 +20,7 @@ CustomDeck:
|
|||||||
Description: Red Tape
|
Description: Red Tape
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90026\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"90026\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"startsInPlay\": true,\n \"permanent\": true,\n \"cycle\": \"Standalone\"\n}"
|
\ \"startsInPlay\": true,\n \"permanent\": true,\n \"cycle\": \"By the Book\"\n}"
|
||||||
GUID: '706176'
|
GUID: '706176'
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,8 +20,9 @@ CustomDeck:
|
|||||||
Description: ''
|
Description: ''
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"09104\",\n \"type\": \"Event\",\n \"class\": \"Survivor\",\n
|
GMNotes: "{\n \"id\": \"09104\",\n \"type\": \"Event\",\n \"class\": \"Survivor\",\n
|
||||||
\ \"cost\": 0,\n \"level\": 0,\n \"traits\": \"Insight. Spirit.\",\n \"cycle\":
|
\ \"cost\": 0,\n \"level\": 0,\n \"traits\": \"Insight. Spirit.\",\n \"uses\":
|
||||||
\"The Scarlet Keys\"\n}"
|
[\n {\n \"count\": 1,\n \"type\": \"Universal\",\n \"token\":
|
||||||
|
\"universalActionAbility\"\n }\n ],\n \"cycle\": \"The Scarlet Keys\"\n}"
|
||||||
GUID: a3d041
|
GUID: a3d041
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -20,8 +20,9 @@ CustomDeck:
|
|||||||
Description: ''
|
Description: ''
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"04148\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"04148\",\n \"type\": \"Asset\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"cost\": 2,\n \"traits\": \"Item. Tome.\",\n \"intellectIcons\": 2,\n \"cycle\":
|
\ \"cost\": 2,\n \"traits\": \"Item. Tome.\",\n \"intellectIcons\": 2,\n \"uses\":
|
||||||
\"The Forgotten Age\"\n}"
|
[\n {\n \"count\": 1,\n \"type\": \"Explore\",\n \"token\": \"universalActionAbility\"\n
|
||||||
|
\ }\n ],\n \"cycle\": \"The Forgotten Age\"\n}"
|
||||||
GUID: 9dc3d4
|
GUID: 9dc3d4
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,8 +21,9 @@ Description: ''
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"10082\",\n \"type\": \"Asset\",\n \"slot\": \"Hand\",\n
|
GMNotes: "{\n \"id\": \"10082\",\n \"type\": \"Asset\",\n \"slot\": \"Hand\",\n
|
||||||
\ \"class\": \"Rogue\",\n \"cost\": 2,\n \"level\": 4,\n \"traits\": \"Item.
|
\ \"class\": \"Rogue\",\n \"cost\": 2,\n \"level\": 4,\n \"traits\": \"Item.
|
||||||
Illicit.\",\n \"intellectIcons\": 1,\n \"agilityIcons\": 1,\n \"cycle\": \"The
|
Illicit.\",\n \"intellectIcons\": 1,\n \"agilityIcons\": 1,\n \"uses\": [\n {\n
|
||||||
Feast of Hemlock Vale\"\n}"
|
\ \"count\": 0,\n \"type\": \"Suspicion\",\n \"token\": \"resource\"\n
|
||||||
|
\ }\n ],\n \"cycle\": \"The Feast of Hemlock Vale\"\n}"
|
||||||
GUID: 7ebb67
|
GUID: 7ebb67
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,7 +21,9 @@ Description: ''
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"10066\",\n \"type\": \"Asset\",\n \"slot\": \"Hand\",\n
|
GMNotes: "{\n \"id\": \"10066\",\n \"type\": \"Asset\",\n \"slot\": \"Hand\",\n
|
||||||
\ \"class\": \"Rogue\",\n \"cost\": 3,\n \"level\": 0,\n \"traits\": \"Item.
|
\ \"class\": \"Rogue\",\n \"cost\": 3,\n \"level\": 0,\n \"traits\": \"Item.
|
||||||
Illicit.\",\n \"intellectIcons\": 1,\n \"cycle\": \"The Feast of Hemlock Vale\"\n}"
|
Illicit.\",\n \"intellectIcons\": 1,\n \"uses\": [\n {\n \"count\": 0,\n
|
||||||
|
\ \"type\": \"Suspicion\",\n \"token\": \"resource\"\n }\n ],\n \"cycle\":
|
||||||
|
\"The Feast of Hemlock Vale\"\n}"
|
||||||
GUID: acd38d
|
GUID: acd38d
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -0,0 +1,248 @@
|
|||||||
|
-- Bundled by luabundle {"version":"1.6.0"}
|
||||||
|
local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)
|
||||||
|
local loadingPlaceholder = {[{}] = true}
|
||||||
|
|
||||||
|
local register
|
||||||
|
local modules = {}
|
||||||
|
|
||||||
|
local require
|
||||||
|
local loaded = {}
|
||||||
|
|
||||||
|
register = function(name, body)
|
||||||
|
if not modules[name] then
|
||||||
|
modules[name] = body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require = function(name)
|
||||||
|
local loadedModule = loaded[name]
|
||||||
|
|
||||||
|
if loadedModule then
|
||||||
|
if loadedModule == loadingPlaceholder then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not modules[name] then
|
||||||
|
if not superRequire then
|
||||||
|
local identifier = type(name) == 'string' and '\"' .. name .. '\"' or tostring(name)
|
||||||
|
error('Tried to require ' .. identifier .. ', but no such module has been registered')
|
||||||
|
else
|
||||||
|
return superRequire(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
loaded[name] = loadingPlaceholder
|
||||||
|
loadedModule = modules[name](require, loaded, register, modules)
|
||||||
|
loaded[name] = loadedModule
|
||||||
|
end
|
||||||
|
|
||||||
|
return loadedModule
|
||||||
|
end
|
||||||
|
|
||||||
|
return require, loaded, register, modules
|
||||||
|
end)(nil)
|
||||||
|
__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
do
|
||||||
|
local OptionPanelApi = {}
|
||||||
|
|
||||||
|
-- loads saved options
|
||||||
|
---@param options table Set a new state for the option table
|
||||||
|
OptionPanelApi.loadSettings = function(options)
|
||||||
|
return Global.call("loadSettings", options)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return any: Table of option panel state
|
||||||
|
OptionPanelApi.getOptions = function()
|
||||||
|
return Global.getTable("optionPanel")
|
||||||
|
end
|
||||||
|
|
||||||
|
return OptionPanelApi
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
require("playercards/cards/FalseCovenant")
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/cards/FalseCovenant", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
buttonLabel = "Cancel"
|
||||||
|
buttonIcon = "token-curse"
|
||||||
|
buttonColor = "#633A84E6"
|
||||||
|
buttonFontSize = 300
|
||||||
|
|
||||||
|
RETURN_TO_POOL = true
|
||||||
|
VALID_TOKENS = {
|
||||||
|
["Curse"] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
require("playercards/CardsWithHelper")
|
||||||
|
require("playercards/CardsThatRedrawTokens")
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/CardsThatRedrawTokens", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
--[[ Library for cards that return and redraw tokens
|
||||||
|
This file is used to add an XML button to a card, turned on via context menu.
|
||||||
|
Valid options modify the appearance of the XML button, as well as the
|
||||||
|
behavior of the return and redraw function. Set options before requiring this file.
|
||||||
|
|
||||||
|
Parameters for the return and redraw functions. Typically set VALID_TOKENS or INVALID_TOKENS, not both.
|
||||||
|
If there are no restrictions on which tokens can be redrawn (e.g. Wendy Adams), keep both empty.
|
||||||
|
* VALID_TOKENS --@type table
|
||||||
|
- keyed table which lists all tokens that can be redrawn by the card
|
||||||
|
- example usage: "False Covenant"
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Curse"] = true
|
||||||
|
> }
|
||||||
|
|
||||||
|
* INVALID_TOKENS --@type table
|
||||||
|
- keyed table which lists all tokens that cannot be redrawn by the card
|
||||||
|
- example usage: "Custom Ammunition"
|
||||||
|
> INVALID_TOKENS = {
|
||||||
|
> ["Auto-fail"] = true
|
||||||
|
> }
|
||||||
|
|
||||||
|
* DRAW_SPECIFIC_TOKEN --@type string (name of token or nil)
|
||||||
|
- if set, will attempt to draw that specific token
|
||||||
|
|
||||||
|
* RETURN_TO_POOL --@type string
|
||||||
|
- allows for the name of the card to be passed onto Global for any special handling
|
||||||
|
|
||||||
|
The following parameters modify the appearence of the XML button and are not listed as part of a table.
|
||||||
|
- buttonHeight (default is 450)
|
||||||
|
- buttonWidth (default is 1400)
|
||||||
|
- buttonPosition (default is "0 -55 -22")
|
||||||
|
- buttonFontSize (default is 250)
|
||||||
|
- buttonRotation (change if button is placed on an investigator cards)
|
||||||
|
- buttonLabel (default is "Redraw Token")
|
||||||
|
- buttonIcon (to add an icon to the right)
|
||||||
|
- buttonColor (default is "#77674DE6")
|
||||||
|
|
||||||
|
----------------------------------------------------------
|
||||||
|
EXAMPLE: Claypool's Furs
|
||||||
|
This card can only redraw the Frost token, and is replaced with a random token from the bag.
|
||||||
|
As a nice reminder the XML button takes on the Frost color and icon with the text "Cancel".
|
||||||
|
> buttonValue = "Cancel"
|
||||||
|
> buttonIcon = "token-frost"
|
||||||
|
> buttonColor = "#404450E6"
|
||||||
|
> buttonFontSize = 300
|
||||||
|
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Frost"] = true
|
||||||
|
> }
|
||||||
|
>
|
||||||
|
> require...
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
-- intentionally global
|
||||||
|
hasXML = true
|
||||||
|
isHelperEnabled = false
|
||||||
|
|
||||||
|
function updateSave()
|
||||||
|
self.script_state = JSON.encode({ isHelperEnabled = isHelperEnabled })
|
||||||
|
end
|
||||||
|
|
||||||
|
function onLoad(savedData)
|
||||||
|
if savedData and savedData ~= "" then
|
||||||
|
local loadedData = JSON.decode(savedData)
|
||||||
|
isHelperEnabled = loadedData.isHelperEnabled
|
||||||
|
end
|
||||||
|
createHelperXML()
|
||||||
|
syncDisplayWithOptionPanel()
|
||||||
|
end
|
||||||
|
|
||||||
|
function createHelperXML()
|
||||||
|
local xmlTable = { {
|
||||||
|
tag = "Button",
|
||||||
|
attributes = {
|
||||||
|
active = "false",
|
||||||
|
id = "Helper",
|
||||||
|
height = buttonHeight or 450,
|
||||||
|
width = buttonWidth or 1400,
|
||||||
|
rotation = buttonRotation or "0 0 180",
|
||||||
|
scale = "0.1 0.1 1",
|
||||||
|
position = buttonPosition or "0 -55 -22",
|
||||||
|
padding = "50 50 50 50",
|
||||||
|
font = "font_teutonic-arkham",
|
||||||
|
fontSize = buttonFontSize or 250,
|
||||||
|
onClick = "triggerXMLTokenLabelCreation",
|
||||||
|
color = buttonColor or "#77674DE6",
|
||||||
|
textColor = "White"
|
||||||
|
},
|
||||||
|
value = buttonLabel or "Redraw Token"
|
||||||
|
} }
|
||||||
|
if buttonIcon then
|
||||||
|
xmlTable[1].attributes.iconWidth = "400"
|
||||||
|
xmlTable[1].attributes.iconAlignment = "Right"
|
||||||
|
xmlTable[1].attributes.icon = buttonIcon
|
||||||
|
end
|
||||||
|
self.UI.setXmlTable(xmlTable)
|
||||||
|
end
|
||||||
|
|
||||||
|
function triggerXMLTokenLabelCreation()
|
||||||
|
Global.call("activeRedrawEffect", {
|
||||||
|
VALID_TOKENS = VALID_TOKENS,
|
||||||
|
INVALID_TOKENS = INVALID_TOKENS,
|
||||||
|
RETURN_TO_POOL = RETURN_TO_POOL
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/CardsWithHelper", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
--[[ Library for cards that have helpers
|
||||||
|
This file is used to share code between cards with helpers.
|
||||||
|
It syncs the visibility of the helper with the option panel and
|
||||||
|
makes sure the card has the respective tag.
|
||||||
|
Additionally, it will call 'initiliaze()' and 'shutOff()'
|
||||||
|
in the parent file if they are present.
|
||||||
|
|
||||||
|
Instructions:
|
||||||
|
1) Define the global variables before requiring this file:
|
||||||
|
hasXML = true (whether the card has an XML display)
|
||||||
|
isHelperEnabled = false (default state of the helper, should be 'false')
|
||||||
|
|
||||||
|
2) In 'onLoad()'', call 'syncDisplayWithOptionPanel()'
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
local optionPanelApi = require("core/OptionPanelApi")
|
||||||
|
|
||||||
|
-- if the respective option is enabled in onLoad(), enable the helper
|
||||||
|
function syncDisplayWithOptionPanel()
|
||||||
|
self.addTag("CardWithHelper")
|
||||||
|
local options = optionPanelApi.getOptions()
|
||||||
|
if options.enableCardHelpers then
|
||||||
|
setHelperState(true)
|
||||||
|
else
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- forces a new state
|
||||||
|
function setHelperState(newState)
|
||||||
|
isHelperEnabled = newState
|
||||||
|
updateSave()
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- toggles the current state
|
||||||
|
function toggleHelper()
|
||||||
|
isHelperEnabled = not isHelperEnabled
|
||||||
|
updateSave()
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- updates the visibility and calls events (after a small delay to allow XML being set)
|
||||||
|
function updateDisplay()
|
||||||
|
Wait.frames(actualDisplayUpdate, 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
function actualDisplayUpdate()
|
||||||
|
if isHelperEnabled then
|
||||||
|
self.clearContextMenu()
|
||||||
|
self.addContextMenuItem("Disable Helper", toggleHelper)
|
||||||
|
if hasXML then self.UI.show("Helper") end
|
||||||
|
if initialize then initialize() end
|
||||||
|
else
|
||||||
|
self.clearContextMenu()
|
||||||
|
self.addContextMenuItem("Enable Helper", toggleHelper)
|
||||||
|
if hasXML then self.UI.hide("Helper") end
|
||||||
|
if shutOff then shutOff() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
return __bundle_require("__root")
|
@ -30,7 +30,7 @@ HideWhenFaceDown: true
|
|||||||
IgnoreFoW: false
|
IgnoreFoW: false
|
||||||
LayoutGroupSortIndex: 0
|
LayoutGroupSortIndex: 0
|
||||||
Locked: false
|
Locked: false
|
||||||
LuaScript: ''
|
LuaScript: !include 'Card False Covenant (2) 3442f5.ttslua'
|
||||||
LuaScriptState: ''
|
LuaScriptState: ''
|
||||||
MeasureMovement: false
|
MeasureMovement: false
|
||||||
Name: Card
|
Name: Card
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,39 @@
|
|||||||
|
<!-- include playercards/FamilyInheritance.xml -->
|
||||||
|
<Defaults>
|
||||||
|
<Button padding="30 30 30 30"
|
||||||
|
font="font_teutonic-arkham"
|
||||||
|
textColor="white"
|
||||||
|
fontSize="235"
|
||||||
|
shadow="#405041B3"
|
||||||
|
shadowDistance="-15 15"/>
|
||||||
|
<TableLayout position="130 0 -22"
|
||||||
|
rotation="0 0 270"
|
||||||
|
height="460"
|
||||||
|
width="2600"
|
||||||
|
scale="0.1 0.1 1"
|
||||||
|
cellSpacing="80"
|
||||||
|
cellBackgroundColor="rgba(1,1,1,0)"/>
|
||||||
|
</Defaults>
|
||||||
|
|
||||||
|
<TableLayout id="Helper"
|
||||||
|
active="false">
|
||||||
|
<Row>
|
||||||
|
<Cell>
|
||||||
|
<Button onClick="loseAll"
|
||||||
|
color="#6D202C"
|
||||||
|
fontSize="195"
|
||||||
|
text="Discard all"/>
|
||||||
|
</Cell>
|
||||||
|
<Cell>
|
||||||
|
<Button onClick="takeAll"
|
||||||
|
color="#173B0B"
|
||||||
|
text="Move all"/>
|
||||||
|
</Cell>
|
||||||
|
<Cell>
|
||||||
|
<Button onClick="add4"
|
||||||
|
color="#77674D"
|
||||||
|
text="Place 4"/>
|
||||||
|
</Cell>
|
||||||
|
</Row>
|
||||||
|
</TableLayout>
|
||||||
|
<!-- include playercards/FamilyInheritance.xml -->
|
@ -54,4 +54,4 @@ Transform:
|
|||||||
scaleY: 1
|
scaleY: 1
|
||||||
scaleZ: 1
|
scaleZ: 1
|
||||||
Value: 0
|
Value: 0
|
||||||
XmlUI: ''
|
XmlUI: !include 'Card Family Inheritance 394603.xml'
|
||||||
|
@ -22,12 +22,13 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"04004\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
GMNotes: "{\n \"id\": \"04004\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
||||||
\ \"traits\": \"Believer. Warden.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
\ \"traits\": \"Believer. Warden.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
||||||
3,\n \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"The Forgotten
|
3,\n \"combatIcons\": 2,\n \"agilityIcons\": 3,\n \"cycle\": \"The Forgotten
|
||||||
Age\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
Age\",\n \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"04013\": 1\n },\n {\n \"04014\":
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"04013\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
1\n },\n {\n \"04014\": 1\n }\n ]\n },\n \"deck_options\":
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
[\n {\n \"faction\": [\n \"mystic\",\n \"neutral\"\n ],\n
|
||||||
5\n }\n },\n {\n \"trait\": [\n \"blessed\"\n ],\n \"level\":
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
||||||
{\n \"min\": 0,\n \"max\": 3\n }\n }\n ]\n}"
|
\ \"trait\": [\n \"blessed\"\n ],\n \"level\": {\n \"min\":
|
||||||
|
0,\n \"max\": 3\n }\n }\n ]\n}"
|
||||||
GUID: eb96e6
|
GUID: eb96e6
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -44,86 +44,112 @@ end)(nil)
|
|||||||
__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
require("playercards/cards/FavoroftheMoon1")
|
require("playercards/cards/FavoroftheMoon1")
|
||||||
end)
|
end)
|
||||||
__bundle_register("playercards/cards/FavoroftheMoon1", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
VALID_TOKENS = {
|
|
||||||
["Curse"] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
SHOW_SINGLE_RELEASE = true
|
|
||||||
KEEP_OPEN = true
|
|
||||||
RESOLVE_TOKEN = true
|
|
||||||
|
|
||||||
require("playercards/CardsThatSealTokens")
|
|
||||||
end)
|
|
||||||
__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
|
||||||
do
|
do
|
||||||
local BlessCurseManagerApi = {}
|
local ChaosBagApi = {}
|
||||||
local guidReferenceApi = require("core/GUIDReferenceApi")
|
|
||||||
|
|
||||||
local function getManager()
|
-- respawns the chaos bag with a new state of tokens
|
||||||
return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager")
|
---@param tokenList table List of chaos token ids
|
||||||
|
ChaosBagApi.setChaosBagState = function(tokenList)
|
||||||
|
Global.call("setChaosBagState", tokenList)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- removes all taken tokens and resets the counts
|
-- returns a Table List of chaos token ids in the current chaos bag
|
||||||
BlessCurseManagerApi.removeTakenTokensAndReset = function()
|
-- requires copying the data into a new table because TTS is weird about handling table return values in Global
|
||||||
local BlessCurseManager = getManager()
|
ChaosBagApi.getChaosBagState = function()
|
||||||
Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05)
|
local chaosBagContentsCatcher = Global.call("getChaosBagState")
|
||||||
Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10)
|
local chaosBagContents = {}
|
||||||
Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15)
|
for _, v in ipairs(chaosBagContentsCatcher) do
|
||||||
|
table.insert(chaosBagContents, v)
|
||||||
|
end
|
||||||
|
return chaosBagContents
|
||||||
end
|
end
|
||||||
|
|
||||||
-- updates the internal count (called by cards that seal bless/curse tokens)
|
-- checks scripting zone for chaos bag (also called by a lot of objects!)
|
||||||
---@param type string Type of chaos token ("Bless" or "Curse")
|
ChaosBagApi.findChaosBag = function()
|
||||||
---@param guid string GUID of the token
|
return Global.call("findChaosBag")
|
||||||
BlessCurseManagerApi.sealedToken = function(type, guid)
|
|
||||||
getManager().call("sealedToken", { type = type, guid = guid })
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- updates the internal count (called by cards that seal bless/curse tokens)
|
-- returns a table of object references to the tokens in play (does not include sealed tokens!)
|
||||||
---@param type string Type of chaos token ("Bless" or "Curse")
|
ChaosBagApi.getTokensInPlay = function()
|
||||||
---@param guid string GUID of the token
|
return Global.call("getChaosTokensinPlay")
|
||||||
BlessCurseManagerApi.releasedToken = function(type, guid)
|
|
||||||
getManager().call("releasedToken", { type = type, guid = guid })
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- updates the internal count (called by cards that seal bless/curse tokens)
|
-- returns all sealed tokens on cards to the chaos bag
|
||||||
---@param type string Type of chaos token ("Bless" or "Curse")
|
|
||||||
---@param guid string GUID of the token
|
|
||||||
BlessCurseManagerApi.returnedToken = function(type, guid)
|
|
||||||
getManager().call("returnedToken", { type = type, guid = guid })
|
|
||||||
end
|
|
||||||
|
|
||||||
-- broadcasts the current status for bless/curse tokens
|
|
||||||
---@param playerColor string Color of the player to show the broadcast to
|
---@param playerColor string Color of the player to show the broadcast to
|
||||||
BlessCurseManagerApi.broadcastStatus = function(playerColor)
|
ChaosBagApi.releaseAllSealedTokens = function(playerColor)
|
||||||
getManager().call("broadcastStatus", playerColor)
|
Global.call("releaseAllSealedTokens", playerColor)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- removes all bless / curse tokens from the chaos bag and play
|
-- returns all drawn tokens to the chaos bag
|
||||||
---@param playerColor string Color of the player to show the broadcast to
|
ChaosBagApi.returnChaosTokens = function()
|
||||||
BlessCurseManagerApi.removeAll = function(playerColor)
|
Global.call("returnChaosTokens")
|
||||||
getManager().call("doRemove", playerColor)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- adds bless / curse sealing to the hovered card
|
-- removes the specified chaos token from the chaos bag
|
||||||
---@param playerColor string Color of the player to show the broadcast to
|
---@param id string ID of the chaos token
|
||||||
---@param hoveredObject tts__Object Hovered object
|
ChaosBagApi.removeChaosToken = function(id)
|
||||||
BlessCurseManagerApi.addBlurseSealingMenu = function(playerColor, hoveredObject)
|
Global.call("removeChaosToken", id)
|
||||||
getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject })
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return BlessCurseManagerApi
|
-- returns a chaos token to the bag and calls all relevant functions
|
||||||
|
---@param token tts__Object Chaos token to return
|
||||||
|
---@param fromBag boolean whether or not the token to return was in the middle of being drawn (true) or elsewhere (false)
|
||||||
|
ChaosBagApi.returnChaosTokenToBag = function(token, fromBag)
|
||||||
|
Global.call("returnChaosTokenToBag", { token = token, fromBag = fromBag })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- spawns the specified chaos token and puts it into the chaos bag
|
||||||
|
---@param id string ID of the chaos token
|
||||||
|
ChaosBagApi.spawnChaosToken = function(id)
|
||||||
|
Global.call("spawnChaosToken", id)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Checks to see if the chaos bag can be manipulated. If a player is searching the bag when tokens
|
||||||
|
-- are drawn or replaced a TTS bug can cause those tokens to vanish. Any functions which change the
|
||||||
|
-- contents of the bag should check this method before doing so.
|
||||||
|
-- This method will broadcast a message to all players if the bag is being searched.
|
||||||
|
---@return any: True if the bag is manipulated, false if it should be blocked.
|
||||||
|
ChaosBagApi.canTouchChaosTokens = function()
|
||||||
|
return Global.call("canTouchChaosTokens")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- draws a chaos token to a playermat
|
||||||
|
---@param mat tts__Object Playermat that triggered this
|
||||||
|
---@param drawAdditional boolean Controls whether additional tokens should be drawn
|
||||||
|
---@param tokenType? string Name of token (e.g. "Bless") to be drawn from the bag
|
||||||
|
---@param guidToBeResolved? string GUID of the sealed token to be resolved instead of drawing a token from the bag
|
||||||
|
---@param takeParameters? table Position and rotation of the location where the new token should be drawn to, usually to replace a returned token
|
||||||
|
---@return tts__Object: Object reference to the token that was drawn
|
||||||
|
ChaosBagApi.drawChaosToken = function(mat, drawAdditional, tokenType, guidToBeResolved, takeParameters)
|
||||||
|
return Global.call("drawChaosToken", {
|
||||||
|
mat = mat,
|
||||||
|
drawAdditional = drawAdditional,
|
||||||
|
tokenType = tokenType,
|
||||||
|
guidToBeResolved = guidToBeResolved,
|
||||||
|
takeParameters = takeParameters
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
-- returns a Table List of chaos token ids in the current chaos bag
|
||||||
|
-- requires copying the data into a new table because TTS is weird about handling table return values in Global
|
||||||
|
ChaosBagApi.getIdUrlMap = function()
|
||||||
|
return Global.getTable("ID_URL_MAP")
|
||||||
|
end
|
||||||
|
|
||||||
|
return ChaosBagApi
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("playermat/PlayermatApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
do
|
do
|
||||||
local PlaymatApi = {}
|
local PlayermatApi = {}
|
||||||
local guidReferenceApi = require("core/GUIDReferenceApi")
|
local guidReferenceApi = require("core/GUIDReferenceApi")
|
||||||
local searchLib = require("util/SearchLib")
|
local searchLib = require("util/SearchLib")
|
||||||
|
local localInvestigatorPosition = { x = -1.17, y = 1, z = -0.01 }
|
||||||
|
|
||||||
-- Convenience function to look up a mat's object by color, or get all mats.
|
-- Convenience function to look up a mat's object by color, or get all mats.
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@return table: Single-element if only single playmat is requested
|
---@return table: Single-element if only single playermat is requested
|
||||||
local function getMatForColor(matColor)
|
local function getMatForColor(matColor)
|
||||||
if matColor == "All" then
|
if matColor == "All" then
|
||||||
return guidReferenceApi.getObjectsByType("Playermat")
|
return guidReferenceApi.getObjectsByType("Playermat")
|
||||||
@ -132,9 +158,9 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the color of the closest playmat
|
-- Returns the color of the closest playermat
|
||||||
---@param startPos table Starting position to get the closest mat from
|
---@param startPos table Starting position to get the closest mat from
|
||||||
PlaymatApi.getMatColorByPosition = function(startPos)
|
PlayermatApi.getMatColorByPosition = function(startPos)
|
||||||
local result, smallestDistance
|
local result, smallestDistance
|
||||||
for matColor, mat in pairs(getMatForColor("All")) do
|
for matColor, mat in pairs(getMatForColor("All")) do
|
||||||
local distance = Vector.between(startPos, mat.getPosition()):magnitude()
|
local distance = Vector.between(startPos, mat.getPosition()):magnitude()
|
||||||
@ -146,17 +172,17 @@ do
|
|||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the color of the player's hand that is seated next to the playmat
|
-- Returns the color of the player's hand that is seated next to the playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.getPlayerColor = function(matColor)
|
PlayermatApi.getPlayerColor = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.getVar("playerColor")
|
return mat.getVar("playerColor")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the color of the playmat that owns the playercolor's hand
|
-- Returns the color of the playermat that owns the playercolor's hand
|
||||||
---@param handColor string Color of the playmat
|
---@param handColor string Color of the playermat
|
||||||
PlaymatApi.getMatColor = function(handColor)
|
PlayermatApi.getMatColor = function(handColor)
|
||||||
for matColor, mat in pairs(getMatForColor("All")) do
|
for matColor, mat in pairs(getMatForColor("All")) do
|
||||||
local playerColor = mat.getVar("playerColor")
|
local playerColor = mat.getVar("playerColor")
|
||||||
if playerColor == handColor then
|
if playerColor == handColor then
|
||||||
@ -165,41 +191,69 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat
|
-- Instructs a playermat to check for DES
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.isDES = function(matColor)
|
PlayermatApi.checkForDES = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.getVar("isDES")
|
mat.call("checkForDES")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Performs a search of the deck area of the requested playmat and returns the result as table
|
-- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.getDeckAreaObjects = function(matColor)
|
---@return boolean: whether DES is present on the playermat
|
||||||
|
PlayermatApi.hasDES = function(matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
return mat.getVar("hasDES")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- gets the slot data for the playermat
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
|
PlayermatApi.getSlotData = function(matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
return mat.getTable("slotData")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- sets the slot data for the playermat
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
|
---@param newSlotData table New slot data for the playermat
|
||||||
|
PlayermatApi.loadSlotData = function(matColor, newSlotData)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
mat.setTable("slotData", newSlotData)
|
||||||
|
mat.call("redrawSlotSymbols")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Performs a search of the deck area of the requested playermat and returns the result as table
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
|
PlayermatApi.getDeckAreaObjects = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.call("getDeckAreaObjects")
|
return mat.call("getDeckAreaObjects")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Flips the top card of the deck (useful after deck manipulation for Norman Withers)
|
-- Flips the top card of the deck (useful after deck manipulation for Norman Withers)
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.flipTopCardFromDeck = function(matColor)
|
PlayermatApi.flipTopCardFromDeck = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.call("flipTopCardFromDeck")
|
return mat.call("flipTopCardFromDeck")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the position of the discard pile of the requested playmat
|
-- Returns the position of the discard pile of the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.getDiscardPosition = function(matColor)
|
PlayermatApi.getDiscardPosition = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.call("returnGlobalDiscardPosition")
|
return mat.call("returnGlobalDiscardPosition")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the position of the draw pile of the requested playmat
|
-- Returns the position of the draw pile of the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.getDrawPosition = function(matColor)
|
PlayermatApi.getDrawPosition = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.call("returnGlobalDrawPosition")
|
return mat.call("returnGlobalDrawPosition")
|
||||||
end
|
end
|
||||||
@ -207,25 +261,25 @@ do
|
|||||||
|
|
||||||
-- Transforms a local position into a global position
|
-- Transforms a local position into a global position
|
||||||
---@param localPos table Local position to be transformed
|
---@param localPos table Local position to be transformed
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.transformLocalPosition = function(localPos, matColor)
|
PlayermatApi.transformLocalPosition = function(localPos, matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.positionToWorld(localPos)
|
return mat.positionToWorld(localPos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the rotation of the requested playmat
|
-- Returns the rotation of the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.returnRotation = function(matColor)
|
PlayermatApi.returnRotation = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.getRotation()
|
return mat.getRotation()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns a table with spawn data (position and rotation) for a helper object
|
-- Returns a table with spawn data (position and rotation) for a helper object
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@param helperName string Name of the helper object
|
---@param helperName string Name of the helper object
|
||||||
PlaymatApi.getHelperSpawnData = function(matColor, helperName)
|
PlayermatApi.getHelperSpawnData = function(matColor, helperName)
|
||||||
local resultTable = {}
|
local resultTable = {}
|
||||||
local localPositionTable = {
|
local localPositionTable = {
|
||||||
["Hand Helper"] = {0.05, 0, -1.182},
|
["Hand Helper"] = {0.05, 0, -1.182},
|
||||||
@ -242,82 +296,99 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Triggers the Upkeep for the requested playmat
|
-- Triggers the Upkeep for the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@param playerColor string Color of the calling player (for messages)
|
---@param playerColor string Color of the calling player (for messages)
|
||||||
PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor)
|
PlayermatApi.doUpkeepFromHotkey = function(matColor, playerColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("doUpkeepFromHotkey", playerColor)
|
mat.call("doUpkeepFromHotkey", playerColor)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Handles discarding for the requested playmat for the provided list of objects
|
-- Handles discarding for the requested playermat for the provided list of objects
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
---@param objList table List of objects to discard
|
---@param objList table List of objects to discard
|
||||||
PlaymatApi.discardListOfObjects = function(matColor, objList)
|
PlayermatApi.discardListOfObjects = function(matColor, objList)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("discardListOfObjects", objList)
|
mat.call("discardListOfObjects", objList)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the active investigator id
|
-- Returns the active investigator id
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.returnInvestigatorId = function(matColor)
|
PlayermatApi.returnInvestigatorId = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.getVar("activeInvestigatorId")
|
return mat.getVar("activeInvestigatorId")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Returns the class of the active investigator
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
|
PlayermatApi.returnInvestigatorClass = function(matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
return mat.getVar("activeInvestigatorClass")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Returns the position for encounter card drawing
|
-- Returns the position for encounter card drawing
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
---@param stack boolean If true, returns the leftmost position instead of the first empty from the right
|
---@param stack boolean If true, returns the leftmost position instead of the first empty from the right
|
||||||
PlaymatApi.getEncounterCardDrawPosition = function(matColor, stack)
|
PlayermatApi.getEncounterCardDrawPosition = function(matColor, stack)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return Vector(mat.call("getEncounterCardDrawPosition", stack))
|
return Vector(mat.call("getEncounterCardDrawPosition", stack))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sets the requested playmat's snap points to limit snapping to matching card types or not. If
|
-- Sets the requested playermat's snap points to limit snapping to matching card types or not. If
|
||||||
-- matchTypes is true, the main card slot snap points will only snap assets, while the
|
-- matchTypes is true, the main card slot snap points will only snap assets, while the
|
||||||
-- investigator area point will only snap Investigators. If matchTypes is false, snap points will
|
-- investigator area point will only snap Investigators. If matchTypes is false, snap points will
|
||||||
-- be reset to snap all cards.
|
-- be reset to snap all cards.
|
||||||
---@param matchCardTypes boolean Whether snap points should only snap for the matching card types
|
---@param matchCardTypes boolean Whether snap points should only snap for the matching card types
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor)
|
PlayermatApi.setLimitSnapsByType = function(matchCardTypes, matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("setLimitSnapsByType", matchCardTypes)
|
mat.call("setLimitSnapsByType", matchCardTypes)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sets the requested playmat's draw 1 button to visible
|
-- Sets the requested playermat's draw 1 button to visible
|
||||||
---@param isDrawButtonVisible boolean Whether the draw 1 button should be visible or not
|
---@param isDrawButtonVisible boolean Whether the draw 1 button should be visible or not
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor)
|
PlayermatApi.showDrawButton = function(isDrawButtonVisible, matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("showDrawButton", isDrawButtonVisible)
|
mat.call("showDrawButton", isDrawButtonVisible)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Shows or hides the clickable clue counter for the requested playmat
|
-- Shows or hides the clickable clue counter for the requested playermat
|
||||||
---@param showCounter boolean Whether the clickable counter should be present or not
|
---@param showCounter boolean Whether the clickable counter should be present or not
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.clickableClues = function(showCounter, matColor)
|
PlayermatApi.clickableClues = function(showCounter, matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("clickableClues", showCounter)
|
mat.call("clickableClues", showCounter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat
|
-- Toggles the use of class textures for the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param state boolean Whether the class texture should be used or not
|
||||||
PlaymatApi.removeClues = function(matColor)
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
|
PlayermatApi.useClassTexture = function(state, matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
mat.call("useClassTexture", state)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
|
PlayermatApi.removeClues = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("removeClues")
|
mat.call("removeClues")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reports the clue count for the requested playmat
|
-- Reports the clue count for the requested playermat
|
||||||
---@param useClickableCounters boolean Controls which type of counter is getting checked
|
---@param useClickableCounters boolean Controls which type of counter is getting checked
|
||||||
PlaymatApi.getClueCount = function(useClickableCounters, matColor)
|
PlayermatApi.getClueCount = function(useClickableCounters, matColor)
|
||||||
local count = 0
|
local count = 0
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
count = count + mat.call("getClueCount", useClickableCounters)
|
count = count + mat.call("getClueCount", useClickableCounters)
|
||||||
@ -326,37 +397,36 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Updates the specified owned counter
|
-- Updates the specified owned counter
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@param type string Counter to target
|
---@param type string Counter to target
|
||||||
---@param newValue number Value to set the counter to
|
---@param newValue number Value to set the counter to
|
||||||
---@param modifier number If newValue is not provided, the existing value will be adjusted by this modifier
|
---@param modifier number If newValue is not provided, the existing value will be adjusted by this modifier
|
||||||
PlaymatApi.updateCounter = function(matColor, type, newValue, modifier)
|
PlayermatApi.updateCounter = function(matColor, type, newValue, modifier)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier })
|
mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Triggers the draw function for the specified playmat
|
-- Triggers the draw function for the specified playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@param number number Amount of cards to draw
|
---@param number number Amount of cards to draw
|
||||||
PlaymatApi.drawCardsWithReshuffle = function(matColor, number)
|
PlayermatApi.drawCardsWithReshuffle = function(matColor, number)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("drawCardsWithReshuffle", number)
|
mat.call("drawCardsWithReshuffle", number)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the resource counter amount
|
-- Returns the resource counter amount
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
---@param type string Counter to target
|
---@param type string Counter to target
|
||||||
PlaymatApi.getCounterValue = function(matColor, type)
|
PlayermatApi.getCounterValue = function(matColor, type)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.call("getCounterValue", type)
|
return mat.call("getCounterValue", type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns a list of mat colors that have an investigator placed
|
-- Returns a list of mat colors that have an investigator placed
|
||||||
PlaymatApi.getUsedMatColors = function()
|
PlayermatApi.getUsedMatColors = function()
|
||||||
local localInvestigatorPosition = { x = -1.17, y = 1, z = -0.01 }
|
|
||||||
local usedColors = {}
|
local usedColors = {}
|
||||||
for matColor, mat in pairs(getMatForColor("All")) do
|
for matColor, mat in pairs(getMatForColor("All")) do
|
||||||
local searchPos = mat.positionToWorld(localInvestigatorPosition)
|
local searchPos = mat.positionToWorld(localInvestigatorPosition)
|
||||||
@ -368,18 +438,39 @@ do
|
|||||||
return usedColors
|
return usedColors
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Returns investigator name
|
||||||
|
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
||||||
|
PlayermatApi.getInvestigatorName = function(matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
local searchPos = mat.positionToWorld(localInvestigatorPosition)
|
||||||
|
local searchResult = searchLib.atPosition(searchPos, "isCardOrDeck")
|
||||||
|
if #searchResult == 1 then
|
||||||
|
return searchResult[1].getName()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
-- Resets the specified skill tracker to "1, 1, 1, 1"
|
-- Resets the specified skill tracker to "1, 1, 1, 1"
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.resetSkillTracker = function(matColor)
|
PlayermatApi.resetSkillTracker = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("resetSkillTracker")
|
mat.call("resetSkillTracker")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Finds all objects on the playmat and associated set aside zone and returns a table
|
-- Redraws the XML for the slot symbols based on the slotData table
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
|
PlayermatApi.redrawSlotSymbols = function(matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
mat.call("redrawSlotSymbols")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Finds all objects on the playermat and associated set aside zone and returns a table
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@param filter string Name of the filte function (see util/SearchLib)
|
---@param filter string Name of the filte function (see util/SearchLib)
|
||||||
PlaymatApi.searchAroundPlaymat = function(matColor, filter)
|
PlayermatApi.searchAroundPlayermat = function(matColor, filter)
|
||||||
local objList = {}
|
local objList = {}
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do
|
for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do
|
||||||
@ -390,33 +481,33 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Discard a non-hidden card from the corresponding player's hand
|
-- Discard a non-hidden card from the corresponding player's hand
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.doDiscardOne = function(matColor)
|
PlayermatApi.doDiscardOne = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("doDiscardOne")
|
mat.call("doDiscardOne")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Triggers the metadata sync for all playmats
|
-- Triggers the metadata sync for all playermats
|
||||||
PlaymatApi.syncAllCustomizableCards = function()
|
PlayermatApi.syncAllCustomizableCards = function()
|
||||||
for _, mat in pairs(getMatForColor("All")) do
|
for _, mat in pairs(getMatForColor("All")) do
|
||||||
mat.call("syncAllCustomizableCards")
|
mat.call("syncAllCustomizableCards")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return PlaymatApi
|
return PlayermatApi
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
__bundle_register("util/SearchLib", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("util/SearchLib", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
do
|
do
|
||||||
local SearchLib = {}
|
local SearchLib = {}
|
||||||
local filterFunctions = {
|
local filterFunctions = {
|
||||||
isActionToken = function(x) return x.getDescription() == "Action Token" end,
|
|
||||||
isCard = function(x) return x.type == "Card" end,
|
isCard = function(x) return x.type == "Card" end,
|
||||||
isDeck = function(x) return x.type == "Deck" end,
|
isDeck = function(x) return x.type == "Deck" end,
|
||||||
isCardOrDeck = function(x) return x.type == "Card" or x.type == "Deck" end,
|
isCardOrDeck = function(x) return x.type == "Card" or x.type == "Deck" end,
|
||||||
isClue = function(x) return x.memo == "clueDoom" and x.is_face_down == false end,
|
isClue = function(x) return x.memo == "clueDoom" and x.is_face_down == false end,
|
||||||
isTileOrToken = function(x) return x.type == "Tile" end
|
isTileOrToken = function(x) return x.type == "Tile" end,
|
||||||
|
isUniversalToken = function(x) return x.getMemo() == "universalActionAbility" end,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- performs the actual search and returns a filtered list of object references
|
-- performs the actual search and returns a filtered list of object references
|
||||||
@ -440,7 +531,7 @@ do
|
|||||||
max_distance = maxDistance or 0
|
max_distance = maxDistance or 0
|
||||||
})
|
})
|
||||||
|
|
||||||
-- filtering the result
|
-- filter the result for matching objects
|
||||||
local objList = {}
|
local objList = {}
|
||||||
for _, v in ipairs(searchResult) do
|
for _, v in ipairs(searchResult) do
|
||||||
if not filter or filterFunc(v.hit_object) then
|
if not filter or filterFunc(v.hit_object) then
|
||||||
@ -457,32 +548,53 @@ do
|
|||||||
|
|
||||||
-- searches the area on an object
|
-- searches the area on an object
|
||||||
SearchLib.onObject = function(obj, filter)
|
SearchLib.onObject = function(obj, filter)
|
||||||
pos = obj.getPosition()
|
local pos = obj.getPosition()
|
||||||
size = obj.getBounds().size:setAt("y", 1)
|
local size = obj.getBounds().size:setAt("y", 1)
|
||||||
return returnSearchResult(pos, _, size, filter)
|
return returnSearchResult(pos, _, size, filter)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- searches the specified position (a single point)
|
-- searches the specified position (a single point)
|
||||||
SearchLib.atPosition = function(pos, filter)
|
SearchLib.atPosition = function(pos, filter)
|
||||||
size = { 0.1, 2, 0.1 }
|
local size = { 0.1, 2, 0.1 }
|
||||||
return returnSearchResult(pos, _, size, filter)
|
return returnSearchResult(pos, _, size, filter)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- searches below the specified position (downwards until y = 0)
|
-- searches below the specified position (downwards until y = 0)
|
||||||
SearchLib.belowPosition = function(pos, filter)
|
SearchLib.belowPosition = function(pos, filter)
|
||||||
direction = { 0, -1, 0 }
|
local size = { 0.1, 2, 0.1 }
|
||||||
maxDistance = pos.y
|
local direction = { 0, -1, 0 }
|
||||||
|
local maxDistance = pos.y
|
||||||
return returnSearchResult(pos, _, size, filter, direction, maxDistance)
|
return returnSearchResult(pos, _, size, filter, direction, maxDistance)
|
||||||
end
|
end
|
||||||
|
|
||||||
return SearchLib
|
return SearchLib
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
__bundle_register("playercards/cards/FavoroftheMoon1", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
VALID_TOKENS = {
|
||||||
|
["Curse"] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
KEEP_OPEN = true
|
||||||
|
MAX_SEALED = 3
|
||||||
|
RESOLVE_TOKEN = true
|
||||||
|
|
||||||
|
require("playercards/CardsThatSealTokens")
|
||||||
|
end)
|
||||||
__bundle_register("playercards/CardsThatSealTokens", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("playercards/CardsThatSealTokens", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
--[[ Library for cards that seal tokens
|
--[[ Library for cards that seal tokens
|
||||||
This file is used to add sealing option to cards' context menu.
|
This file is used to add sealing option to cards' context menu.
|
||||||
|
NOTE: all cards are allowed to release a single token to enable Hallow and A Watchful Peace,
|
||||||
|
and to release all sealed tokens to allow for cards that might leave play with sealed tokens on them.
|
||||||
Valid options (set before requiring this file):
|
Valid options (set before requiring this file):
|
||||||
|
|
||||||
|
MAX_SEALED --@type: number (maximum number of tokens allowable by the card to be sealed)
|
||||||
|
- required for all cards
|
||||||
|
- if MAX_SEALED is more than 1, then an XML label is created for the topmost token indicating the number of sealed tokens
|
||||||
|
- gives an error if user tries to seal additional tokens on the card
|
||||||
|
- example usage: "The Chthonian Stone"
|
||||||
|
> MAX_SEALED = 1
|
||||||
|
|
||||||
UPDATE_ON_HOVER --@type: boolean
|
UPDATE_ON_HOVER --@type: boolean
|
||||||
- automatically updates the context menu options when the card is hovered
|
- automatically updates the context menu options when the card is hovered
|
||||||
- the "Read Bag" function reads the content of the chaos bag to update the context menu
|
- the "Read Bag" function reads the content of the chaos bag to update the context menu
|
||||||
@ -493,19 +605,16 @@ KEEP_OPEN --@type: boolean
|
|||||||
- makes the context menu stay open after selecting an option
|
- makes the context menu stay open after selecting an option
|
||||||
- example usage: "Unrelenting"
|
- example usage: "Unrelenting"
|
||||||
|
|
||||||
SHOW_SINGLE_RELEASE --@type: boolean
|
SHOW_MULTI_RELEASE --@type: number (maximum amount of tokens to release at once)
|
||||||
- enables an entry in the context menu
|
- enables an entry in the context menu
|
||||||
- this entry allows releasing a single token
|
- this entry allows releasing of multiple tokens at once, to the maximum number
|
||||||
- example usage: "Holy Spear" (to keep the other tokens and just release one)
|
- does not fail if there are fewer than the maximum sealed
|
||||||
|
- example usage: "Nephthys" (to release up to 3 bless tokens at once)
|
||||||
SHOW_MULTI_RELEASE --@type: number (amount of tokens to release at once)
|
|
||||||
- enables an entry in the context menu
|
|
||||||
- this entry allows releasing of multiple tokens at once
|
|
||||||
- example usage: "Nephthys" (to release 3 bless tokens at once)
|
|
||||||
|
|
||||||
SHOW_MULTI_RETURN --@type: number (amount of tokens to return to pool at once)
|
SHOW_MULTI_RETURN --@type: number (amount of tokens to return to pool at once)
|
||||||
- enables an entry in the context menu
|
- enables an entry in the context menu
|
||||||
- this entry allows returning tokens to the token pool
|
- this entry allows returning tokens to the token pool
|
||||||
|
- fails if not enough tokens are sealed
|
||||||
- example usage: "Nephthys" (to return 3 bless tokens at once)
|
- example usage: "Nephthys" (to return 3 bless tokens at once)
|
||||||
|
|
||||||
SHOW_MULTI_SEAL --@type: number (amount of tokens to seal at once)
|
SHOW_MULTI_SEAL --@type: number (amount of tokens to seal at once)
|
||||||
@ -539,6 +648,7 @@ Thus it should be implemented like this:
|
|||||||
> ["+1"] = true,
|
> ["+1"] = true,
|
||||||
> ["Elder Sign"] = true
|
> ["Elder Sign"] = true
|
||||||
> }
|
> }
|
||||||
|
> MAX_SEALED = 1
|
||||||
> require...
|
> require...
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
Example 2: Holy Spear
|
Example 2: Holy Spear
|
||||||
@ -549,21 +659,35 @@ Thus it should be implemented like this:
|
|||||||
> VALID_TOKENS = {
|
> VALID_TOKENS = {
|
||||||
> ["Bless"] = true
|
> ["Bless"] = true
|
||||||
> }
|
> }
|
||||||
> SHOW_SINGLE_RELEASE = true
|
|
||||||
> SHOW_MULTI_SEAL = 2
|
> SHOW_MULTI_SEAL = 2
|
||||||
|
> MAX_SEALED = 10
|
||||||
> require...
|
> require...
|
||||||
----------------------------------------------------------]]
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi")
|
local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi")
|
||||||
local chaosBagApi = require("chaosbag/ChaosBagApi")
|
local chaosBagApi = require("chaosbag/ChaosBagApi")
|
||||||
local guidReferenceApi = require("core/GUIDReferenceApi")
|
local guidReferenceApi = require("core/GUIDReferenceApi")
|
||||||
local playmatApi = require("playermat/PlaymatApi")
|
local playermatApi = require("playermat/PlayermatApi")
|
||||||
local tokenArrangerApi = require("accessories/TokenArrangerApi")
|
local tokenArrangerApi = require("accessories/TokenArrangerApi")
|
||||||
|
|
||||||
local sealedTokens = {}
|
local sealedTokens = {}
|
||||||
local ID_URL_MAP = {}
|
local ID_URL_MAP = {}
|
||||||
local tokensInBag = {}
|
local tokensInBag = {}
|
||||||
|
|
||||||
|
-- XML background color for each token for label when stacked
|
||||||
|
local tokenColor = {
|
||||||
|
["Skull"] = "#4A0400E6",
|
||||||
|
["Cultist"] = "#173B0BE6",
|
||||||
|
["Tablet"] = "#1D2238E6",
|
||||||
|
["Elder Thing"] = "#4D2331E6",
|
||||||
|
["Auto-fail"] = "#9B0004E6",
|
||||||
|
["Bless"] = "#9D702CE6",
|
||||||
|
["Curse"] = "#633A84E6",
|
||||||
|
["Frost"] = "#404450E6",
|
||||||
|
["Elder Sign"] = "#50A8CEE6",
|
||||||
|
[""] = "#77674DE6"
|
||||||
|
}
|
||||||
|
|
||||||
function onSave() return JSON.encode(sealedTokens) end
|
function onSave() return JSON.encode(sealedTokens) end
|
||||||
|
|
||||||
function onLoad(savedData)
|
function onLoad(savedData)
|
||||||
@ -575,13 +699,15 @@ end
|
|||||||
|
|
||||||
-- builds the context menu
|
-- builds the context menu
|
||||||
function generateContextMenu()
|
function generateContextMenu()
|
||||||
-- conditional single or multi release options
|
self.addContextMenuItem("Release one token", releaseOneToken)
|
||||||
if SHOW_SINGLE_RELEASE then
|
|
||||||
self.addContextMenuItem("Release token", releaseOneToken)
|
-- conditional release options
|
||||||
elseif SHOW_MULTI_RELEASE then
|
if MAX_SEALED > 1 then
|
||||||
|
self.addContextMenuItem("Release all tokens", releaseAllTokens)
|
||||||
|
end
|
||||||
|
|
||||||
|
if SHOW_MULTI_RELEASE then
|
||||||
self.addContextMenuItem("Release " .. SHOW_MULTI_RELEASE .. " token(s)", releaseMultipleTokens)
|
self.addContextMenuItem("Release " .. SHOW_MULTI_RELEASE .. " token(s)", releaseMultipleTokens)
|
||||||
else
|
|
||||||
self.addContextMenuItem("Release token(s)", releaseAllTokens)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if RESOLVE_TOKEN then
|
if RESOLVE_TOKEN then
|
||||||
@ -619,7 +745,7 @@ function generateContextMenu()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if allowed then
|
if allowed then
|
||||||
for i = 1, SHOW_MULTI_SEAL do
|
for i = SHOW_MULTI_SEAL, 1, -1 do
|
||||||
sealToken(map.name, playerColor)
|
sealToken(map.name, playerColor)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -656,6 +782,10 @@ end
|
|||||||
|
|
||||||
-- seals the named token on this card
|
-- seals the named token on this card
|
||||||
function sealToken(name, playerColor)
|
function sealToken(name, playerColor)
|
||||||
|
if #sealedTokens >= MAX_SEALED then
|
||||||
|
printToColor("Cannot seal any more tokens on this card", playerColor, "Red")
|
||||||
|
return
|
||||||
|
end
|
||||||
if not chaosBagApi.canTouchChaosTokens() then return end
|
if not chaosBagApi.canTouchChaosTokens() then return end
|
||||||
local chaosbag = chaosBagApi.findChaosBag()
|
local chaosbag = chaosBagApi.findChaosBag()
|
||||||
for i, obj in ipairs(chaosbag.getObjects()) do
|
for i, obj in ipairs(chaosbag.getObjects()) do
|
||||||
@ -672,6 +802,16 @@ function sealToken(name, playerColor)
|
|||||||
if name == "Bless" or name == "Curse" then
|
if name == "Bless" or name == "Curse" then
|
||||||
blessCurseManagerApi.sealedToken(name, guid)
|
blessCurseManagerApi.sealedToken(name, guid)
|
||||||
end
|
end
|
||||||
|
-- destroy XML on just covered token
|
||||||
|
if #sealedTokens > 1 then
|
||||||
|
local coveredToken = getObjectFromGUID(sealedTokens[#sealedTokens - 1])
|
||||||
|
if coveredToken ~= nil then
|
||||||
|
coveredToken.UI.setXml("")
|
||||||
|
else
|
||||||
|
table.remove(sealedTokens, #sealedTokens - 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
updateStackSize()
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@ -691,16 +831,22 @@ function releaseOneToken(playerColor)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- release multiple tokens at once
|
-- release up to multiple tokens at once with no minimum
|
||||||
function releaseMultipleTokens(playerColor)
|
function releaseMultipleTokens(playerColor)
|
||||||
if SHOW_MULTI_RELEASE <= #sealedTokens then
|
if #sealedTokens == 0 then
|
||||||
for i = 1, SHOW_MULTI_RELEASE do
|
printToColor("Not enough tokens sealed.", playerColor)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local numRemoved = SHOW_MULTI_RELEASE
|
||||||
|
if #sealedTokens < SHOW_MULTI_RELEASE then
|
||||||
|
numRemoved = #sealedTokens
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, numRemoved do
|
||||||
putTokenAway(table.remove(sealedTokens))
|
putTokenAway(table.remove(sealedTokens))
|
||||||
end
|
end
|
||||||
printToColor("Releasing " .. SHOW_MULTI_RELEASE .. " tokens", playerColor)
|
printToColor("Releasing " .. numRemoved .. " tokens", playerColor)
|
||||||
else
|
|
||||||
printToColor("Not enough tokens sealed.", playerColor)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- releases all sealed tokens
|
-- releases all sealed tokens
|
||||||
@ -741,6 +887,7 @@ function putTokenAway(guid)
|
|||||||
if name == "Bless" or name == "Curse" then
|
if name == "Bless" or name == "Curse" then
|
||||||
blessCurseManagerApi.releasedToken(name, guid)
|
blessCurseManagerApi.releasedToken(name, guid)
|
||||||
end
|
end
|
||||||
|
updateStackSize()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns the token to the pool (== removes it)
|
-- returns the token to the pool (== removes it)
|
||||||
@ -753,6 +900,7 @@ function returnToken(guid)
|
|||||||
if name == "Bless" or name == "Curse" then
|
if name == "Bless" or name == "Curse" then
|
||||||
blessCurseManagerApi.returnedToken(name, guid)
|
blessCurseManagerApi.returnedToken(name, guid)
|
||||||
end
|
end
|
||||||
|
updateStackSize()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- resolves sealed token as if it came from the chaos bag
|
-- resolves sealed token as if it came from the chaos bag
|
||||||
@ -761,11 +909,47 @@ function resolveSealed()
|
|||||||
broadcastToAll("No tokens sealed.", "Red")
|
broadcastToAll("No tokens sealed.", "Red")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local closestMatColor = playmatApi.getMatColorByPosition(self.getPosition())
|
local closestMatColor = playermatApi.getMatColorByPosition(self.getPosition())
|
||||||
local mat = guidReferenceApi.getObjectByOwnerAndType(closestMatColor, "Playermat")
|
local mat = guidReferenceApi.getObjectByOwnerAndType(closestMatColor, "Playermat")
|
||||||
local guidToBeResolved = table.remove(sealedTokens)
|
local guidToBeResolved = table.remove(sealedTokens)
|
||||||
|
local resolvedToken = getObjectFromGUID(guidToBeResolved)
|
||||||
|
resolvedToken.UI.setXml("")
|
||||||
|
updateStackSize()
|
||||||
chaosBagApi.drawChaosToken(mat, true, _, guidToBeResolved)
|
chaosBagApi.drawChaosToken(mat, true, _, guidToBeResolved)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function updateStackSize()
|
||||||
|
if MAX_SEALED == 1 then return end
|
||||||
|
if #sealedTokens == 0 then return end
|
||||||
|
-- get topmost sealed token
|
||||||
|
local topToken = getObjectFromGUID(sealedTokens[#sealedTokens])
|
||||||
|
local name = topToken.getName()
|
||||||
|
|
||||||
|
topToken.UI.setXmlTable({
|
||||||
|
{
|
||||||
|
tag = "Panel",
|
||||||
|
attributes = {
|
||||||
|
height = 380,
|
||||||
|
width = 380,
|
||||||
|
rotation = "0 0 180",
|
||||||
|
scale = "0.2 0.2 1",
|
||||||
|
position = "0 0 -12",
|
||||||
|
color = tokenColor[name] or "#77674DE6"
|
||||||
|
},
|
||||||
|
children = {
|
||||||
|
tag = "Text",
|
||||||
|
attributes = {
|
||||||
|
fontSize = "380",
|
||||||
|
font = "font_teutonic-arkham",
|
||||||
|
color = "#ffffff",
|
||||||
|
outline = "#000000",
|
||||||
|
outlineSize = "8 -8",
|
||||||
|
text = "x" .. #sealedTokens
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
do
|
do
|
||||||
@ -801,92 +985,81 @@ do
|
|||||||
return TokenArrangerApi
|
return TokenArrangerApi
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
__bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
do
|
do
|
||||||
local ChaosBagApi = {}
|
local BlessCurseManagerApi = {}
|
||||||
|
local guidReferenceApi = require("core/GUIDReferenceApi")
|
||||||
|
|
||||||
-- respawns the chaos bag with a new state of tokens
|
local function getManager()
|
||||||
---@param tokenList table List of chaos token ids
|
return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager")
|
||||||
ChaosBagApi.setChaosBagState = function(tokenList)
|
|
||||||
return Global.call("setChaosBagState", tokenList)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns a Table List of chaos token ids in the current chaos bag
|
-- removes all taken tokens and resets the counts
|
||||||
-- requires copying the data into a new table because TTS is weird about handling table return values in Global
|
BlessCurseManagerApi.removeTakenTokensAndReset = function()
|
||||||
ChaosBagApi.getChaosBagState = function()
|
local BlessCurseManager = getManager()
|
||||||
local chaosBagContentsCatcher = Global.call("getChaosBagState")
|
Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05)
|
||||||
local chaosBagContents = {}
|
Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10)
|
||||||
for _, v in ipairs(chaosBagContentsCatcher) do
|
Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15)
|
||||||
table.insert(chaosBagContents, v)
|
|
||||||
end
|
|
||||||
return chaosBagContents
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- checks scripting zone for chaos bag (also called by a lot of objects!)
|
-- updates the internal count (called by cards that seal bless/curse tokens)
|
||||||
ChaosBagApi.findChaosBag = function()
|
---@param type string Type of chaos token ("Bless" or "Curse")
|
||||||
return Global.call("findChaosBag")
|
---@param guid string GUID of the token
|
||||||
|
BlessCurseManagerApi.sealedToken = function(type, guid)
|
||||||
|
getManager().call("sealedToken", { type = type, guid = guid })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns a table of object references to the tokens in play (does not include sealed tokens!)
|
-- updates the internal count (called by cards that seal bless/curse tokens)
|
||||||
ChaosBagApi.getTokensInPlay = function()
|
---@param type string Type of chaos token ("Bless" or "Curse")
|
||||||
return Global.call("getChaosTokensinPlay")
|
---@param guid string GUID of the token
|
||||||
|
---@param fromBag? boolean Whether or not token was just drawn from the chaos bag
|
||||||
|
BlessCurseManagerApi.releasedToken = function(type, guid, fromBag)
|
||||||
|
getManager().call("releasedToken", { type = type, guid = guid, fromBag = fromBag })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns all sealed tokens on cards to the chaos bag
|
-- updates the internal count (called by cards that seal bless/curse tokens)
|
||||||
|
---@param type string Type of chaos token ("Bless" or "Curse")
|
||||||
|
---@param guid string GUID of the token
|
||||||
|
BlessCurseManagerApi.returnedToken = function(type, guid)
|
||||||
|
getManager().call("returnedToken", { type = type, guid = guid })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- broadcasts the current status for bless/curse tokens
|
||||||
---@param playerColor string Color of the player to show the broadcast to
|
---@param playerColor string Color of the player to show the broadcast to
|
||||||
ChaosBagApi.releaseAllSealedTokens = function(playerColor)
|
BlessCurseManagerApi.broadcastStatus = function(playerColor)
|
||||||
return Global.call("releaseAllSealedTokens", playerColor)
|
getManager().call("broadcastStatus", playerColor)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns all drawn tokens to the chaos bag
|
-- removes all bless / curse tokens from the chaos bag and play
|
||||||
ChaosBagApi.returnChaosTokens = function()
|
---@param playerColor string Color of the player to show the broadcast to
|
||||||
return Global.call("returnChaosTokens")
|
BlessCurseManagerApi.removeAll = function(playerColor)
|
||||||
|
getManager().call("doRemove", playerColor)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- removes the specified chaos token from the chaos bag
|
-- adds bless / curse sealing to the hovered card
|
||||||
---@param id string ID of the chaos token
|
---@param playerColor string Color of the player to show the broadcast to
|
||||||
ChaosBagApi.removeChaosToken = function(id)
|
---@param hoveredObject tts__Object Hovered object
|
||||||
return Global.call("removeChaosToken", id)
|
BlessCurseManagerApi.addBlurseSealingMenu = function(playerColor, hoveredObject)
|
||||||
|
getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns a chaos token to the bag and calls all relevant functions
|
-- adds bless / curse to the chaos bag
|
||||||
---@param token tts__Object Chaos token to return
|
---@param type string Type of chaos token ("Bless" or "Curse")
|
||||||
ChaosBagApi.returnChaosTokenToBag = function(token)
|
BlessCurseManagerApi.addToken = function(type)
|
||||||
return Global.call("returnChaosTokenToBag", token)
|
getManager().call("addToken", type)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- spawns the specified chaos token and puts it into the chaos bag
|
-- removes bless / curse from the chaos bag
|
||||||
---@param id string ID of the chaos token
|
---@param type string Type of chaos token ("Bless" or "Curse")
|
||||||
ChaosBagApi.spawnChaosToken = function(id)
|
BlessCurseManagerApi.removeToken = function(type)
|
||||||
return Global.call("spawnChaosToken", id)
|
getManager().call("removeToken", type)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Checks to see if the chaos bag can be manipulated. If a player is searching the bag when tokens
|
BlessCurseManagerApi.getBlessCurseInBag = function()
|
||||||
-- are drawn or replaced a TTS bug can cause those tokens to vanish. Any functions which change the
|
return getManager().call("getBlessCurseInBag", {})
|
||||||
-- contents of the bag should check this method before doing so.
|
|
||||||
-- This method will broadcast a message to all players if the bag is being searched.
|
|
||||||
---@return any canTouch True if the bag is manipulated, false if it should be blocked.
|
|
||||||
ChaosBagApi.canTouchChaosTokens = function()
|
|
||||||
return Global.call("canTouchChaosTokens")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- called by playermats (by the "Draw chaos token" button)
|
return BlessCurseManagerApi
|
||||||
---@param mat tts__Object Playermat that triggered this
|
|
||||||
---@param drawAdditional boolean Controls whether additional tokens should be drawn
|
|
||||||
---@param tokenType? string Name of token (e.g. "Bless") to be drawn from the bag
|
|
||||||
---@param guidToBeResolved? string GUID of the sealed token to be resolved instead of drawing a token from the bag
|
|
||||||
---@param returnedToken? tts__Object Token to be replaced with newly drawn token
|
|
||||||
ChaosBagApi.drawChaosToken = function(mat, drawAdditional, tokenType, guidToBeResolved, returnedToken)
|
|
||||||
return Global.call("drawChaosToken", {mat = mat, drawAdditional = drawAdditional, tokenType = tokenType, guidToBeResolved = guidToBeResolved, returnedToken = returnedToken})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- returns a Table List of chaos token ids in the current chaos bag
|
|
||||||
-- requires copying the data into a new table because TTS is weird about handling table return values in Global
|
|
||||||
ChaosBagApi.getIdUrlMap = function()
|
|
||||||
return Global.getTable("ID_URL_MAP")
|
|
||||||
end
|
|
||||||
|
|
||||||
return ChaosBagApi
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -20,8 +20,7 @@ CustomDeck:
|
|||||||
Description: Advanced
|
Description: Advanced
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90051\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"90051\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"traits\": \"Endtimes.\",\n \"weakness\": true,\n \"cycle\": \"The Dunwich
|
\ \"traits\": \"Endtimes.\",\n \"weakness\": true,\n \"cycle\": \"Laid to Rest\"\n}"
|
||||||
Legacy\"\n}"
|
|
||||||
GUID: '561775'
|
GUID: '561775'
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,7 +22,7 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"04003\",\n \"type\": \"Investigator\",\n \"class\": \"Rogue\",\n
|
GMNotes: "{\n \"id\": \"04003\",\n \"type\": \"Investigator\",\n \"class\": \"Rogue\",\n
|
||||||
\ \"traits\": \"Criminal.\",\n \"willpowerIcons\": 1,\n \"intellectIcons\": 4,\n
|
\ \"traits\": \"Criminal.\",\n \"willpowerIcons\": 1,\n \"intellectIcons\": 4,\n
|
||||||
\ \"combatIcons\": 3,\n \"agilityIcons\": 4,\n \"cycle\": \"The Forgotten Age\",\n
|
\ \"combatIcons\": 3,\n \"agilityIcons\": 4,\n \"cycle\": \"The Forgotten Age\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Evade\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
1,\n \"signatures\": [\n {\n \"04010\": 1\n },\n {\n \"04011\":
|
1,\n \"signatures\": [\n {\n \"04010\": 1\n },\n {\n \"04011\":
|
||||||
1\n },\n {\n \"04012\": 1\n }\n ]\n },\n \"deck_options\":
|
1\n },\n {\n \"04012\": 1\n }\n ]\n },\n \"deck_options\":
|
||||||
[\n {\n \"trait\": [\n \"illicit\"\n ],\n \"level\": {\n
|
[\n {\n \"trait\": [\n \"illicit\"\n ],\n \"level\": {\n
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -49,71 +49,11 @@ VALID_TOKENS = {
|
|||||||
["Curse"] = true
|
["Curse"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
SHOW_SINGLE_RELEASE = true
|
MAX_SEALED = 10
|
||||||
KEEP_OPEN = true
|
KEEP_OPEN = true
|
||||||
|
|
||||||
require("playercards/CardsThatSealTokens")
|
require("playercards/CardsThatSealTokens")
|
||||||
end)
|
end)
|
||||||
__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
|
||||||
do
|
|
||||||
local BlessCurseManagerApi = {}
|
|
||||||
local guidReferenceApi = require("core/GUIDReferenceApi")
|
|
||||||
|
|
||||||
local function getManager()
|
|
||||||
return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- removes all taken tokens and resets the counts
|
|
||||||
BlessCurseManagerApi.removeTakenTokensAndReset = function()
|
|
||||||
local BlessCurseManager = getManager()
|
|
||||||
Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05)
|
|
||||||
Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10)
|
|
||||||
Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- updates the internal count (called by cards that seal bless/curse tokens)
|
|
||||||
---@param type string Type of chaos token ("Bless" or "Curse")
|
|
||||||
---@param guid string GUID of the token
|
|
||||||
BlessCurseManagerApi.sealedToken = function(type, guid)
|
|
||||||
getManager().call("sealedToken", { type = type, guid = guid })
|
|
||||||
end
|
|
||||||
|
|
||||||
-- updates the internal count (called by cards that seal bless/curse tokens)
|
|
||||||
---@param type string Type of chaos token ("Bless" or "Curse")
|
|
||||||
---@param guid string GUID of the token
|
|
||||||
BlessCurseManagerApi.releasedToken = function(type, guid)
|
|
||||||
getManager().call("releasedToken", { type = type, guid = guid })
|
|
||||||
end
|
|
||||||
|
|
||||||
-- updates the internal count (called by cards that seal bless/curse tokens)
|
|
||||||
---@param type string Type of chaos token ("Bless" or "Curse")
|
|
||||||
---@param guid string GUID of the token
|
|
||||||
BlessCurseManagerApi.returnedToken = function(type, guid)
|
|
||||||
getManager().call("returnedToken", { type = type, guid = guid })
|
|
||||||
end
|
|
||||||
|
|
||||||
-- broadcasts the current status for bless/curse tokens
|
|
||||||
---@param playerColor string Color of the player to show the broadcast to
|
|
||||||
BlessCurseManagerApi.broadcastStatus = function(playerColor)
|
|
||||||
getManager().call("broadcastStatus", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- removes all bless / curse tokens from the chaos bag and play
|
|
||||||
---@param playerColor string Color of the player to show the broadcast to
|
|
||||||
BlessCurseManagerApi.removeAll = function(playerColor)
|
|
||||||
getManager().call("doRemove", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- adds bless / curse sealing to the hovered card
|
|
||||||
---@param playerColor string Color of the player to show the broadcast to
|
|
||||||
---@param hoveredObject tts__Object Hovered object
|
|
||||||
BlessCurseManagerApi.addBlurseSealingMenu = function(playerColor, hoveredObject)
|
|
||||||
getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject })
|
|
||||||
end
|
|
||||||
|
|
||||||
return BlessCurseManagerApi
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
__bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("chaosbag/ChaosBagApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
do
|
do
|
||||||
local ChaosBagApi = {}
|
local ChaosBagApi = {}
|
||||||
@ -121,7 +61,7 @@ do
|
|||||||
-- respawns the chaos bag with a new state of tokens
|
-- respawns the chaos bag with a new state of tokens
|
||||||
---@param tokenList table List of chaos token ids
|
---@param tokenList table List of chaos token ids
|
||||||
ChaosBagApi.setChaosBagState = function(tokenList)
|
ChaosBagApi.setChaosBagState = function(tokenList)
|
||||||
return Global.call("setChaosBagState", tokenList)
|
Global.call("setChaosBagState", tokenList)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns a Table List of chaos token ids in the current chaos bag
|
-- returns a Table List of chaos token ids in the current chaos bag
|
||||||
@ -148,49 +88,57 @@ do
|
|||||||
-- returns all sealed tokens on cards to the chaos bag
|
-- returns all sealed tokens on cards to the chaos bag
|
||||||
---@param playerColor string Color of the player to show the broadcast to
|
---@param playerColor string Color of the player to show the broadcast to
|
||||||
ChaosBagApi.releaseAllSealedTokens = function(playerColor)
|
ChaosBagApi.releaseAllSealedTokens = function(playerColor)
|
||||||
return Global.call("releaseAllSealedTokens", playerColor)
|
Global.call("releaseAllSealedTokens", playerColor)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns all drawn tokens to the chaos bag
|
-- returns all drawn tokens to the chaos bag
|
||||||
ChaosBagApi.returnChaosTokens = function()
|
ChaosBagApi.returnChaosTokens = function()
|
||||||
return Global.call("returnChaosTokens")
|
Global.call("returnChaosTokens")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- removes the specified chaos token from the chaos bag
|
-- removes the specified chaos token from the chaos bag
|
||||||
---@param id string ID of the chaos token
|
---@param id string ID of the chaos token
|
||||||
ChaosBagApi.removeChaosToken = function(id)
|
ChaosBagApi.removeChaosToken = function(id)
|
||||||
return Global.call("removeChaosToken", id)
|
Global.call("removeChaosToken", id)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns a chaos token to the bag and calls all relevant functions
|
-- returns a chaos token to the bag and calls all relevant functions
|
||||||
---@param token tts__Object Chaos token to return
|
---@param token tts__Object Chaos token to return
|
||||||
ChaosBagApi.returnChaosTokenToBag = function(token)
|
---@param fromBag boolean whether or not the token to return was in the middle of being drawn (true) or elsewhere (false)
|
||||||
return Global.call("returnChaosTokenToBag", token)
|
ChaosBagApi.returnChaosTokenToBag = function(token, fromBag)
|
||||||
|
Global.call("returnChaosTokenToBag", { token = token, fromBag = fromBag })
|
||||||
end
|
end
|
||||||
|
|
||||||
-- spawns the specified chaos token and puts it into the chaos bag
|
-- spawns the specified chaos token and puts it into the chaos bag
|
||||||
---@param id string ID of the chaos token
|
---@param id string ID of the chaos token
|
||||||
ChaosBagApi.spawnChaosToken = function(id)
|
ChaosBagApi.spawnChaosToken = function(id)
|
||||||
return Global.call("spawnChaosToken", id)
|
Global.call("spawnChaosToken", id)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Checks to see if the chaos bag can be manipulated. If a player is searching the bag when tokens
|
-- Checks to see if the chaos bag can be manipulated. If a player is searching the bag when tokens
|
||||||
-- are drawn or replaced a TTS bug can cause those tokens to vanish. Any functions which change the
|
-- are drawn or replaced a TTS bug can cause those tokens to vanish. Any functions which change the
|
||||||
-- contents of the bag should check this method before doing so.
|
-- contents of the bag should check this method before doing so.
|
||||||
-- This method will broadcast a message to all players if the bag is being searched.
|
-- This method will broadcast a message to all players if the bag is being searched.
|
||||||
---@return any canTouch True if the bag is manipulated, false if it should be blocked.
|
---@return any: True if the bag is manipulated, false if it should be blocked.
|
||||||
ChaosBagApi.canTouchChaosTokens = function()
|
ChaosBagApi.canTouchChaosTokens = function()
|
||||||
return Global.call("canTouchChaosTokens")
|
return Global.call("canTouchChaosTokens")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- called by playermats (by the "Draw chaos token" button)
|
-- draws a chaos token to a playermat
|
||||||
---@param mat tts__Object Playermat that triggered this
|
---@param mat tts__Object Playermat that triggered this
|
||||||
---@param drawAdditional boolean Controls whether additional tokens should be drawn
|
---@param drawAdditional boolean Controls whether additional tokens should be drawn
|
||||||
---@param tokenType? string Name of token (e.g. "Bless") to be drawn from the bag
|
---@param tokenType? string Name of token (e.g. "Bless") to be drawn from the bag
|
||||||
---@param guidToBeResolved? string GUID of the sealed token to be resolved instead of drawing a token from the bag
|
---@param guidToBeResolved? string GUID of the sealed token to be resolved instead of drawing a token from the bag
|
||||||
---@param returnedToken? tts__Object Token to be replaced with newly drawn token
|
---@param takeParameters? table Position and rotation of the location where the new token should be drawn to, usually to replace a returned token
|
||||||
ChaosBagApi.drawChaosToken = function(mat, drawAdditional, tokenType, guidToBeResolved, returnedToken)
|
---@return tts__Object: Object reference to the token that was drawn
|
||||||
return Global.call("drawChaosToken", {mat = mat, drawAdditional = drawAdditional, tokenType = tokenType, guidToBeResolved = guidToBeResolved, returnedToken = returnedToken})
|
ChaosBagApi.drawChaosToken = function(mat, drawAdditional, tokenType, guidToBeResolved, takeParameters)
|
||||||
|
return Global.call("drawChaosToken", {
|
||||||
|
mat = mat,
|
||||||
|
drawAdditional = drawAdditional,
|
||||||
|
tokenType = tokenType,
|
||||||
|
guidToBeResolved = guidToBeResolved,
|
||||||
|
takeParameters = takeParameters
|
||||||
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns a Table List of chaos token ids in the current chaos bag
|
-- returns a Table List of chaos token ids in the current chaos bag
|
||||||
@ -202,15 +150,16 @@ do
|
|||||||
return ChaosBagApi
|
return ChaosBagApi
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("playermat/PlayermatApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
do
|
do
|
||||||
local PlaymatApi = {}
|
local PlayermatApi = {}
|
||||||
local guidReferenceApi = require("core/GUIDReferenceApi")
|
local guidReferenceApi = require("core/GUIDReferenceApi")
|
||||||
local searchLib = require("util/SearchLib")
|
local searchLib = require("util/SearchLib")
|
||||||
|
local localInvestigatorPosition = { x = -1.17, y = 1, z = -0.01 }
|
||||||
|
|
||||||
-- Convenience function to look up a mat's object by color, or get all mats.
|
-- Convenience function to look up a mat's object by color, or get all mats.
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@return table: Single-element if only single playmat is requested
|
---@return table: Single-element if only single playermat is requested
|
||||||
local function getMatForColor(matColor)
|
local function getMatForColor(matColor)
|
||||||
if matColor == "All" then
|
if matColor == "All" then
|
||||||
return guidReferenceApi.getObjectsByType("Playermat")
|
return guidReferenceApi.getObjectsByType("Playermat")
|
||||||
@ -219,9 +168,9 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the color of the closest playmat
|
-- Returns the color of the closest playermat
|
||||||
---@param startPos table Starting position to get the closest mat from
|
---@param startPos table Starting position to get the closest mat from
|
||||||
PlaymatApi.getMatColorByPosition = function(startPos)
|
PlayermatApi.getMatColorByPosition = function(startPos)
|
||||||
local result, smallestDistance
|
local result, smallestDistance
|
||||||
for matColor, mat in pairs(getMatForColor("All")) do
|
for matColor, mat in pairs(getMatForColor("All")) do
|
||||||
local distance = Vector.between(startPos, mat.getPosition()):magnitude()
|
local distance = Vector.between(startPos, mat.getPosition()):magnitude()
|
||||||
@ -233,17 +182,17 @@ do
|
|||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the color of the player's hand that is seated next to the playmat
|
-- Returns the color of the player's hand that is seated next to the playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.getPlayerColor = function(matColor)
|
PlayermatApi.getPlayerColor = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.getVar("playerColor")
|
return mat.getVar("playerColor")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the color of the playmat that owns the playercolor's hand
|
-- Returns the color of the playermat that owns the playercolor's hand
|
||||||
---@param handColor string Color of the playmat
|
---@param handColor string Color of the playermat
|
||||||
PlaymatApi.getMatColor = function(handColor)
|
PlayermatApi.getMatColor = function(handColor)
|
||||||
for matColor, mat in pairs(getMatForColor("All")) do
|
for matColor, mat in pairs(getMatForColor("All")) do
|
||||||
local playerColor = mat.getVar("playerColor")
|
local playerColor = mat.getVar("playerColor")
|
||||||
if playerColor == handColor then
|
if playerColor == handColor then
|
||||||
@ -252,41 +201,69 @@ do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns if there is the card "Dream-Enhancing Serum" on the requested playmat
|
-- Instructs a playermat to check for DES
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.isDES = function(matColor)
|
PlayermatApi.checkForDES = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.getVar("isDES")
|
mat.call("checkForDES")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Performs a search of the deck area of the requested playmat and returns the result as table
|
-- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.getDeckAreaObjects = function(matColor)
|
---@return boolean: whether DES is present on the playermat
|
||||||
|
PlayermatApi.hasDES = function(matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
return mat.getVar("hasDES")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- gets the slot data for the playermat
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
|
PlayermatApi.getSlotData = function(matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
return mat.getTable("slotData")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- sets the slot data for the playermat
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
|
---@param newSlotData table New slot data for the playermat
|
||||||
|
PlayermatApi.loadSlotData = function(matColor, newSlotData)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
mat.setTable("slotData", newSlotData)
|
||||||
|
mat.call("redrawSlotSymbols")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Performs a search of the deck area of the requested playermat and returns the result as table
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
|
PlayermatApi.getDeckAreaObjects = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.call("getDeckAreaObjects")
|
return mat.call("getDeckAreaObjects")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Flips the top card of the deck (useful after deck manipulation for Norman Withers)
|
-- Flips the top card of the deck (useful after deck manipulation for Norman Withers)
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.flipTopCardFromDeck = function(matColor)
|
PlayermatApi.flipTopCardFromDeck = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.call("flipTopCardFromDeck")
|
return mat.call("flipTopCardFromDeck")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the position of the discard pile of the requested playmat
|
-- Returns the position of the discard pile of the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.getDiscardPosition = function(matColor)
|
PlayermatApi.getDiscardPosition = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.call("returnGlobalDiscardPosition")
|
return mat.call("returnGlobalDiscardPosition")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the position of the draw pile of the requested playmat
|
-- Returns the position of the draw pile of the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.getDrawPosition = function(matColor)
|
PlayermatApi.getDrawPosition = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.call("returnGlobalDrawPosition")
|
return mat.call("returnGlobalDrawPosition")
|
||||||
end
|
end
|
||||||
@ -294,25 +271,25 @@ do
|
|||||||
|
|
||||||
-- Transforms a local position into a global position
|
-- Transforms a local position into a global position
|
||||||
---@param localPos table Local position to be transformed
|
---@param localPos table Local position to be transformed
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.transformLocalPosition = function(localPos, matColor)
|
PlayermatApi.transformLocalPosition = function(localPos, matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.positionToWorld(localPos)
|
return mat.positionToWorld(localPos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the rotation of the requested playmat
|
-- Returns the rotation of the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.returnRotation = function(matColor)
|
PlayermatApi.returnRotation = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.getRotation()
|
return mat.getRotation()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns a table with spawn data (position and rotation) for a helper object
|
-- Returns a table with spawn data (position and rotation) for a helper object
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@param helperName string Name of the helper object
|
---@param helperName string Name of the helper object
|
||||||
PlaymatApi.getHelperSpawnData = function(matColor, helperName)
|
PlayermatApi.getHelperSpawnData = function(matColor, helperName)
|
||||||
local resultTable = {}
|
local resultTable = {}
|
||||||
local localPositionTable = {
|
local localPositionTable = {
|
||||||
["Hand Helper"] = {0.05, 0, -1.182},
|
["Hand Helper"] = {0.05, 0, -1.182},
|
||||||
@ -329,82 +306,99 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
-- Triggers the Upkeep for the requested playmat
|
-- Triggers the Upkeep for the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@param playerColor string Color of the calling player (for messages)
|
---@param playerColor string Color of the calling player (for messages)
|
||||||
PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor)
|
PlayermatApi.doUpkeepFromHotkey = function(matColor, playerColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("doUpkeepFromHotkey", playerColor)
|
mat.call("doUpkeepFromHotkey", playerColor)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Handles discarding for the requested playmat for the provided list of objects
|
-- Handles discarding for the requested playermat for the provided list of objects
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
---@param objList table List of objects to discard
|
---@param objList table List of objects to discard
|
||||||
PlaymatApi.discardListOfObjects = function(matColor, objList)
|
PlayermatApi.discardListOfObjects = function(matColor, objList)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("discardListOfObjects", objList)
|
mat.call("discardListOfObjects", objList)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the active investigator id
|
-- Returns the active investigator id
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
PlaymatApi.returnInvestigatorId = function(matColor)
|
PlayermatApi.returnInvestigatorId = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.getVar("activeInvestigatorId")
|
return mat.getVar("activeInvestigatorId")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Returns the class of the active investigator
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
|
PlayermatApi.returnInvestigatorClass = function(matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
return mat.getVar("activeInvestigatorClass")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Returns the position for encounter card drawing
|
-- Returns the position for encounter card drawing
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
---@param stack boolean If true, returns the leftmost position instead of the first empty from the right
|
---@param stack boolean If true, returns the leftmost position instead of the first empty from the right
|
||||||
PlaymatApi.getEncounterCardDrawPosition = function(matColor, stack)
|
PlayermatApi.getEncounterCardDrawPosition = function(matColor, stack)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return Vector(mat.call("getEncounterCardDrawPosition", stack))
|
return Vector(mat.call("getEncounterCardDrawPosition", stack))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sets the requested playmat's snap points to limit snapping to matching card types or not. If
|
-- Sets the requested playermat's snap points to limit snapping to matching card types or not. If
|
||||||
-- matchTypes is true, the main card slot snap points will only snap assets, while the
|
-- matchTypes is true, the main card slot snap points will only snap assets, while the
|
||||||
-- investigator area point will only snap Investigators. If matchTypes is false, snap points will
|
-- investigator area point will only snap Investigators. If matchTypes is false, snap points will
|
||||||
-- be reset to snap all cards.
|
-- be reset to snap all cards.
|
||||||
---@param matchCardTypes boolean Whether snap points should only snap for the matching card types
|
---@param matchCardTypes boolean Whether snap points should only snap for the matching card types
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor)
|
PlayermatApi.setLimitSnapsByType = function(matchCardTypes, matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("setLimitSnapsByType", matchCardTypes)
|
mat.call("setLimitSnapsByType", matchCardTypes)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Sets the requested playmat's draw 1 button to visible
|
-- Sets the requested playermat's draw 1 button to visible
|
||||||
---@param isDrawButtonVisible boolean Whether the draw 1 button should be visible or not
|
---@param isDrawButtonVisible boolean Whether the draw 1 button should be visible or not
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor)
|
PlayermatApi.showDrawButton = function(isDrawButtonVisible, matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("showDrawButton", isDrawButtonVisible)
|
mat.call("showDrawButton", isDrawButtonVisible)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Shows or hides the clickable clue counter for the requested playmat
|
-- Shows or hides the clickable clue counter for the requested playermat
|
||||||
---@param showCounter boolean Whether the clickable counter should be present or not
|
---@param showCounter boolean Whether the clickable counter should be present or not
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.clickableClues = function(showCounter, matColor)
|
PlayermatApi.clickableClues = function(showCounter, matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("clickableClues", showCounter)
|
mat.call("clickableClues", showCounter)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Removes all clues (to the trash for tokens and counters set to 0) for the requested playmat
|
-- Toggles the use of class textures for the requested playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param state boolean Whether the class texture should be used or not
|
||||||
PlaymatApi.removeClues = function(matColor)
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
|
PlayermatApi.useClassTexture = function(state, matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
mat.call("useClassTexture", state)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
|
PlayermatApi.removeClues = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("removeClues")
|
mat.call("removeClues")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Reports the clue count for the requested playmat
|
-- Reports the clue count for the requested playermat
|
||||||
---@param useClickableCounters boolean Controls which type of counter is getting checked
|
---@param useClickableCounters boolean Controls which type of counter is getting checked
|
||||||
PlaymatApi.getClueCount = function(useClickableCounters, matColor)
|
PlayermatApi.getClueCount = function(useClickableCounters, matColor)
|
||||||
local count = 0
|
local count = 0
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
count = count + mat.call("getClueCount", useClickableCounters)
|
count = count + mat.call("getClueCount", useClickableCounters)
|
||||||
@ -413,37 +407,36 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Updates the specified owned counter
|
-- Updates the specified owned counter
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@param type string Counter to target
|
---@param type string Counter to target
|
||||||
---@param newValue number Value to set the counter to
|
---@param newValue number Value to set the counter to
|
||||||
---@param modifier number If newValue is not provided, the existing value will be adjusted by this modifier
|
---@param modifier number If newValue is not provided, the existing value will be adjusted by this modifier
|
||||||
PlaymatApi.updateCounter = function(matColor, type, newValue, modifier)
|
PlayermatApi.updateCounter = function(matColor, type, newValue, modifier)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier })
|
mat.call("updateCounter", { type = type, newValue = newValue, modifier = modifier })
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Triggers the draw function for the specified playmat
|
-- Triggers the draw function for the specified playermat
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@param number number Amount of cards to draw
|
---@param number number Amount of cards to draw
|
||||||
PlaymatApi.drawCardsWithReshuffle = function(matColor, number)
|
PlayermatApi.drawCardsWithReshuffle = function(matColor, number)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("drawCardsWithReshuffle", number)
|
mat.call("drawCardsWithReshuffle", number)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns the resource counter amount
|
-- Returns the resource counter amount
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
---@param matColor string Color of the playermat - White, Orange, Green or Red (does not support "All")
|
||||||
---@param type string Counter to target
|
---@param type string Counter to target
|
||||||
PlaymatApi.getCounterValue = function(matColor, type)
|
PlayermatApi.getCounterValue = function(matColor, type)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
return mat.call("getCounterValue", type)
|
return mat.call("getCounterValue", type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns a list of mat colors that have an investigator placed
|
-- Returns a list of mat colors that have an investigator placed
|
||||||
PlaymatApi.getUsedMatColors = function()
|
PlayermatApi.getUsedMatColors = function()
|
||||||
local localInvestigatorPosition = { x = -1.17, y = 1, z = -0.01 }
|
|
||||||
local usedColors = {}
|
local usedColors = {}
|
||||||
for matColor, mat in pairs(getMatForColor("All")) do
|
for matColor, mat in pairs(getMatForColor("All")) do
|
||||||
local searchPos = mat.positionToWorld(localInvestigatorPosition)
|
local searchPos = mat.positionToWorld(localInvestigatorPosition)
|
||||||
@ -455,18 +448,39 @@ do
|
|||||||
return usedColors
|
return usedColors
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Returns investigator name
|
||||||
|
---@param matColor string Color of the playmat - White, Orange, Green or Red (does not support "All")
|
||||||
|
PlayermatApi.getInvestigatorName = function(matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
local searchPos = mat.positionToWorld(localInvestigatorPosition)
|
||||||
|
local searchResult = searchLib.atPosition(searchPos, "isCardOrDeck")
|
||||||
|
if #searchResult == 1 then
|
||||||
|
return searchResult[1].getName()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
|
||||||
-- Resets the specified skill tracker to "1, 1, 1, 1"
|
-- Resets the specified skill tracker to "1, 1, 1, 1"
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.resetSkillTracker = function(matColor)
|
PlayermatApi.resetSkillTracker = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("resetSkillTracker")
|
mat.call("resetSkillTracker")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Finds all objects on the playmat and associated set aside zone and returns a table
|
-- Redraws the XML for the slot symbols based on the slotData table
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
|
PlayermatApi.redrawSlotSymbols = function(matColor)
|
||||||
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
|
mat.call("redrawSlotSymbols")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Finds all objects on the playermat and associated set aside zone and returns a table
|
||||||
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
---@param filter string Name of the filte function (see util/SearchLib)
|
---@param filter string Name of the filte function (see util/SearchLib)
|
||||||
PlaymatApi.searchAroundPlaymat = function(matColor, filter)
|
PlayermatApi.searchAroundPlayermat = function(matColor, filter)
|
||||||
local objList = {}
|
local objList = {}
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do
|
for _, obj in ipairs(mat.call("searchAroundSelf", filter)) do
|
||||||
@ -477,33 +491,33 @@ do
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- Discard a non-hidden card from the corresponding player's hand
|
-- Discard a non-hidden card from the corresponding player's hand
|
||||||
---@param matColor string Color of the playmat - White, Orange, Green, Red or All
|
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
|
||||||
PlaymatApi.doDiscardOne = function(matColor)
|
PlayermatApi.doDiscardOne = function(matColor)
|
||||||
for _, mat in pairs(getMatForColor(matColor)) do
|
for _, mat in pairs(getMatForColor(matColor)) do
|
||||||
mat.call("doDiscardOne")
|
mat.call("doDiscardOne")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Triggers the metadata sync for all playmats
|
-- Triggers the metadata sync for all playermats
|
||||||
PlaymatApi.syncAllCustomizableCards = function()
|
PlayermatApi.syncAllCustomizableCards = function()
|
||||||
for _, mat in pairs(getMatForColor("All")) do
|
for _, mat in pairs(getMatForColor("All")) do
|
||||||
mat.call("syncAllCustomizableCards")
|
mat.call("syncAllCustomizableCards")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return PlaymatApi
|
return PlayermatApi
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
__bundle_register("util/SearchLib", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("util/SearchLib", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
do
|
do
|
||||||
local SearchLib = {}
|
local SearchLib = {}
|
||||||
local filterFunctions = {
|
local filterFunctions = {
|
||||||
isActionToken = function(x) return x.getDescription() == "Action Token" end,
|
|
||||||
isCard = function(x) return x.type == "Card" end,
|
isCard = function(x) return x.type == "Card" end,
|
||||||
isDeck = function(x) return x.type == "Deck" end,
|
isDeck = function(x) return x.type == "Deck" end,
|
||||||
isCardOrDeck = function(x) return x.type == "Card" or x.type == "Deck" end,
|
isCardOrDeck = function(x) return x.type == "Card" or x.type == "Deck" end,
|
||||||
isClue = function(x) return x.memo == "clueDoom" and x.is_face_down == false end,
|
isClue = function(x) return x.memo == "clueDoom" and x.is_face_down == false end,
|
||||||
isTileOrToken = function(x) return x.type == "Tile" end
|
isTileOrToken = function(x) return x.type == "Tile" end,
|
||||||
|
isUniversalToken = function(x) return x.getMemo() == "universalActionAbility" end,
|
||||||
}
|
}
|
||||||
|
|
||||||
-- performs the actual search and returns a filtered list of object references
|
-- performs the actual search and returns a filtered list of object references
|
||||||
@ -527,7 +541,7 @@ do
|
|||||||
max_distance = maxDistance or 0
|
max_distance = maxDistance or 0
|
||||||
})
|
})
|
||||||
|
|
||||||
-- filtering the result
|
-- filter the result for matching objects
|
||||||
local objList = {}
|
local objList = {}
|
||||||
for _, v in ipairs(searchResult) do
|
for _, v in ipairs(searchResult) do
|
||||||
if not filter or filterFunc(v.hit_object) then
|
if not filter or filterFunc(v.hit_object) then
|
||||||
@ -544,21 +558,22 @@ do
|
|||||||
|
|
||||||
-- searches the area on an object
|
-- searches the area on an object
|
||||||
SearchLib.onObject = function(obj, filter)
|
SearchLib.onObject = function(obj, filter)
|
||||||
pos = obj.getPosition()
|
local pos = obj.getPosition()
|
||||||
size = obj.getBounds().size:setAt("y", 1)
|
local size = obj.getBounds().size:setAt("y", 1)
|
||||||
return returnSearchResult(pos, _, size, filter)
|
return returnSearchResult(pos, _, size, filter)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- searches the specified position (a single point)
|
-- searches the specified position (a single point)
|
||||||
SearchLib.atPosition = function(pos, filter)
|
SearchLib.atPosition = function(pos, filter)
|
||||||
size = { 0.1, 2, 0.1 }
|
local size = { 0.1, 2, 0.1 }
|
||||||
return returnSearchResult(pos, _, size, filter)
|
return returnSearchResult(pos, _, size, filter)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- searches below the specified position (downwards until y = 0)
|
-- searches below the specified position (downwards until y = 0)
|
||||||
SearchLib.belowPosition = function(pos, filter)
|
SearchLib.belowPosition = function(pos, filter)
|
||||||
direction = { 0, -1, 0 }
|
local size = { 0.1, 2, 0.1 }
|
||||||
maxDistance = pos.y
|
local direction = { 0, -1, 0 }
|
||||||
|
local maxDistance = pos.y
|
||||||
return returnSearchResult(pos, _, size, filter, direction, maxDistance)
|
return returnSearchResult(pos, _, size, filter, direction, maxDistance)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -568,8 +583,17 @@ end)
|
|||||||
__bundle_register("playercards/CardsThatSealTokens", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("playercards/CardsThatSealTokens", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
--[[ Library for cards that seal tokens
|
--[[ Library for cards that seal tokens
|
||||||
This file is used to add sealing option to cards' context menu.
|
This file is used to add sealing option to cards' context menu.
|
||||||
|
NOTE: all cards are allowed to release a single token to enable Hallow and A Watchful Peace,
|
||||||
|
and to release all sealed tokens to allow for cards that might leave play with sealed tokens on them.
|
||||||
Valid options (set before requiring this file):
|
Valid options (set before requiring this file):
|
||||||
|
|
||||||
|
MAX_SEALED --@type: number (maximum number of tokens allowable by the card to be sealed)
|
||||||
|
- required for all cards
|
||||||
|
- if MAX_SEALED is more than 1, then an XML label is created for the topmost token indicating the number of sealed tokens
|
||||||
|
- gives an error if user tries to seal additional tokens on the card
|
||||||
|
- example usage: "The Chthonian Stone"
|
||||||
|
> MAX_SEALED = 1
|
||||||
|
|
||||||
UPDATE_ON_HOVER --@type: boolean
|
UPDATE_ON_HOVER --@type: boolean
|
||||||
- automatically updates the context menu options when the card is hovered
|
- automatically updates the context menu options when the card is hovered
|
||||||
- the "Read Bag" function reads the content of the chaos bag to update the context menu
|
- the "Read Bag" function reads the content of the chaos bag to update the context menu
|
||||||
@ -580,19 +604,16 @@ KEEP_OPEN --@type: boolean
|
|||||||
- makes the context menu stay open after selecting an option
|
- makes the context menu stay open after selecting an option
|
||||||
- example usage: "Unrelenting"
|
- example usage: "Unrelenting"
|
||||||
|
|
||||||
SHOW_SINGLE_RELEASE --@type: boolean
|
SHOW_MULTI_RELEASE --@type: number (maximum amount of tokens to release at once)
|
||||||
- enables an entry in the context menu
|
- enables an entry in the context menu
|
||||||
- this entry allows releasing a single token
|
- this entry allows releasing of multiple tokens at once, to the maximum number
|
||||||
- example usage: "Holy Spear" (to keep the other tokens and just release one)
|
- does not fail if there are fewer than the maximum sealed
|
||||||
|
- example usage: "Nephthys" (to release up to 3 bless tokens at once)
|
||||||
SHOW_MULTI_RELEASE --@type: number (amount of tokens to release at once)
|
|
||||||
- enables an entry in the context menu
|
|
||||||
- this entry allows releasing of multiple tokens at once
|
|
||||||
- example usage: "Nephthys" (to release 3 bless tokens at once)
|
|
||||||
|
|
||||||
SHOW_MULTI_RETURN --@type: number (amount of tokens to return to pool at once)
|
SHOW_MULTI_RETURN --@type: number (amount of tokens to return to pool at once)
|
||||||
- enables an entry in the context menu
|
- enables an entry in the context menu
|
||||||
- this entry allows returning tokens to the token pool
|
- this entry allows returning tokens to the token pool
|
||||||
|
- fails if not enough tokens are sealed
|
||||||
- example usage: "Nephthys" (to return 3 bless tokens at once)
|
- example usage: "Nephthys" (to return 3 bless tokens at once)
|
||||||
|
|
||||||
SHOW_MULTI_SEAL --@type: number (amount of tokens to seal at once)
|
SHOW_MULTI_SEAL --@type: number (amount of tokens to seal at once)
|
||||||
@ -626,6 +647,7 @@ Thus it should be implemented like this:
|
|||||||
> ["+1"] = true,
|
> ["+1"] = true,
|
||||||
> ["Elder Sign"] = true
|
> ["Elder Sign"] = true
|
||||||
> }
|
> }
|
||||||
|
> MAX_SEALED = 1
|
||||||
> require...
|
> require...
|
||||||
----------------------------------------------------------
|
----------------------------------------------------------
|
||||||
Example 2: Holy Spear
|
Example 2: Holy Spear
|
||||||
@ -636,21 +658,35 @@ Thus it should be implemented like this:
|
|||||||
> VALID_TOKENS = {
|
> VALID_TOKENS = {
|
||||||
> ["Bless"] = true
|
> ["Bless"] = true
|
||||||
> }
|
> }
|
||||||
> SHOW_SINGLE_RELEASE = true
|
|
||||||
> SHOW_MULTI_SEAL = 2
|
> SHOW_MULTI_SEAL = 2
|
||||||
|
> MAX_SEALED = 10
|
||||||
> require...
|
> require...
|
||||||
----------------------------------------------------------]]
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi")
|
local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi")
|
||||||
local chaosBagApi = require("chaosbag/ChaosBagApi")
|
local chaosBagApi = require("chaosbag/ChaosBagApi")
|
||||||
local guidReferenceApi = require("core/GUIDReferenceApi")
|
local guidReferenceApi = require("core/GUIDReferenceApi")
|
||||||
local playmatApi = require("playermat/PlaymatApi")
|
local playermatApi = require("playermat/PlayermatApi")
|
||||||
local tokenArrangerApi = require("accessories/TokenArrangerApi")
|
local tokenArrangerApi = require("accessories/TokenArrangerApi")
|
||||||
|
|
||||||
local sealedTokens = {}
|
local sealedTokens = {}
|
||||||
local ID_URL_MAP = {}
|
local ID_URL_MAP = {}
|
||||||
local tokensInBag = {}
|
local tokensInBag = {}
|
||||||
|
|
||||||
|
-- XML background color for each token for label when stacked
|
||||||
|
local tokenColor = {
|
||||||
|
["Skull"] = "#4A0400E6",
|
||||||
|
["Cultist"] = "#173B0BE6",
|
||||||
|
["Tablet"] = "#1D2238E6",
|
||||||
|
["Elder Thing"] = "#4D2331E6",
|
||||||
|
["Auto-fail"] = "#9B0004E6",
|
||||||
|
["Bless"] = "#9D702CE6",
|
||||||
|
["Curse"] = "#633A84E6",
|
||||||
|
["Frost"] = "#404450E6",
|
||||||
|
["Elder Sign"] = "#50A8CEE6",
|
||||||
|
[""] = "#77674DE6"
|
||||||
|
}
|
||||||
|
|
||||||
function onSave() return JSON.encode(sealedTokens) end
|
function onSave() return JSON.encode(sealedTokens) end
|
||||||
|
|
||||||
function onLoad(savedData)
|
function onLoad(savedData)
|
||||||
@ -662,13 +698,15 @@ end
|
|||||||
|
|
||||||
-- builds the context menu
|
-- builds the context menu
|
||||||
function generateContextMenu()
|
function generateContextMenu()
|
||||||
-- conditional single or multi release options
|
self.addContextMenuItem("Release one token", releaseOneToken)
|
||||||
if SHOW_SINGLE_RELEASE then
|
|
||||||
self.addContextMenuItem("Release token", releaseOneToken)
|
-- conditional release options
|
||||||
elseif SHOW_MULTI_RELEASE then
|
if MAX_SEALED > 1 then
|
||||||
|
self.addContextMenuItem("Release all tokens", releaseAllTokens)
|
||||||
|
end
|
||||||
|
|
||||||
|
if SHOW_MULTI_RELEASE then
|
||||||
self.addContextMenuItem("Release " .. SHOW_MULTI_RELEASE .. " token(s)", releaseMultipleTokens)
|
self.addContextMenuItem("Release " .. SHOW_MULTI_RELEASE .. " token(s)", releaseMultipleTokens)
|
||||||
else
|
|
||||||
self.addContextMenuItem("Release token(s)", releaseAllTokens)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if RESOLVE_TOKEN then
|
if RESOLVE_TOKEN then
|
||||||
@ -706,7 +744,7 @@ function generateContextMenu()
|
|||||||
end
|
end
|
||||||
|
|
||||||
if allowed then
|
if allowed then
|
||||||
for i = 1, SHOW_MULTI_SEAL do
|
for i = SHOW_MULTI_SEAL, 1, -1 do
|
||||||
sealToken(map.name, playerColor)
|
sealToken(map.name, playerColor)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -743,6 +781,10 @@ end
|
|||||||
|
|
||||||
-- seals the named token on this card
|
-- seals the named token on this card
|
||||||
function sealToken(name, playerColor)
|
function sealToken(name, playerColor)
|
||||||
|
if #sealedTokens >= MAX_SEALED then
|
||||||
|
printToColor("Cannot seal any more tokens on this card", playerColor, "Red")
|
||||||
|
return
|
||||||
|
end
|
||||||
if not chaosBagApi.canTouchChaosTokens() then return end
|
if not chaosBagApi.canTouchChaosTokens() then return end
|
||||||
local chaosbag = chaosBagApi.findChaosBag()
|
local chaosbag = chaosBagApi.findChaosBag()
|
||||||
for i, obj in ipairs(chaosbag.getObjects()) do
|
for i, obj in ipairs(chaosbag.getObjects()) do
|
||||||
@ -759,6 +801,16 @@ function sealToken(name, playerColor)
|
|||||||
if name == "Bless" or name == "Curse" then
|
if name == "Bless" or name == "Curse" then
|
||||||
blessCurseManagerApi.sealedToken(name, guid)
|
blessCurseManagerApi.sealedToken(name, guid)
|
||||||
end
|
end
|
||||||
|
-- destroy XML on just covered token
|
||||||
|
if #sealedTokens > 1 then
|
||||||
|
local coveredToken = getObjectFromGUID(sealedTokens[#sealedTokens - 1])
|
||||||
|
if coveredToken ~= nil then
|
||||||
|
coveredToken.UI.setXml("")
|
||||||
|
else
|
||||||
|
table.remove(sealedTokens, #sealedTokens - 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
updateStackSize()
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
@ -778,16 +830,22 @@ function releaseOneToken(playerColor)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- release multiple tokens at once
|
-- release up to multiple tokens at once with no minimum
|
||||||
function releaseMultipleTokens(playerColor)
|
function releaseMultipleTokens(playerColor)
|
||||||
if SHOW_MULTI_RELEASE <= #sealedTokens then
|
if #sealedTokens == 0 then
|
||||||
for i = 1, SHOW_MULTI_RELEASE do
|
printToColor("Not enough tokens sealed.", playerColor)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local numRemoved = SHOW_MULTI_RELEASE
|
||||||
|
if #sealedTokens < SHOW_MULTI_RELEASE then
|
||||||
|
numRemoved = #sealedTokens
|
||||||
|
end
|
||||||
|
|
||||||
|
for i = 1, numRemoved do
|
||||||
putTokenAway(table.remove(sealedTokens))
|
putTokenAway(table.remove(sealedTokens))
|
||||||
end
|
end
|
||||||
printToColor("Releasing " .. SHOW_MULTI_RELEASE .. " tokens", playerColor)
|
printToColor("Releasing " .. numRemoved .. " tokens", playerColor)
|
||||||
else
|
|
||||||
printToColor("Not enough tokens sealed.", playerColor)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- releases all sealed tokens
|
-- releases all sealed tokens
|
||||||
@ -828,6 +886,7 @@ function putTokenAway(guid)
|
|||||||
if name == "Bless" or name == "Curse" then
|
if name == "Bless" or name == "Curse" then
|
||||||
blessCurseManagerApi.releasedToken(name, guid)
|
blessCurseManagerApi.releasedToken(name, guid)
|
||||||
end
|
end
|
||||||
|
updateStackSize()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns the token to the pool (== removes it)
|
-- returns the token to the pool (== removes it)
|
||||||
@ -840,6 +899,7 @@ function returnToken(guid)
|
|||||||
if name == "Bless" or name == "Curse" then
|
if name == "Bless" or name == "Curse" then
|
||||||
blessCurseManagerApi.returnedToken(name, guid)
|
blessCurseManagerApi.returnedToken(name, guid)
|
||||||
end
|
end
|
||||||
|
updateStackSize()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- resolves sealed token as if it came from the chaos bag
|
-- resolves sealed token as if it came from the chaos bag
|
||||||
@ -848,11 +908,47 @@ function resolveSealed()
|
|||||||
broadcastToAll("No tokens sealed.", "Red")
|
broadcastToAll("No tokens sealed.", "Red")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local closestMatColor = playmatApi.getMatColorByPosition(self.getPosition())
|
local closestMatColor = playermatApi.getMatColorByPosition(self.getPosition())
|
||||||
local mat = guidReferenceApi.getObjectByOwnerAndType(closestMatColor, "Playermat")
|
local mat = guidReferenceApi.getObjectByOwnerAndType(closestMatColor, "Playermat")
|
||||||
local guidToBeResolved = table.remove(sealedTokens)
|
local guidToBeResolved = table.remove(sealedTokens)
|
||||||
|
local resolvedToken = getObjectFromGUID(guidToBeResolved)
|
||||||
|
resolvedToken.UI.setXml("")
|
||||||
|
updateStackSize()
|
||||||
chaosBagApi.drawChaosToken(mat, true, _, guidToBeResolved)
|
chaosBagApi.drawChaosToken(mat, true, _, guidToBeResolved)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function updateStackSize()
|
||||||
|
if MAX_SEALED == 1 then return end
|
||||||
|
if #sealedTokens == 0 then return end
|
||||||
|
-- get topmost sealed token
|
||||||
|
local topToken = getObjectFromGUID(sealedTokens[#sealedTokens])
|
||||||
|
local name = topToken.getName()
|
||||||
|
|
||||||
|
topToken.UI.setXmlTable({
|
||||||
|
{
|
||||||
|
tag = "Panel",
|
||||||
|
attributes = {
|
||||||
|
height = 380,
|
||||||
|
width = 380,
|
||||||
|
rotation = "0 0 180",
|
||||||
|
scale = "0.2 0.2 1",
|
||||||
|
position = "0 0 -12",
|
||||||
|
color = tokenColor[name] or "#77674DE6"
|
||||||
|
},
|
||||||
|
children = {
|
||||||
|
tag = "Text",
|
||||||
|
attributes = {
|
||||||
|
fontSize = "380",
|
||||||
|
font = "font_teutonic-arkham",
|
||||||
|
color = "#ffffff",
|
||||||
|
outline = "#000000",
|
||||||
|
outlineSize = "8 -8",
|
||||||
|
text = "x" .. #sealedTokens
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
end)
|
end)
|
||||||
__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("accessories/TokenArrangerApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
do
|
do
|
||||||
@ -888,6 +984,83 @@ do
|
|||||||
return TokenArrangerApi
|
return TokenArrangerApi
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
__bundle_register("chaosbag/BlessCurseManagerApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
do
|
||||||
|
local BlessCurseManagerApi = {}
|
||||||
|
local guidReferenceApi = require("core/GUIDReferenceApi")
|
||||||
|
|
||||||
|
local function getManager()
|
||||||
|
return guidReferenceApi.getObjectByOwnerAndType("Mythos", "BlessCurseManager")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- removes all taken tokens and resets the counts
|
||||||
|
BlessCurseManagerApi.removeTakenTokensAndReset = function()
|
||||||
|
local BlessCurseManager = getManager()
|
||||||
|
Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Bless") end, 0.05)
|
||||||
|
Wait.time(function() BlessCurseManager.call("removeTakenTokens", "Curse") end, 0.10)
|
||||||
|
Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- updates the internal count (called by cards that seal bless/curse tokens)
|
||||||
|
---@param type string Type of chaos token ("Bless" or "Curse")
|
||||||
|
---@param guid string GUID of the token
|
||||||
|
BlessCurseManagerApi.sealedToken = function(type, guid)
|
||||||
|
getManager().call("sealedToken", { type = type, guid = guid })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- updates the internal count (called by cards that seal bless/curse tokens)
|
||||||
|
---@param type string Type of chaos token ("Bless" or "Curse")
|
||||||
|
---@param guid string GUID of the token
|
||||||
|
---@param fromBag? boolean Whether or not token was just drawn from the chaos bag
|
||||||
|
BlessCurseManagerApi.releasedToken = function(type, guid, fromBag)
|
||||||
|
getManager().call("releasedToken", { type = type, guid = guid, fromBag = fromBag })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- updates the internal count (called by cards that seal bless/curse tokens)
|
||||||
|
---@param type string Type of chaos token ("Bless" or "Curse")
|
||||||
|
---@param guid string GUID of the token
|
||||||
|
BlessCurseManagerApi.returnedToken = function(type, guid)
|
||||||
|
getManager().call("returnedToken", { type = type, guid = guid })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- broadcasts the current status for bless/curse tokens
|
||||||
|
---@param playerColor string Color of the player to show the broadcast to
|
||||||
|
BlessCurseManagerApi.broadcastStatus = function(playerColor)
|
||||||
|
getManager().call("broadcastStatus", playerColor)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- removes all bless / curse tokens from the chaos bag and play
|
||||||
|
---@param playerColor string Color of the player to show the broadcast to
|
||||||
|
BlessCurseManagerApi.removeAll = function(playerColor)
|
||||||
|
getManager().call("doRemove", playerColor)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- adds bless / curse sealing to the hovered card
|
||||||
|
---@param playerColor string Color of the player to show the broadcast to
|
||||||
|
---@param hoveredObject tts__Object Hovered object
|
||||||
|
BlessCurseManagerApi.addBlurseSealingMenu = function(playerColor, hoveredObject)
|
||||||
|
getManager().call("addMenuOptions", { playerColor = playerColor, hoveredObject = hoveredObject })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- adds bless / curse to the chaos bag
|
||||||
|
---@param type string Type of chaos token ("Bless" or "Curse")
|
||||||
|
BlessCurseManagerApi.addToken = function(type)
|
||||||
|
getManager().call("addToken", type)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- removes bless / curse from the chaos bag
|
||||||
|
---@param type string Type of chaos token ("Bless" or "Curse")
|
||||||
|
BlessCurseManagerApi.removeToken = function(type)
|
||||||
|
getManager().call("removeToken", type)
|
||||||
|
end
|
||||||
|
|
||||||
|
BlessCurseManagerApi.getBlessCurseInBag = function()
|
||||||
|
return getManager().call("getBlessCurseInBag", {})
|
||||||
|
end
|
||||||
|
|
||||||
|
return BlessCurseManagerApi
|
||||||
|
end
|
||||||
|
end)
|
||||||
__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
__bundle_register("core/GUIDReferenceApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
do
|
do
|
||||||
local GUIDReferenceApi = {}
|
local GUIDReferenceApi = {}
|
||||||
|
@ -21,7 +21,8 @@ Description: ''
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"60121\",\n \"type\": \"Event\",\n \"class\": \"Guardian\",\n
|
GMNotes: "{\n \"id\": \"60121\",\n \"type\": \"Event\",\n \"class\": \"Guardian\",\n
|
||||||
\ \"cost\": 2,\n \"level\": 1,\n \"traits\": \"Spirit.\",\n \"willpowerIcons\":
|
\ \"cost\": 2,\n \"level\": 1,\n \"traits\": \"Spirit.\",\n \"willpowerIcons\":
|
||||||
2,\n \"cycle\": \"Investigator Packs\"\n}"
|
2,\n \"uses\": [\n {\n \"count\": 1,\n \"type\": \"Fight\",\n \"token\":
|
||||||
|
\"universalActionAbility\"\n }\n ],\n \"cycle\": \"Investigator Packs\"\n}"
|
||||||
GUID: 9e7f6a
|
GUID: 9e7f6a
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,7 +21,9 @@ Description: ''
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"09053\",\n \"type\": \"Event\",\n \"class\": \"Seeker\",\n
|
GMNotes: "{\n \"id\": \"09053\",\n \"type\": \"Event\",\n \"class\": \"Seeker\",\n
|
||||||
\ \"cost\": 0,\n \"level\": 1,\n \"traits\": \"Insight.\",\n \"willpowerIcons\":
|
\ \"cost\": 0,\n \"level\": 1,\n \"traits\": \"Insight.\",\n \"willpowerIcons\":
|
||||||
1,\n \"wildIcons\": 1,\n \"cycle\": \"The Scarlet Keys\"\n}"
|
1,\n \"wildIcons\": 1,\n \"uses\": [\n {\n \"count\": 1,\n \"type\":
|
||||||
|
\"Universal\",\n \"token\": \"universalActionAbility\"\n }\n ],\n \"cycle\":
|
||||||
|
\"The Scarlet Keys\"\n}"
|
||||||
GUID: '425841'
|
GUID: '425841'
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,7 +21,8 @@ Description: ''
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"03265\",\n \"type\": \"Event\",\n \"class\": \"Seeker\",\n
|
GMNotes: "{\n \"id\": \"03265\",\n \"type\": \"Event\",\n \"class\": \"Seeker\",\n
|
||||||
\ \"cost\": 0,\n \"level\": 0,\n \"traits\": \"Insight.\",\n \"wildIcons\": 1,\n
|
\ \"cost\": 0,\n \"level\": 0,\n \"traits\": \"Insight.\",\n \"wildIcons\": 1,\n
|
||||||
\ \"cycle\": \"The Path to Carcosa\"\n}"
|
\ \"uses\": [\n {\n \"count\": 1,\n \"type\": \"Universal\",\n \"token\":
|
||||||
|
\"universalActionAbility\"\n }\n ],\n \"cycle\": \"The Path to Carcosa\"\n}"
|
||||||
GUID: bbfe9b
|
GUID: bbfe9b
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -24,14 +24,14 @@ GMNotes: "{\n \"id\": \"10015\",\n \"type\": \"Investigator\",\n \"class\": \
|
|||||||
1,\n \"maxCount\": 1,\n \"id\": \"10015-b1\"\n },\n {\n \"count\":
|
1,\n \"maxCount\": 1,\n \"id\": \"10015-b1\"\n },\n {\n \"count\":
|
||||||
1,\n \"maxCount\": 1,\n \"id\": \"10015-b2\"\n }\n ],\n \"willpowerIcons\":
|
1,\n \"maxCount\": 1,\n \"id\": \"10015-b2\"\n }\n ],\n \"willpowerIcons\":
|
||||||
3,\n \"intellectIcons\": 1,\n \"combatIcons\": 5,\n \"agilityIcons\": 3,\n \"cycle\":
|
3,\n \"intellectIcons\": 1,\n \"combatIcons\": 5,\n \"agilityIcons\": 3,\n \"cycle\":
|
||||||
\"The Feast of Hemlock Vale\",\n \"deck_requirements\": {\n \"size\": 35,\n
|
\"The Feast of Hemlock Vale\",\n \"extraToken\": \"None\",\n \"deck_requirements\":
|
||||||
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"10017\":
|
{\n \"size\": 35,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\":
|
||||||
1\n },\n {\n \"10018\": 1\n }\n ]\n },\n \"deck_options\":
|
[\n {\n \"10017\": 1\n },\n {\n \"10018\": 1\n }\n
|
||||||
[\n {\n \"faction\": [\n \"seeker\",\n \"neutral\"\n ],\n
|
\ ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"seeker\",\n
|
||||||
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ \"trait\": [\n \"insight\",\n \"spirit\"\n ],\n \"level\":
|
5\n }\n },\n {\n \"trait\": [\n \"insight\",\n \"spirit\"\n
|
||||||
{\n \"min\": 0,\n \"max\": 2\n },\n \"limit\": 10\n }\n
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 2\n },\n
|
||||||
\ ]\n}"
|
\ \"limit\": 10\n }\n ]\n}"
|
||||||
GUID: 3764cd
|
GUID: 3764cd
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -20,8 +20,8 @@ CustomDeck:
|
|||||||
Description: ''
|
Description: ''
|
||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90048\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n
|
GMNotes: "{\n \"id\": \"90048\",\n \"type\": \"Treachery\",\n \"class\": \"Neutral\",\n
|
||||||
\ \"traits\": \"Hardship.\",\n \"weakness\": true,\n \"cycle\": \"The Dunwich
|
\ \"traits\": \"Hardship.\",\n \"weakness\": true,\n \"cycle\": \"On the Road
|
||||||
Legacy\"\n}"
|
Again\"\n}"
|
||||||
GUID: '876557'
|
GUID: '876557'
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,11 +22,11 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"60201\",\n \"type\": \"Investigator\",\n \"class\": \"Seeker\",\n
|
GMNotes: "{\n \"id\": \"60201\",\n \"type\": \"Investigator\",\n \"class\": \"Seeker\",\n
|
||||||
\ \"traits\": \"Miskatonic.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
\ \"traits\": \"Miskatonic.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
||||||
5,\n \"combatIcons\": 1,\n \"agilityIcons\": 2,\n \"cycle\": \"Investigator Packs\",\n
|
5,\n \"combatIcons\": 1,\n \"agilityIcons\": 2,\n \"cycle\": \"Investigator Packs\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"60202\": 1\n },\n {\n \"60203\":
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"60202\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"seeker\",\n
|
1\n },\n {\n \"60203\": 1\n }\n ]\n },\n \"deck_options\":
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
[\n {\n \"faction\": [\n \"seeker\",\n \"neutral\"\n ],\n
|
||||||
5\n }\n }\n ]\n}"
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n }\n ]\n}"
|
||||||
GUID: 1fa944
|
GUID: 1fa944
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -0,0 +1,250 @@
|
|||||||
|
-- Bundled by luabundle {"version":"1.6.0"}
|
||||||
|
local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)
|
||||||
|
local loadingPlaceholder = {[{}] = true}
|
||||||
|
|
||||||
|
local register
|
||||||
|
local modules = {}
|
||||||
|
|
||||||
|
local require
|
||||||
|
local loaded = {}
|
||||||
|
|
||||||
|
register = function(name, body)
|
||||||
|
if not modules[name] then
|
||||||
|
modules[name] = body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
require = function(name)
|
||||||
|
local loadedModule = loaded[name]
|
||||||
|
|
||||||
|
if loadedModule then
|
||||||
|
if loadedModule == loadingPlaceholder then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not modules[name] then
|
||||||
|
if not superRequire then
|
||||||
|
local identifier = type(name) == 'string' and '\"' .. name .. '\"' or tostring(name)
|
||||||
|
error('Tried to require ' .. identifier .. ', but no such module has been registered')
|
||||||
|
else
|
||||||
|
return superRequire(name)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
loaded[name] = loadingPlaceholder
|
||||||
|
loadedModule = modules[name](require, loaded, register, modules)
|
||||||
|
loaded[name] = loadedModule
|
||||||
|
end
|
||||||
|
|
||||||
|
return loadedModule
|
||||||
|
end
|
||||||
|
|
||||||
|
return require, loaded, register, modules
|
||||||
|
end)(nil)
|
||||||
|
__bundle_register("playercards/CardsWithHelper", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
--[[ Library for cards that have helpers
|
||||||
|
This file is used to share code between cards with helpers.
|
||||||
|
It syncs the visibility of the helper with the option panel and
|
||||||
|
makes sure the card has the respective tag.
|
||||||
|
Additionally, it will call 'initiliaze()' and 'shutOff()'
|
||||||
|
in the parent file if they are present.
|
||||||
|
|
||||||
|
Instructions:
|
||||||
|
1) Define the global variables before requiring this file:
|
||||||
|
hasXML = true (whether the card has an XML display)
|
||||||
|
isHelperEnabled = false (default state of the helper, should be 'false')
|
||||||
|
|
||||||
|
2) In 'onLoad()'', call 'syncDisplayWithOptionPanel()'
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
local optionPanelApi = require("core/OptionPanelApi")
|
||||||
|
|
||||||
|
-- if the respective option is enabled in onLoad(), enable the helper
|
||||||
|
function syncDisplayWithOptionPanel()
|
||||||
|
self.addTag("CardWithHelper")
|
||||||
|
local options = optionPanelApi.getOptions()
|
||||||
|
if options.enableCardHelpers then
|
||||||
|
setHelperState(true)
|
||||||
|
else
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- forces a new state
|
||||||
|
function setHelperState(newState)
|
||||||
|
isHelperEnabled = newState
|
||||||
|
updateSave()
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- toggles the current state
|
||||||
|
function toggleHelper()
|
||||||
|
isHelperEnabled = not isHelperEnabled
|
||||||
|
updateSave()
|
||||||
|
updateDisplay()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- updates the visibility and calls events (after a small delay to allow XML being set)
|
||||||
|
function updateDisplay()
|
||||||
|
Wait.frames(actualDisplayUpdate, 5)
|
||||||
|
end
|
||||||
|
|
||||||
|
function actualDisplayUpdate()
|
||||||
|
if isHelperEnabled then
|
||||||
|
self.clearContextMenu()
|
||||||
|
self.addContextMenuItem("Disable Helper", toggleHelper)
|
||||||
|
if hasXML then self.UI.show("Helper") end
|
||||||
|
if initialize then initialize() end
|
||||||
|
else
|
||||||
|
self.clearContextMenu()
|
||||||
|
self.addContextMenuItem("Enable Helper", toggleHelper)
|
||||||
|
if hasXML then self.UI.hide("Helper") end
|
||||||
|
if shutOff then shutOff() end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("core/OptionPanelApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
do
|
||||||
|
local OptionPanelApi = {}
|
||||||
|
|
||||||
|
-- loads saved options
|
||||||
|
---@param options table Set a new state for the option table
|
||||||
|
OptionPanelApi.loadSettings = function(options)
|
||||||
|
return Global.call("loadSettings", options)
|
||||||
|
end
|
||||||
|
|
||||||
|
---@return any: Table of option panel state
|
||||||
|
OptionPanelApi.getOptions = function()
|
||||||
|
return Global.getTable("optionPanel")
|
||||||
|
end
|
||||||
|
|
||||||
|
return OptionPanelApi
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
require("playercards/cards/HeavyFurs")
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/cards/HeavyFurs", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
VALID_TOKENS = {
|
||||||
|
["Skull"] = true,
|
||||||
|
["Tablet"] = true,
|
||||||
|
["Elder Thing"] = true,
|
||||||
|
["Cultist"] = true,
|
||||||
|
["Frost"] = true,
|
||||||
|
["Custom Token"] = true,
|
||||||
|
["Elder Sign"] = true,
|
||||||
|
["Bless"] = true,
|
||||||
|
["Curse"] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
require("playercards/CardsWithHelper")
|
||||||
|
require("playercards/CardsThatRedrawTokens")
|
||||||
|
end)
|
||||||
|
__bundle_register("playercards/CardsThatRedrawTokens", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||||
|
--[[ Library for cards that return and redraw tokens
|
||||||
|
This file is used to add an XML button to a card, turned on via context menu.
|
||||||
|
Valid options modify the appearance of the XML button, as well as the
|
||||||
|
behavior of the return and redraw function. Set options before requiring this file.
|
||||||
|
|
||||||
|
Parameters for the return and redraw functions. Typically set VALID_TOKENS or INVALID_TOKENS, not both.
|
||||||
|
If there are no restrictions on which tokens can be redrawn (e.g. Wendy Adams), keep both empty.
|
||||||
|
* VALID_TOKENS --@type table
|
||||||
|
- keyed table which lists all tokens that can be redrawn by the card
|
||||||
|
- example usage: "False Covenant"
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Curse"] = true
|
||||||
|
> }
|
||||||
|
|
||||||
|
* INVALID_TOKENS --@type table
|
||||||
|
- keyed table which lists all tokens that cannot be redrawn by the card
|
||||||
|
- example usage: "Custom Ammunition"
|
||||||
|
> INVALID_TOKENS = {
|
||||||
|
> ["Auto-fail"] = true
|
||||||
|
> }
|
||||||
|
|
||||||
|
* DRAW_SPECIFIC_TOKEN --@type string (name of token or nil)
|
||||||
|
- if set, will attempt to draw that specific token
|
||||||
|
|
||||||
|
* RETURN_TO_POOL --@type string
|
||||||
|
- allows for the name of the card to be passed onto Global for any special handling
|
||||||
|
|
||||||
|
The following parameters modify the appearence of the XML button and are not listed as part of a table.
|
||||||
|
- buttonHeight (default is 450)
|
||||||
|
- buttonWidth (default is 1400)
|
||||||
|
- buttonPosition (default is "0 -55 -22")
|
||||||
|
- buttonFontSize (default is 250)
|
||||||
|
- buttonRotation (change if button is placed on an investigator cards)
|
||||||
|
- buttonLabel (default is "Redraw Token")
|
||||||
|
- buttonIcon (to add an icon to the right)
|
||||||
|
- buttonColor (default is "#77674DE6")
|
||||||
|
|
||||||
|
----------------------------------------------------------
|
||||||
|
EXAMPLE: Claypool's Furs
|
||||||
|
This card can only redraw the Frost token, and is replaced with a random token from the bag.
|
||||||
|
As a nice reminder the XML button takes on the Frost color and icon with the text "Cancel".
|
||||||
|
> buttonValue = "Cancel"
|
||||||
|
> buttonIcon = "token-frost"
|
||||||
|
> buttonColor = "#404450E6"
|
||||||
|
> buttonFontSize = 300
|
||||||
|
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Frost"] = true
|
||||||
|
> }
|
||||||
|
>
|
||||||
|
> require...
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
-- intentionally global
|
||||||
|
hasXML = true
|
||||||
|
isHelperEnabled = false
|
||||||
|
|
||||||
|
function updateSave()
|
||||||
|
self.script_state = JSON.encode({ isHelperEnabled = isHelperEnabled })
|
||||||
|
end
|
||||||
|
|
||||||
|
function onLoad(savedData)
|
||||||
|
if savedData and savedData ~= "" then
|
||||||
|
local loadedData = JSON.decode(savedData)
|
||||||
|
isHelperEnabled = loadedData.isHelperEnabled
|
||||||
|
end
|
||||||
|
createHelperXML()
|
||||||
|
syncDisplayWithOptionPanel()
|
||||||
|
end
|
||||||
|
|
||||||
|
function createHelperXML()
|
||||||
|
local xmlTable = { {
|
||||||
|
tag = "Button",
|
||||||
|
attributes = {
|
||||||
|
active = "false",
|
||||||
|
id = "Helper",
|
||||||
|
height = buttonHeight or 450,
|
||||||
|
width = buttonWidth or 1400,
|
||||||
|
rotation = buttonRotation or "0 0 180",
|
||||||
|
scale = "0.1 0.1 1",
|
||||||
|
position = buttonPosition or "0 -55 -22",
|
||||||
|
padding = "50 50 50 50",
|
||||||
|
font = "font_teutonic-arkham",
|
||||||
|
fontSize = buttonFontSize or 250,
|
||||||
|
onClick = "triggerXMLTokenLabelCreation",
|
||||||
|
color = buttonColor or "#77674DE6",
|
||||||
|
textColor = "White"
|
||||||
|
},
|
||||||
|
value = buttonLabel or "Redraw Token"
|
||||||
|
} }
|
||||||
|
if buttonIcon then
|
||||||
|
xmlTable[1].attributes.iconWidth = "400"
|
||||||
|
xmlTable[1].attributes.iconAlignment = "Right"
|
||||||
|
xmlTable[1].attributes.icon = buttonIcon
|
||||||
|
end
|
||||||
|
self.UI.setXmlTable(xmlTable)
|
||||||
|
end
|
||||||
|
|
||||||
|
function triggerXMLTokenLabelCreation()
|
||||||
|
Global.call("activeRedrawEffect", {
|
||||||
|
VALID_TOKENS = VALID_TOKENS,
|
||||||
|
INVALID_TOKENS = INVALID_TOKENS,
|
||||||
|
RETURN_TO_POOL = RETURN_TO_POOL
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
return __bundle_require("__root")
|
@ -30,7 +30,7 @@ HideWhenFaceDown: true
|
|||||||
IgnoreFoW: false
|
IgnoreFoW: false
|
||||||
LayoutGroupSortIndex: 0
|
LayoutGroupSortIndex: 0
|
||||||
Locked: false
|
Locked: false
|
||||||
LuaScript: ''
|
LuaScript: !include 'Card Heavy Furs 275450.ttslua'
|
||||||
LuaScriptState: ''
|
LuaScriptState: ''
|
||||||
MeasureMovement: false
|
MeasureMovement: false
|
||||||
Name: Card
|
Name: Card
|
||||||
|
@ -21,7 +21,7 @@ Description: Artifact from Another Life (Advanced)
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90018\",\n \"type\": \"Asset\",\n \"slot\": \"Accessory\",\n
|
GMNotes: "{\n \"id\": \"90018\",\n \"type\": \"Asset\",\n \"slot\": \"Accessory\",\n
|
||||||
\ \"class\": \"Neutral\",\n \"cost\": 3,\n \"traits\": \"Item. Relic.\",\n \"willpowerIcons\":
|
\ \"class\": \"Neutral\",\n \"cost\": 3,\n \"traits\": \"Item. Relic.\",\n \"willpowerIcons\":
|
||||||
1,\n \"combatIcons\": 1,\n \"wildIcons\": 2,\n \"cycle\": \"Standalone\"\n}"
|
1,\n \"combatIcons\": 1,\n \"wildIcons\": 2,\n \"cycle\": \"Bad Blood\"\n}"
|
||||||
GUID: bf151d
|
GUID: bf151d
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -21,25 +21,29 @@ Description: ''
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"09061\",\n \"type\": \"Event\",\n \"class\": \"Rogue\",\n
|
GMNotes: "{\n \"id\": \"09061\",\n \"type\": \"Event\",\n \"class\": \"Rogue\",\n
|
||||||
\ \"cost\": 1,\n \"level\": 0,\n \"traits\": \"Gambit.\",\n \"agilityIcons\":
|
\ \"cost\": 1,\n \"level\": 0,\n \"traits\": \"Gambit.\",\n \"agilityIcons\":
|
||||||
1,\n \"customizations\": [\n {\n \"name\": \"Reflex Response\",\n \"xp\":
|
1,\n \"uses\": [\n {\n \"count\": 1,\n \"type\": \"Universal\",\n
|
||||||
1,\n \"text\": \"Add the following play condition: \u201C- You take damage
|
\ \"token\": \"universalActionAbility\"\n }\n ],\n \"customizations\":
|
||||||
or horror.\u201D\"\n },\n {\n \"name\": \"Situational Awareness\",\n
|
[\n {\n \"name\": \"Reflex Response\",\n \"xp\": 1,\n \"text\":
|
||||||
\ \"xp\": 1,\n \"text\": \"Add the following play condition: \u201C- A
|
\"Add the following play condition: \u201C- You take damage or horror.\u201D\"\n
|
||||||
location enters play or is revealed.\u201D\"\n },\n {\n \"name\": \"Killer
|
\ },\n {\n \"name\": \"Situational Awareness\",\n \"xp\": 1,\n \"text\":
|
||||||
Instinct\",\n \"xp\": 1,\n \"text\": \"Add the following play condition:
|
\"Add the following play condition: \u201C- A location enters play or is revealed.\u201D\"\n
|
||||||
\u201C- An enemy engages you.\u201D\"\n },\n {\n \"name\": \"Gut Reaction\",\n
|
\ },\n {\n \"name\": \"Killer Instinct\",\n \"xp\": 1,\n \"text\":
|
||||||
\ \"xp\": 1,\n \"text\": \"Add the following play condition: \u201C- A
|
\"Add the following play condition: \u201C- An enemy engages you.\u201D\"\n },\n
|
||||||
treachery enters your threat area .\u201D\"\n },\n {\n \"name\": \"Muscle
|
\ {\n \"name\": \"Gut Reaction\",\n \"xp\": 1,\n \"text\": \"Add
|
||||||
Memory\",\n \"xp\": 1,\n \"text\": \"Add the following play condition:
|
the following play condition: \u201C- A treachery enters your threat area .\u201D\"\n
|
||||||
\u201C- You play an asset.\u201D\"\n },\n {\n \"name\": \"Sharpened Talent\",\n
|
\ },\n {\n \"name\": \"Muscle Memory\",\n \"xp\": 1,\n \"text\":
|
||||||
\ \"xp\": 2,\n \"text\": \"During the action granted by Honed Instinct,
|
\"Add the following play condition: \u201C- You play an asset.\u201D\"\n },\n
|
||||||
you get +2 to each of your skills.\"\n },\n {\n \"name\": \"Impulse Control\",\n
|
\ {\n \"name\": \"Sharpened Talent\",\n \"xp\": 2,\n \"text\":
|
||||||
\ \"xp\": 3,\n \"text\": \"You may include up to three copies of Honed
|
\"During the action granted by Honed Instinct, you get +2 to each of your skills.\"\n
|
||||||
Instinct in your deck. Honed Instinct gets \u20131 cost.\",\n \"replaces\":
|
\ },\n {\n \"name\": \"Impulse Control\",\n \"xp\": 3,\n \"text\":
|
||||||
{\n \"cost\": 0\n }\n },\n {\n \"name\": \"Force of Habit\",\n
|
\"You may include up to three copies of Honed Instinct in your deck. Honed Instinct
|
||||||
\ \"xp\": 5,\n \"text\": \"When you play Honed Instinct, you may take 2
|
gets \u20131 cost.\",\n \"replaces\": {\n \"cost\": 0\n }\n },\n
|
||||||
actions instead of 1 (one at a time). Then, remove it from the game.\"\n }\n
|
\ {\n \"name\": \"Force of Habit\",\n \"xp\": 5,\n \"text\": \"When
|
||||||
\ ],\n \"cycle\": \"The Scarlet Keys\"\n}"
|
you play Honed Instinct, you may take 2 actions instead of 1 (one at a time). Then,
|
||||||
|
remove it from the game.\",\n \"replaces\": {\n \"uses\": [\n {\n
|
||||||
|
\ \"count\": 2,\n \"type\": \"Universal\",\n \"token\":
|
||||||
|
\"universalActionAbility\"\n }\n ]\n }\n }\n ],\n \"cycle\":
|
||||||
|
\"The Scarlet Keys\"\n}"
|
||||||
GUID: 1cde62
|
GUID: 1cde62
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -1 +0,0 @@
|
|||||||
do_not_ready = true
|
|
@ -30,7 +30,7 @@ HideWhenFaceDown: true
|
|||||||
IgnoreFoW: false
|
IgnoreFoW: false
|
||||||
LayoutGroupSortIndex: 0
|
LayoutGroupSortIndex: 0
|
||||||
Locked: false
|
Locked: false
|
||||||
LuaScript: !include 'Card Jacob Morrison (3) aa38d0.ttslua'
|
LuaScript: ''
|
||||||
LuaScriptState: ''
|
LuaScriptState: ''
|
||||||
MeasureMovement: false
|
MeasureMovement: false
|
||||||
Name: Card
|
Name: Card
|
||||||
@ -40,6 +40,7 @@ Snap: true
|
|||||||
Sticky: true
|
Sticky: true
|
||||||
Tags:
|
Tags:
|
||||||
- Asset
|
- Asset
|
||||||
|
- DoNotReady
|
||||||
- PlayerCard
|
- PlayerCard
|
||||||
Tooltip: true
|
Tooltip: true
|
||||||
Transform:
|
Transform:
|
||||||
|
@ -22,11 +22,11 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"60401\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
GMNotes: "{\n \"id\": \"60401\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
||||||
\ \"traits\": \"Clairvoyant.\",\n \"willpowerIcons\": 5,\n \"intellectIcons\":
|
\ \"traits\": \"Clairvoyant.\",\n \"willpowerIcons\": 5,\n \"intellectIcons\":
|
||||||
3,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"Investigator Packs\",\n
|
3,\n \"combatIcons\": 2,\n \"agilityIcons\": 2,\n \"cycle\": \"Investigator Packs\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"60402\": 1\n },\n {\n \"60403\":
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"60402\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
1\n },\n {\n \"60403\": 1\n }\n ]\n },\n \"deck_options\":
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
[\n {\n \"faction\": [\n \"mystic\",\n \"neutral\"\n ],\n
|
||||||
5\n }\n }\n ]\n}"
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n }\n ]\n}"
|
||||||
GUID: a2cd75
|
GUID: a2cd75
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,14 +22,14 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"02003\",\n \"alternate_ids\": [\n \"98001\"\n ],\n \"type\":
|
GMNotes: "{\n \"id\": \"02003\",\n \"alternate_ids\": [\n \"98001\"\n ],\n \"type\":
|
||||||
\"Investigator\",\n \"class\": \"Rogue\",\n \"traits\": \"Drifter.\",\n \"willpowerIcons\":
|
\"Investigator\",\n \"class\": \"Rogue\",\n \"traits\": \"Drifter.\",\n \"willpowerIcons\":
|
||||||
3,\n \"intellectIcons\": 3,\n \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\":
|
3,\n \"intellectIcons\": 3,\n \"combatIcons\": 3,\n \"agilityIcons\": 3,\n \"cycle\":
|
||||||
\"The Dunwich Legacy\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\"The Dunwich Legacy\",\n \"extraToken\": \"None\",\n \"deck_requirements\": {\n
|
||||||
1,\n \"signatures\": [\n {\n \"98002\": 1,\n \"02010\": 1\n
|
\ \"size\": 30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n
|
||||||
\ },\n {\n \"98003\": 1,\n \"02011\": 1\n }\n ]\n
|
\ {\n \"98002\": 1,\n \"02010\": 1\n },\n {\n \"98003\":
|
||||||
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"rogue\",\n \"neutral\"\n
|
1,\n \"02011\": 1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\":
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n
|
[\n \"rogue\",\n \"neutral\"\n ],\n \"level\": {\n \"min\":
|
||||||
\ },\n {\n \"level\": {\n \"min\": 0,\n \"max\": 0\n },\n
|
0,\n \"max\": 5\n }\n },\n {\n \"level\": {\n \"min\":
|
||||||
\ \"limit\": 5,\n \"error\": \"You cannot have more than 5 cards that are
|
0,\n \"max\": 0\n },\n \"limit\": 5,\n \"error\": \"You cannot
|
||||||
not Rogue or Neutral\"\n }\n ]\n}"
|
have more than 5 cards that are not Rogue or Neutral\"\n }\n ]\n}"
|
||||||
GUID: 9058d3
|
GUID: 9058d3
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
@ -71,15 +71,15 @@ States:
|
|||||||
GMNotes: "{\n \"id\": \"02003\",\n \"alternate_ids\": [\n \"98001\"\n ],\n
|
GMNotes: "{\n \"id\": \"02003\",\n \"alternate_ids\": [\n \"98001\"\n ],\n
|
||||||
\ \"type\": \"Investigator\",\n \"class\": \"Rogue\",\n \"traits\": \"Drifter.\",\n
|
\ \"type\": \"Investigator\",\n \"class\": \"Rogue\",\n \"traits\": \"Drifter.\",\n
|
||||||
\ \"willpowerIcons\": 3,\n \"intellectIcons\": 3,\n \"combatIcons\": 3,\n
|
\ \"willpowerIcons\": 3,\n \"intellectIcons\": 3,\n \"combatIcons\": 3,\n
|
||||||
\ \"agilityIcons\": 3,\n \"cycle\": \"The Dunwich Legacy\",\n \"deck_requirements\":
|
\ \"agilityIcons\": 3,\n \"cycle\": \"The Dunwich Legacy\",\r\n \"extraToken\":
|
||||||
{\n \"size\": 30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\":
|
\"None\"\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
[\n {\n \"98002\": 1,\n \"02010\": 1\n },\n {\n
|
1,\n \"signatures\": [\n {\n \"98002\": 1,\n \"02010\":
|
||||||
\ \"98003\": 1,\n \"02011\": 1\n }\n ]\n },\n \"deck_options\":
|
1\n },\n {\n \"98003\": 1,\n \"02011\": 1\n }\n
|
||||||
[\n {\n \"faction\": [\n \"rogue\",\n \"neutral\"\n ],\n
|
\ ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"rogue\",\n
|
||||||
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ {\n \"level\": {\n \"min\": 0,\n \"max\": 0\n },\n
|
5\n }\n },\n {\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
\ \"limit\": 5,\n \"error\": \"You cannot have more than 5 cards that
|
0\n },\n \"limit\": 5,\n \"error\": \"You cannot have more than
|
||||||
are not Rogue or Neutral\"\n }\n ]\n}\n"
|
5 cards that are not Rogue or Neutral\"\n }\n ]\n}\n"
|
||||||
GUID: b954f6
|
GUID: b954f6
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,8 +21,8 @@ Description: The Musician
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"02004-pb\",\n \"type\": \"Investigator\",\n \"class\":
|
GMNotes: "{\n \"id\": \"02004-pb\",\n \"type\": \"Investigator\",\n \"class\":
|
||||||
\"Mystic\",\n \"traits\": \"Performer.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
\"Mystic\",\n \"traits\": \"Performer.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
||||||
3,\n \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"The Dunwich Legacy\",\n
|
3,\n \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"Laid to Rest\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 39,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 39,\n \"randomBasicWeaknessCount\":
|
||||||
1,\n \"signatures\": [\n {\n \"90050\": 1,\n \"02012\": 1\n
|
1,\n \"signatures\": [\n {\n \"90050\": 1,\n \"02012\": 1\n
|
||||||
\ },\n {\n \"90051\": 1,\n \"02013\": 1\n },\n {\n
|
\ },\n {\n \"90051\": 1,\n \"02013\": 1\n },\n {\n
|
||||||
\ \"90052\": 1\n },\n {\n \"90053\": 1\n }\n ]\n
|
\ \"90052\": 1\n },\n {\n \"90053\": 1\n }\n ]\n
|
||||||
|
@ -21,11 +21,11 @@ Description: The Musician
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"02004-pf\",\n \"type\": \"Investigator\",\n \"class\":
|
GMNotes: "{\n \"id\": \"02004-pf\",\n \"type\": \"Investigator\",\n \"class\":
|
||||||
\"Mystic\",\n \"traits\": \"Performer. Cursed.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
\"Mystic\",\n \"traits\": \"Performer. Cursed.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
||||||
3,\n \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"The Dunwich Legacy\",\n
|
3,\n \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"Laid to Rest\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\": 30,\n
|
||||||
1,\n \"signatures\": [\n {\n \"90050\": 1,\n \"02012\": 1\n
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"90050\":
|
||||||
\ },\n {\n \"90051\": 1,\n \"02013\": 1\n }\n ]\n
|
1,\n \"02012\": 1\n },\n {\n \"90051\": 1,\n \"02013\":
|
||||||
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
5\n }\n },\n {\n \"level\": {\n \"min\": 0,\n \"max\":
|
5\n }\n },\n {\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
0\n },\n \"limit\": 5,\n \"error\": \"You cannot have more than 5
|
0\n },\n \"limit\": 5,\n \"error\": \"You cannot have more than 5
|
||||||
|
@ -21,12 +21,12 @@ Description: The Musician
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"02004-p\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
GMNotes: "{\n \"id\": \"02004-p\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
||||||
\ \"traits\": \"Performer. Cursed.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
\ \"traits\": \"Performer. Cursed.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
||||||
3,\n \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"The Dunwich Legacy\",\n
|
3,\n \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"Laid to Rest\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 39,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\": 39,\n
|
||||||
1,\n \"signatures\": [\n {\n \"90050\": 1,\n \"02012\": 1\n
|
\ \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"90050\":
|
||||||
\ },\n {\n \"90051\": 1,\n \"02013\": 1\n },\n {\n
|
1,\n \"02012\": 1\n },\n {\n \"90051\": 1,\n \"02013\":
|
||||||
\ \"90052\": 1\n },\n {\n \"90053\": 1\n }\n ]\n
|
1\n },\n {\n \"90052\": 1\n },\n {\n \"90053\":
|
||||||
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"neutral\"\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"neutral\"\n
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n
|
||||||
\ },\n {\n \"faction\": [\n \"mystic\"\n ],\n \"level\":
|
\ },\n {\n \"faction\": [\n \"mystic\"\n ],\n \"level\":
|
||||||
{\n \"min\": 0,\n \"max\": 3\n }\n },\n {\n \"faction\":
|
{\n \"min\": 0,\n \"max\": 3\n }\n },\n {\n \"faction\":
|
||||||
|
@ -22,7 +22,7 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"02004\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
GMNotes: "{\n \"id\": \"02004\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
||||||
\ \"traits\": \"Performer.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": 3,\n
|
\ \"traits\": \"Performer.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\": 3,\n
|
||||||
\ \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"The Dunwich Legacy\",\n
|
\ \"combatIcons\": 3,\n \"agilityIcons\": 2,\n \"cycle\": \"The Dunwich Legacy\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
1,\n \"signatures\": [\n {\n \"90050\": 1,\n \"02012\": 1\n
|
1,\n \"signatures\": [\n {\n \"90050\": 1,\n \"02012\": 1\n
|
||||||
\ },\n {\n \"90051\": 1,\n \"02013\": 1\n }\n ]\n
|
\ },\n {\n \"90051\": 1,\n \"02013\": 1\n }\n ]\n
|
||||||
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
\ },\n \"deck_options\": [\n {\n \"faction\": [\n \"mystic\",\n
|
||||||
|
@ -21,7 +21,7 @@ Description: The Dead Speak (Advanced)
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"90050\",\n \"type\": \"Asset\",\n \"slot\": \"Hand\",\n
|
GMNotes: "{\n \"id\": \"90050\",\n \"type\": \"Asset\",\n \"slot\": \"Hand\",\n
|
||||||
\ \"class\": \"Neutral\",\n \"cost\": 2,\n \"traits\": \"Item. Instrument. Relic.\",\n
|
\ \"class\": \"Neutral\",\n \"cost\": 2,\n \"traits\": \"Item. Instrument. Relic.\",\n
|
||||||
\ \"willpowerIcons\": 2,\n \"wildIcons\": 2,\n \"cycle\": \"The Dunwich Legacy\"\n}"
|
\ \"willpowerIcons\": 2,\n \"wildIcons\": 2,\n \"cycle\": \"Laid to Rest\"\n}"
|
||||||
GUID: 7dfd5f
|
GUID: 7dfd5f
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,7 +22,7 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"05002\",\n \"type\": \"Investigator\",\n \"class\": \"Seeker\",\n
|
GMNotes: "{\n \"id\": \"05002\",\n \"type\": \"Investigator\",\n \"class\": \"Seeker\",\n
|
||||||
\ \"traits\": \"Detective.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\": 4,\n
|
\ \"traits\": \"Detective.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\": 4,\n
|
||||||
\ \"combatIcons\": 4,\n \"agilityIcons\": 2,\n \"cycle\": \"The Circle Undone\",\n
|
\ \"combatIcons\": 4,\n \"agilityIcons\": 2,\n \"cycle\": \"The Circle Undone\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 40,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 40,\n \"randomBasicWeaknessCount\":
|
||||||
1,\n \"signatures\": [\n {\n \"05009\": 1\n },\n {\n \"05010\":
|
1,\n \"signatures\": [\n {\n \"05009\": 1\n },\n {\n \"05010\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"seeker\",\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"seeker\",\n
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
|
@ -22,14 +22,15 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"10004\",\n \"type\": \"Investigator\",\n \"class\": \"Seeker\",\n
|
GMNotes: "{\n \"id\": \"10004\",\n \"type\": \"Investigator\",\n \"class\": \"Seeker\",\n
|
||||||
\ \"traits\": \"Miskatonic. Scholar.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\":
|
\ \"traits\": \"Miskatonic. Scholar.\",\n \"willpowerIcons\": 2,\n \"intellectIcons\":
|
||||||
4,\n \"combatIcons\": 2,\n \"agilityIcons\": 4,\n \"cycle\": \"The Feast of Hemlock
|
4,\n \"combatIcons\": 2,\n \"agilityIcons\": 4,\n \"cycle\": \"The Feast of Hemlock
|
||||||
Vale\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
Vale\",\n \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\":
|
||||||
1,\n \"signatures\": [\n {\n \"10005\": 1\n },\n {\n \"10008\":
|
30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"10005\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"seeker\",\n
|
1\n },\n {\n \"10008\": 1\n }\n ]\n },\n \"deck_options\":
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
[\n {\n \"faction\": [\n \"seeker\",\n \"neutral\"\n ],\n
|
||||||
5\n }\n },\n {\n \"trait\": [\n \"science\"\n ],\n \"level\":
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
||||||
{\n \"min\": 0,\n \"max\": 4\n }\n },\n {\n \"trait\":
|
\ \"trait\": [\n \"science\"\n ],\n \"level\": {\n \"min\":
|
||||||
[\n \"insight\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
0,\n \"max\": 4\n }\n },\n {\n \"trait\": [\n \"insight\"\n
|
||||||
1\n }\n }\n ]\n}"
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 1\n }\n
|
||||||
|
\ }\n ]\n}"
|
||||||
GUID: ce2322
|
GUID: ce2322
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -22,7 +22,7 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"09008\",\n \"type\": \"Investigator\",\n \"class\": \"Rogue\",\n
|
GMNotes: "{\n \"id\": \"09008\",\n \"type\": \"Investigator\",\n \"class\": \"Rogue\",\n
|
||||||
\ \"traits\": \"Criminal.\",\n \"willpowerIcons\": 3,\n \"intellectIcons\": 2,\n
|
\ \"traits\": \"Criminal.\",\n \"willpowerIcons\": 3,\n \"intellectIcons\": 2,\n
|
||||||
\ \"combatIcons\": 2,\n \"agilityIcons\": 5,\n \"cycle\": \"The Scarlet Keys\",\n
|
\ \"combatIcons\": 2,\n \"agilityIcons\": 5,\n \"cycle\": \"The Scarlet Keys\",\n
|
||||||
\ \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
\ \"extraToken\": \"None\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
||||||
1,\n \"signatures\": [\n {\n \"09009\": 1\n },\n {\n \"09010\":
|
1,\n \"signatures\": [\n {\n \"09009\": 1\n },\n {\n \"09010\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"neutral\",\n
|
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"neutral\",\n
|
||||||
\ \"rogue\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
\ \"rogue\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,44 @@
|
|||||||
|
<!-- include playercards/KohakuNarukami.xml -->
|
||||||
|
<Defaults>
|
||||||
|
<Button padding="50 50 50 50"
|
||||||
|
font="font_teutonic-arkham"
|
||||||
|
fontSize="200"
|
||||||
|
iconWidth="300"
|
||||||
|
iconAlignment="Right"/>
|
||||||
|
<TableLayout position="0 188 -22"
|
||||||
|
rotation="0 0 90"
|
||||||
|
height="1800"
|
||||||
|
width="700"
|
||||||
|
scale="0.1 0.1 1"
|
||||||
|
cellSpacing="80"
|
||||||
|
cellBackgroundColor="rgba(1,1,1,0)"/>
|
||||||
|
</Defaults>
|
||||||
|
|
||||||
|
<TableLayout id="Helper"
|
||||||
|
active="false">
|
||||||
|
<Row>
|
||||||
|
<Cell>
|
||||||
|
<Button id="Bless"
|
||||||
|
icon="token-bless"/>
|
||||||
|
</Cell>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Cell>
|
||||||
|
<Button id="Curse"
|
||||||
|
icon="token-curse"/>
|
||||||
|
</Cell>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Cell>
|
||||||
|
<Button id="Action"
|
||||||
|
text="Remove tokens"/>
|
||||||
|
</Cell>
|
||||||
|
</Row>
|
||||||
|
<Row>
|
||||||
|
<Cell>
|
||||||
|
<Button id="ElderSign"
|
||||||
|
icon="token-eldersign"/>
|
||||||
|
</Cell>
|
||||||
|
</Row>
|
||||||
|
</TableLayout>
|
||||||
|
<!-- include playercards/KohakuNarukami.xml -->
|
@ -22,16 +22,16 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"10012\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
GMNotes: "{\n \"id\": \"10012\",\n \"type\": \"Investigator\",\n \"class\": \"Mystic\",\n
|
||||||
\ \"traits\": \"Scholar. Blessed. Cursed.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
\ \"traits\": \"Scholar. Blessed. Cursed.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
||||||
4,\n \"combatIcons\": 3,\n \"agilityIcons\": 1,\n \"cycle\": \"The Feast of Hemlock
|
4,\n \"combatIcons\": 3,\n \"agilityIcons\": 1,\n \"cycle\": \"The Feast of Hemlock
|
||||||
Vale\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
Vale\",\n \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\":
|
||||||
1,\n \"signatures\": [\n {\n \"10013\": 1\n },\n {\n \"10014\":
|
30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"10013\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"neutral\"\n
|
1\n },\n {\n \"10014\": 1\n }\n ]\n },\n \"deck_options\":
|
||||||
|
[\n {\n \"faction\": [\n \"neutral\"\n ],\n \"level\":
|
||||||
|
{\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n \"faction\":
|
||||||
|
[\n \"mystic\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
||||||
|
3\n }\n },\n {\n \"trait\": [\n \"blessed\",\n \"cursed\"\n
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n
|
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n
|
||||||
\ },\n {\n \"faction\": [\n \"mystic\"\n ],\n \"level\":
|
\ },\n {\n \"trait\": [\n \"occult\"\n ],\n \"level\":
|
||||||
{\n \"min\": 0,\n \"max\": 3\n }\n },\n {\n \"trait\":
|
{\n \"min\": 0,\n \"max\": 0\n }\n }\n ]\n}"
|
||||||
[\n \"blessed\",\n \"cursed\"\n ],\n \"level\": {\n \"min\":
|
|
||||||
0,\n \"max\": 5\n }\n },\n {\n \"trait\": [\n \"occult\"\n
|
|
||||||
\ ],\n \"level\": {\n \"min\": 0,\n \"max\": 0\n }\n
|
|
||||||
\ }\n ]\n}"
|
|
||||||
GUID: 54eaa7
|
GUID: 54eaa7
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
@ -40,7 +40,7 @@ HideWhenFaceDown: true
|
|||||||
IgnoreFoW: false
|
IgnoreFoW: false
|
||||||
LayoutGroupSortIndex: 0
|
LayoutGroupSortIndex: 0
|
||||||
Locked: false
|
Locked: false
|
||||||
LuaScript: ''
|
LuaScript: !include "Card K\u014Dhaku Narukami 54eaa7.ttslua"
|
||||||
LuaScriptState: ''
|
LuaScriptState: ''
|
||||||
MeasureMovement: false
|
MeasureMovement: false
|
||||||
Name: Card
|
Name: Card
|
||||||
@ -63,4 +63,4 @@ Transform:
|
|||||||
scaleY: 1
|
scaleY: 1
|
||||||
scaleZ: 1.15
|
scaleZ: 1.15
|
||||||
Value: 0
|
Value: 0
|
||||||
XmlUI: ''
|
XmlUI: !include "Card K\u014Dhaku Narukami 54eaa7.xml"
|
||||||
|
@ -22,12 +22,13 @@ DragSelectable: true
|
|||||||
GMNotes: "{\n \"id\": \"04001\",\n \"type\": \"Investigator\",\n \"class\": \"Guardian\",\n
|
GMNotes: "{\n \"id\": \"04001\",\n \"type\": \"Investigator\",\n \"class\": \"Guardian\",\n
|
||||||
\ \"traits\": \"Veteran. Wayfarer.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
\ \"traits\": \"Veteran. Wayfarer.\",\n \"willpowerIcons\": 4,\n \"intellectIcons\":
|
||||||
3,\n \"combatIcons\": 4,\n \"agilityIcons\": 1,\n \"cycle\": \"The Forgotten
|
3,\n \"combatIcons\": 4,\n \"agilityIcons\": 1,\n \"cycle\": \"The Forgotten
|
||||||
Age\",\n \"deck_requirements\": {\n \"size\": 30,\n \"randomBasicWeaknessCount\":
|
Age\",\n \"extraToken\": \"Reaction\",\n \"deck_requirements\": {\n \"size\":
|
||||||
1,\n \"signatures\": [\n {\n \"04006\": 1\n },\n {\n \"04007\":
|
30,\n \"randomBasicWeaknessCount\": 1,\n \"signatures\": [\n {\n \"04006\":
|
||||||
1\n }\n ]\n },\n \"deck_options\": [\n {\n \"faction\": [\n \"guardian\",\n
|
1\n },\n {\n \"04007\": 1\n }\n ]\n },\n \"deck_options\":
|
||||||
\ \"neutral\"\n ],\n \"level\": {\n \"min\": 0,\n \"max\":
|
[\n {\n \"faction\": [\n \"guardian\",\n \"neutral\"\n ],\n
|
||||||
5\n }\n },\n {\n \"faction\": [\n \"rogue\"\n ],\n \"level\":
|
\ \"level\": {\n \"min\": 0,\n \"max\": 5\n }\n },\n {\n
|
||||||
{\n \"min\": 0,\n \"max\": 2\n }\n }\n ]\n}"
|
\ \"faction\": [\n \"rogue\"\n ],\n \"level\": {\n \"min\":
|
||||||
|
0,\n \"max\": 2\n }\n }\n ]\n}"
|
||||||
GUID: '126932'
|
GUID: '126932'
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
@ -21,7 +21,9 @@ Description: The Louisiana Lion
|
|||||||
DragSelectable: true
|
DragSelectable: true
|
||||||
GMNotes: "{\n \"id\": \"01054\",\n \"alternate_ids\": [\n \"01554\"\n ],\n \"type\":
|
GMNotes: "{\n \"id\": \"01054\",\n \"alternate_ids\": [\n \"01554\"\n ],\n \"type\":
|
||||||
\"Asset\",\n \"slot\": \"Ally\",\n \"class\": \"Rogue\",\n \"cost\": 5,\n \"level\":
|
\"Asset\",\n \"slot\": \"Ally\",\n \"class\": \"Rogue\",\n \"cost\": 5,\n \"level\":
|
||||||
1,\n \"traits\": \"Ally. Criminal.\",\n \"intellectIcons\": 1,\n \"cycle\": \"Core\"\n}"
|
1,\n \"traits\": \"Ally. Criminal.\",\n \"intellectIcons\": 1,\n \"uses\": [\n
|
||||||
|
\ {\n \"count\": 1,\n \"type\": \"Universal\",\n \"token\": \"universalActionAbility\"\n
|
||||||
|
\ }\n ],\n \"cycle\": \"Core\"\n}"
|
||||||
GUID: 27446e
|
GUID: 27446e
|
||||||
Grid: true
|
Grid: true
|
||||||
GridProjection: false
|
GridProjection: false
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user