Merge branch 'master' into patches
This commit is contained in:
commit
85cb7bc7e2
2009
unpacked.ttslua
2009
unpacked.ttslua
File diff suppressed because it is too large
Load Diff
124
unpacked.xml
124
unpacked.xml
@ -567,16 +567,13 @@
|
||||
<!-- Default formatting -->
|
||||
<Defaults>
|
||||
<Text color="#FFFFFF"
|
||||
alignment="MiddleLeft" />
|
||||
alignment="MiddleLeft"/>
|
||||
|
||||
<Toggle isOn="False"
|
||||
rectAlignment="MiddleRight" />
|
||||
|
||||
<Dropdown rectAlignment="MiddleCenter" />
|
||||
<Dropdown rectAlignment="MiddleCenter"/>
|
||||
|
||||
<Cell dontUseTableCellBackground="true"
|
||||
outlineSize="0 1"
|
||||
outline="grey" />
|
||||
outline="grey"/>
|
||||
|
||||
<!-- main window -->
|
||||
<TableLayout class="window"
|
||||
@ -588,20 +585,20 @@
|
||||
outline="grey"
|
||||
showAnimation="SlideIn_Right"
|
||||
hideAnimation="SlideOut_Right"
|
||||
animationDuration="0.2" />
|
||||
animationDuration="0.2"/>
|
||||
|
||||
<!-- group headers -->
|
||||
<Row class="group-header"
|
||||
preferredHeight="44" />
|
||||
preferredHeight="44"/>
|
||||
<Cell class="group-header"
|
||||
padding="10 10 0 0"
|
||||
columnSpan="3"
|
||||
color="#222222" />
|
||||
color="#222222"/>
|
||||
<Panel class="group-header"
|
||||
padding="5 0 0 0" />
|
||||
padding="5 0 0 0"/>
|
||||
<Text class="group-header"
|
||||
fontSize="28"
|
||||
font="font_teutonic-arkham" />
|
||||
font="font_teutonic-arkham"/>
|
||||
|
||||
<!-- options -->
|
||||
<Row class="option-text"
|
||||
@ -630,6 +627,14 @@
|
||||
font="font_teutonic-arkham"/>
|
||||
<Panel class="doubleColumn-wrapper"
|
||||
padding="0 17 3 3"/>
|
||||
<Button class="optionToggle"
|
||||
image="option_off"
|
||||
rectAlignment="MiddleRight"
|
||||
offsetXY="-30 0"
|
||||
colors="#FFFFFF|#dfdfdf"
|
||||
height="36"
|
||||
width="65"
|
||||
ignoreLayout="True"/>
|
||||
|
||||
<!-- buttons at the bottom -->
|
||||
<Button class="bottomButtons"
|
||||
@ -716,8 +721,24 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="showTitleSplash"
|
||||
onValueChanged="onClick_toggleOption(showTitleSplash)"/>
|
||||
<Button class="optionToggle"
|
||||
id="showTitleSplash"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</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>
|
||||
|
||||
@ -740,8 +761,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="playAreaSnapTags"
|
||||
onValueChanged="onClick_toggleOption(playAreaSnapTags)"/>
|
||||
<Button class="optionToggle"
|
||||
id="playAreaSnapTags"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
@ -754,8 +776,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="playAreaConnections"
|
||||
onValueChanged="onClick_toggleOption(playAreaConnections)"/>
|
||||
<Button class="optionToggle"
|
||||
id="playAreaConnections"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
@ -785,8 +808,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="changePlayAreaImage"
|
||||
onValueChanged="onClick_toggleOption(changePlayAreaImage)"/>
|
||||
<Button class="optionToggle"
|
||||
id="changePlayAreaImage"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
@ -809,8 +833,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="useSnapTags"
|
||||
onValueChanged="onClick_toggleOption(useSnapTags)"/>
|
||||
<Button class="optionToggle"
|
||||
id="useSnapTags"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
@ -823,8 +848,24 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="showDrawButton"
|
||||
onValueChanged="onClick_toggleOption(showDrawButton)"/>
|
||||
<Button class="optionToggle"
|
||||
id="showDrawButton"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</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>
|
||||
|
||||
@ -837,8 +878,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="useClueClickers"
|
||||
onValueChanged="onClick_toggleOption(useClueClickers)"/>
|
||||
<Button class="optionToggle"
|
||||
id="useClueClickers"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
@ -862,7 +904,7 @@
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
<!-- Option: remove a player mat -->
|
||||
<!-- Option: remove a playermat -->
|
||||
<Row class="option-text"
|
||||
tooltip="Remove an unused playermat for more table space.
Displayed are the default colors.">
|
||||
<Cell class="option-singleColumn">
|
||||
@ -903,8 +945,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="showAttachmentHelper"
|
||||
onValueChanged="onClick_toggleOption(showAttachmentHelper)"/>
|
||||
<Button class="optionToggle"
|
||||
id="showAttachmentHelper"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
@ -917,8 +960,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="showCleanUpHelper"
|
||||
onValueChanged="onClick_toggleOption(showCleanUpHelper)"/>
|
||||
<Button class="optionToggle"
|
||||
id="showCleanUpHelper"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
@ -931,8 +975,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="showCYOA"
|
||||
onValueChanged="onClick_toggleOption(showCYOA)"/>
|
||||
<Button class="optionToggle"
|
||||
id="showCYOA"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
@ -945,8 +990,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="showDisplacementTool"
|
||||
onValueChanged="onClick_toggleOption(showDisplacementTool)"/>
|
||||
<Button class="optionToggle"
|
||||
id="showDisplacementTool"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
@ -959,8 +1005,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="showHandHelper"
|
||||
onValueChanged="onClick_toggleOption(showHandHelper)"/>
|
||||
<Button class="optionToggle"
|
||||
id="showHandHelper"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
|
||||
@ -973,8 +1020,9 @@
|
||||
</Panel>
|
||||
</Cell>
|
||||
<Cell class="option-button">
|
||||
<Toggle id="showSearchAssistant"
|
||||
onValueChanged="onClick_toggleOption(showSearchAssistant)"/>
|
||||
<Button class="optionToggle"
|
||||
id="showSearchAssistant"
|
||||
onClick="onClick_toggleOption"/>
|
||||
</Cell>
|
||||
</Row>
|
||||
</TableLayout>
|
||||
|
356
unpacked.yaml
356
unpacked.yaml
@ -71,33 +71,18 @@ ComponentTags:
|
||||
normalized: investigator
|
||||
- displayed: chaosBag
|
||||
normalized: chaosbag
|
||||
- displayed: ActionToken
|
||||
normalized: actiontoken
|
||||
- displayed: LargeBox
|
||||
normalized: largebox
|
||||
- displayed: CampaignBox
|
||||
normalized: campaignbox
|
||||
- displayed: CameraZoom_ignore
|
||||
normalized: camerazoom_ignore
|
||||
- displayed: UniversalToken
|
||||
normalized: universaltoken
|
||||
CustomUIAssets:
|
||||
- Name: refresh
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/1695031152736214852/EC3BBEF1A1788381A8F4C5ACB7FB27770CAF03C5/
|
||||
- Name: close
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/1695031152736214756/2EEB07E453A7ECF4BE5A1030A253185B37A7CDAB/
|
||||
- Name: cthulhu
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/1782854877010107768/BC6A97F193385D01C1A9149B68923F55A284CB2D/
|
||||
- Name: dark-cult
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/1782854877010108105/08594607341D6537C28A08A34CE82159025AB8DB/
|
||||
- Name: yog-sothoth
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/1782854877010107124/D8042D1A1B08CFB7E76488B09216B4611D85A2B9/
|
||||
- Name: elder-sign
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/1782854877010107442/43BC029410751208A90AE7FDEBCB587A0E9403D7/
|
||||
- Name: devourer
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/1782854877010106784/6E00433E3425D0A7C6121E0DDB6A79167BA78569/
|
||||
@ -113,24 +98,18 @@ CustomUIAssets:
|
||||
- Name: option-gear
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2026086584372569912/5CB461AEAE2E59D3064D90A776EB86C46081EC78/
|
||||
- Name: font_birmingham
|
||||
- Name: option_on
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2462982115668997008/2178787B67B3C96F3419EDBAB8420E39893756BC/
|
||||
- Name: option_off
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2462982115668996901/D6438ECBB11DECC6DB9987589FF526FBAD4D2368/
|
||||
- Name: font_arkhamicons
|
||||
Type: 1
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2027213118466443497/3CF9BB9AF968D245961494CC9A151774EB9BA638/
|
||||
- Name: font_columbus
|
||||
Type: 1
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2027213118466515872/F473E4ACC75ACB6CE07457C45290B4912E0B3286/
|
||||
- Name: font_oldremington
|
||||
Type: 1
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2027213118466515932/AFCE53F1E1D9580D166F53AD9EB0D77A331D4A26/
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2462982115649258367/C20CC4C299A6FE5F1ECAB968E15BE590337CC019/
|
||||
- Name: font_teutonic-arkham
|
||||
Type: 1
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2027213118467703445/89328E273B4C5180BF491516CE998DE3C604E162/
|
||||
- Name: font_uglyqua
|
||||
Type: 1
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2027213118466516005/113C19D37CFFA9E554394FD5B11B32967F846A62/
|
||||
- Name: font_chinese_fzlibian
|
||||
Type: 1
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2028355502896482829/8DAB311590B97586309E66D795AC2C43D4913188/
|
||||
- Name: header_cover
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2280574378889753624/53E7443E2A9957BC5CA4D73B67D5C1C30971C9F9/
|
||||
@ -143,24 +122,18 @@ CustomUIAssets:
|
||||
- Name: header_olive
|
||||
Type: 0
|
||||
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
|
||||
Type: 0
|
||||
URL: https://i.imgur.com/6MReiEO.png
|
||||
- Name: Inv-Roland
|
||||
Type: 0
|
||||
URL: https://i.imgur.com/lx6unDY.png
|
||||
- Name: NextArrow
|
||||
Type: 0
|
||||
URL: https://i.imgur.com/MztSQis.png
|
||||
- Name: Exit
|
||||
Type: 0
|
||||
URL: https://i.imgur.com/8qmTXwt.png
|
||||
- Name: Inv-Roland
|
||||
Type: 0
|
||||
URL: https://i.imgur.com/lx6unDY.png
|
||||
- Name: Inv-Mandy
|
||||
Type: 0
|
||||
URL: https://i.imgur.com/hniMC5g.png
|
||||
@ -224,7 +197,37 @@ CustomUIAssets:
|
||||
- Name: box-cover-mask-wide
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2115061298538827369/A20C2ECB8ECDC1B0AD8B2B38F68CA1C1F5E07D37/
|
||||
Date: Mon Mar 4 23:52:37 CET 2024
|
||||
- Name: token-skull
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2380784374775547231/E0FEEF462DE4E7704832CA2415D0D027A6BF5041/
|
||||
- Name: token-bless
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2380784374775547028/7855033DE0EB1FDDF706E1303054D35FE0902532/
|
||||
- Name: token-curse
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2380784374775547135/2360372CBE9452CB7B4D135BE13BBA6D46B7D427/
|
||||
- Name: token-cultist
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2380784374792650461/10D8037632900AA86045BDD42A564716D5855B1B/
|
||||
- Name: token-tablet
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2380784374792650857/29DAE514E5C838C24C90ABBFFF92B1359B9A2F76/
|
||||
- Name: token-elder-thing
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2380784374792650683/1C046B6335317CA1AEBFC80645EEC18852D83D80/
|
||||
- Name: token-frost
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2380784374792650766/73E07A50BE6FD9BED266F3421B472C4BF913DE81/
|
||||
- Name: token-auto-fail
|
||||
Type: 0
|
||||
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
|
||||
Type: 0
|
||||
URL: http://cloud-3.steamusercontent.com/ugc/2380784374792650571/E4C2B2B69282A4EE15FE290FF6B08BEFC8FCA65C/
|
||||
Date: Mon Jul 8 20:19:48 CEST 2024
|
||||
DecalPallet:
|
||||
- ImageURL: http://cloud-3.steamusercontent.com/ugc/1474319121424323663/BC5570ECF747F1B30224461B576E8B0FE7FA5F33/
|
||||
Name: Achivement Checkmark
|
||||
@ -233,7 +236,7 @@ DecalPallet:
|
||||
Name: Victory Display
|
||||
Size: 15
|
||||
Decals: []
|
||||
EpochTime: 1709592757
|
||||
EpochTime: 1720462788
|
||||
GameComplexity: ''
|
||||
GameMode: Arkham Horror LCG - Super Complete Edition
|
||||
GameType: ''
|
||||
@ -284,7 +287,7 @@ Lighting:
|
||||
LutIndex: 0
|
||||
ReflectionIntensity: 1
|
||||
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:
|
||||
AudioLibrary:
|
||||
- Item1: http://cloud-3.steamusercontent.com/ugc/784110538847453001/4481D1CC5684FCF04AB143954DEFE09E94BF5CEB/
|
||||
@ -342,11 +345,14 @@ MusicPlayer:
|
||||
Note: ''
|
||||
ObjectStates:
|
||||
- !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/HandTrigger 5fe087.yaml'
|
||||
- !include 'unpacked/HandTrigger be2f17.yaml'
|
||||
- !include 'unpacked/HandTrigger 0285cc.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 TableLegBottomLeft c8edca.yaml'
|
||||
- !include 'unpacked/Custom_Assetbundle TableLegTopLeft 393bf7.yaml'
|
||||
@ -402,7 +408,9 @@ ObjectStates:
|
||||
- !include 'unpacked/Custom_Model_Bag Trash 5f896a.yaml'
|
||||
- !include 'unpacked/Custom_Model_Bag Trash 147e80.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 Latest FAQ faqfaq.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 3b2550.yaml'
|
||||
@ -416,8 +424,6 @@ ObjectStates:
|
||||
- !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 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 Clue Counter 37be78.yaml'
|
||||
- !include 'unpacked/Custom_Model Clue Counter 1769ed.yaml'
|
||||
@ -426,8 +432,7 @@ ObjectStates:
|
||||
- !include 'unpacked/Custom_Token Master Clue Counter 4a3aa4.yaml'
|
||||
- !include 'unpacked/Custom_Model_Bag Legacy Assets 7165a9.yaml'
|
||||
- !include 'unpacked/Custom_Token Play Area 721ba2.yaml'
|
||||
- !include 'unpacked/Bag Additional Player Cards 2cba6b.yaml'
|
||||
- !include 'unpacked/Custom_Assetbundle_Bag Barkham Horror 308439.yaml'
|
||||
- !include 'unpacked/Custom_Model_Bag Additional Player Cards 2cba6b.yaml'
|
||||
- !include 'unpacked/Custom_Token Chaos Bag Stat Tracker 766620.yaml'
|
||||
- !include 'unpacked/Checker_white Token Spawn Tool 36b4ee.yaml'
|
||||
- !include 'unpacked/Custom_Model_Bag Standalone Scenarios 77a5f9.yaml'
|
||||
@ -448,8 +453,6 @@ ObjectStates:
|
||||
- !include 'unpacked/Custom_Model_Bag Chaos Bag fea079.yaml'
|
||||
- !include 'unpacked/Custom_Tile Data Helper 708279.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 The Dream-Eaters a16a1a.yaml'
|
||||
- !include 'unpacked/Custom_Model The Feast of Hemlock Vale c740af.yaml'
|
||||
@ -459,27 +462,11 @@ ObjectStates:
|
||||
- !include 'unpacked/Custom_Tile Playermat 2 Orange bd0ff4.yaml'
|
||||
- !include 'unpacked/Custom_Tile Playermat 3 Green 383d8b.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_Tile ArkhamDB Deck Importer a28140.yaml'
|
||||
- !include 'unpacked/Checker_white Configuration 03804b.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/Custom_Token Investigator Skill Tracker af7ed7.yaml'
|
||||
- !include 'unpacked/Custom_Token Investigator Skill Tracker e598c2.yaml'
|
||||
@ -500,7 +487,6 @@ ObjectStates:
|
||||
- !include 'unpacked/Custom_Tile Token Remover 2ba7a5.yaml'
|
||||
- !include 'unpacked/Custom_Tile Token Remover 0a5a29.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 975c39.yaml'
|
||||
- !include 'unpacked/BlockRectangle Table Divider 75937e.yaml'
|
||||
@ -509,10 +495,10 @@ ObjectStates:
|
||||
- !include 'unpacked/Custom_Model Decoration - Ammo b43845.yaml'
|
||||
- !include 'unpacked/Custom_Model Decoration - Ammo d35ee9.yaml'
|
||||
- !include 'unpacked/Custom_Token Victory Display 6ccd6d.yaml'
|
||||
- !include 'unpacked/Custom_Tile Campaign Overview e03c01.yaml'
|
||||
- !include 'unpacked/Custom_Tile Official Releases Overview 8e22bb.yaml'
|
||||
- !include 'unpacked/Custom_Tile Fan-Made Expansion Overview de7cae.yaml'
|
||||
- !include 'unpacked/Bag OptionPanel Source 830bd0.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/3DText d628cc.yaml'
|
||||
- !include 'unpacked/go_game_piece_black Navigation Overlay Handler 797ede.yaml'
|
||||
@ -520,7 +506,7 @@ ObjectStates:
|
||||
- !include 'unpacked/Custom_Token Token Arranger 022907.yaml'
|
||||
- !include 'unpacked/Custom_Tile Chaos Bag Manager 023240.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_0 0a8592.yaml'
|
||||
- !include 'unpacked/Custom_Tile Tokencache_-1 b644d2.yaml'
|
||||
@ -541,6 +527,18 @@ ObjectStates:
|
||||
- !include 'unpacked/Custom_Tile Tokencache_Curse 16a9a7.yaml'
|
||||
- !include 'unpacked/Custom_Tile Tokencache_Frost b2b7be.yaml'
|
||||
- !include 'unpacked/BlockSquare Physics Detector b300d8.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
|
||||
PlayerCounts:
|
||||
- 0
|
||||
@ -548,7 +546,7 @@ PlayerCounts:
|
||||
PlayingTime:
|
||||
- 0
|
||||
- 0
|
||||
SaveName: Arkham SCE - 3.7.0
|
||||
SaveName: Arkham SCE - 3.9.0
|
||||
Sky: Sky_Museum
|
||||
SkyURL: https://i.imgur.com/GkQqaOF.jpg
|
||||
SnapPoints:
|
||||
@ -736,182 +734,80 @@ SnapPoints:
|
||||
x: -26
|
||||
y: 1.48
|
||||
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:
|
||||
'10':
|
||||
body: "Created by Whimsical\n\nAnything that passes over the remover that isn't
|
||||
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
|
||||
to your play area first."
|
||||
'1':
|
||||
body: 'Welcome to Arkham Horror LCG - Super Complete Edition!
|
||||
|
||||
|
||||
Make sure to take the tour that can be started with the token in the middle
|
||||
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
|
||||
id: 10
|
||||
title: Token Remover
|
||||
id: 1
|
||||
title: Basic Intro
|
||||
visibleColor:
|
||||
b: 0.5
|
||||
g: 0.5
|
||||
r: 0.5
|
||||
'11':
|
||||
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':
|
||||
'2':
|
||||
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,
|
||||
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
|
||||
their own hand.
|
||||
color: Grey
|
||||
id: 7
|
||||
id: 2
|
||||
title: How to Hide Hands
|
||||
visibleColor:
|
||||
b: 0.5
|
||||
g: 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
|
||||
Tags: []
|
||||
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,13 +45,16 @@ __bundle_register("__root", function(require, _LOADED, __bundle_register, __bund
|
||||
require("playercards/AllCardsBag")
|
||||
end)
|
||||
__bundle_register("playercards/AllCardsBag", function(require, _LOADED, __bundle_register, __bundle_modules)
|
||||
local cardIdIndex = { }
|
||||
local classAndLevelIndex = { }
|
||||
local basicWeaknessList = { }
|
||||
local uniqueWeaknessList = { }
|
||||
local cycleIndex = { }
|
||||
local guidReferenceApi = require("core/GUIDReferenceApi")
|
||||
|
||||
local cardIdIndex = {}
|
||||
local classAndLevelIndex = {}
|
||||
local basicWeaknessList = {}
|
||||
local uniqueWeaknessList = {}
|
||||
local cycleIndex = {}
|
||||
|
||||
local indexingDone = false
|
||||
local otherCardsDetected = false
|
||||
|
||||
function onLoad()
|
||||
self.addContextMenuItem("Rebuild Index", startIndexBuild)
|
||||
@ -59,13 +62,13 @@ function onLoad()
|
||||
Wait.frames(startIndexBuild, 30)
|
||||
end
|
||||
|
||||
-- Called by Hotfix bags when they load. If we are still loading indexes, then
|
||||
-- Called by Hotfix bags when they load. If we are still loading indexes, then
|
||||
-- the all cards and hotfix bags are being loaded together, and we can ignore
|
||||
-- this call as the hotfix will be included in the initial indexing. If it is
|
||||
-- this call as the hotfix will be included in the initial indexing. If it is
|
||||
-- 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.
|
||||
function rebuildIndexForHotfix()
|
||||
if (indexingDone) then
|
||||
if indexingDone then
|
||||
startIndexBuild()
|
||||
end
|
||||
end
|
||||
@ -73,23 +76,23 @@ end
|
||||
-- Resets all current bag indexes
|
||||
function clearIndexes()
|
||||
indexingDone = false
|
||||
cardIdIndex = { }
|
||||
classAndLevelIndex = { }
|
||||
classAndLevelIndex["Guardian-upgrade"] = { }
|
||||
classAndLevelIndex["Seeker-upgrade"] = { }
|
||||
classAndLevelIndex["Mystic-upgrade"] = { }
|
||||
classAndLevelIndex["Survivor-upgrade"] = { }
|
||||
classAndLevelIndex["Rogue-upgrade"] = { }
|
||||
classAndLevelIndex["Neutral-upgrade"] = { }
|
||||
classAndLevelIndex["Guardian-level0"] = { }
|
||||
classAndLevelIndex["Seeker-level0"] = { }
|
||||
classAndLevelIndex["Mystic-level0"] = { }
|
||||
classAndLevelIndex["Survivor-level0"] = { }
|
||||
classAndLevelIndex["Rogue-level0"] = { }
|
||||
classAndLevelIndex["Neutral-level0"] = { }
|
||||
cycleIndex = { }
|
||||
basicWeaknessList = { }
|
||||
uniqueWeaknessList = { }
|
||||
cardIdIndex = {}
|
||||
classAndLevelIndex = {}
|
||||
classAndLevelIndex["Guardian-upgrade"] = {}
|
||||
classAndLevelIndex["Seeker-upgrade"] = {}
|
||||
classAndLevelIndex["Mystic-upgrade"] = {}
|
||||
classAndLevelIndex["Survivor-upgrade"] = {}
|
||||
classAndLevelIndex["Rogue-upgrade"] = {}
|
||||
classAndLevelIndex["Neutral-upgrade"] = {}
|
||||
classAndLevelIndex["Guardian-level0"] = {}
|
||||
classAndLevelIndex["Seeker-level0"] = {}
|
||||
classAndLevelIndex["Mystic-level0"] = {}
|
||||
classAndLevelIndex["Survivor-level0"] = {}
|
||||
classAndLevelIndex["Rogue-level0"] = {}
|
||||
classAndLevelIndex["Neutral-level0"] = {}
|
||||
cycleIndex = {}
|
||||
basicWeaknessList = {}
|
||||
uniqueWeaknessList = {}
|
||||
end
|
||||
|
||||
-- Clears the bag indexes and starts the coroutine to rebuild the indexes
|
||||
@ -104,287 +107,372 @@ function onObjectLeaveContainer(container, _)
|
||||
end
|
||||
end
|
||||
|
||||
-- Create the card indexes by iterating all cards in the bag, parsing their
|
||||
-- metadata, and creating the keyed lookup tables for the cards. This is a
|
||||
-- coroutine which will spread the workload by processing 20 cards before
|
||||
-- yielding. Based on the current count of cards this will require
|
||||
-- approximately 60 frames to complete.
|
||||
-- Create the card indexes by iterating all cards in the bag, parsing their metadata
|
||||
-- and creating the keyed lookup tables for the cards. This is a coroutine which will
|
||||
-- spread the workload by processing 20 cards before yielding.
|
||||
function buildIndex()
|
||||
local cardCount = 0
|
||||
indexingDone = false
|
||||
if (self.getData().ContainedObjects == nil) then
|
||||
return 1
|
||||
end
|
||||
for i, cardData in ipairs(self.getData().ContainedObjects) do
|
||||
local cardMetadata = JSON.decode(cardData.GMNotes)
|
||||
if (cardMetadata ~= nil) then
|
||||
addCardToIndex(cardData, cardMetadata)
|
||||
cardCount = cardCount + 1
|
||||
if cardCount > 9 then
|
||||
cardCount = 0
|
||||
coroutine.yield(0)
|
||||
end
|
||||
otherCardsDetected = false
|
||||
|
||||
-- process the allcardsbag itself
|
||||
for _, cardData in ipairs(self.getData().ContainedObjects) do
|
||||
addCardToIndex(cardData)
|
||||
cardCount = cardCount + 1
|
||||
if cardCount > 19 then
|
||||
cardCount = 0
|
||||
coroutine.yield(0)
|
||||
end
|
||||
end
|
||||
local hotfixBags = getObjectsWithTag("AllCardsHotfix")
|
||||
for _, hotfixBag in ipairs(hotfixBags) do
|
||||
if (#hotfixBag.getObjects() > 0) then
|
||||
for i, cardData in ipairs(hotfixBag.getData().ContainedObjects) do
|
||||
if cardData.ContainedObjects then
|
||||
for j, deepCardData in ipairs(cardData.ContainedObjects) do
|
||||
local deepCardMetadata = JSON.decode(deepCardData.GMNotes)
|
||||
if deepCardMetadata ~= nil then
|
||||
addCardToIndex(deepCardData, deepCardMetadata)
|
||||
cardCount = cardCount + 1
|
||||
if cardCount > 9 then
|
||||
cardCount = 0
|
||||
coroutine.yield(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
local cardMetadata = JSON.decode(cardData.GMNotes)
|
||||
if cardMetadata ~= nil then
|
||||
addCardToIndex(cardData, cardMetadata)
|
||||
cardCount = cardCount + 1
|
||||
if cardCount > 9 then
|
||||
cardCount = 0
|
||||
coroutine.yield(0)
|
||||
end
|
||||
|
||||
-- process hotfix bags (and the additional playercards bag)
|
||||
for _, hotfixBag in ipairs(getObjectsWithTag("AllCardsHotfix")) do
|
||||
local hotfixData = hotfixBag.getData()
|
||||
|
||||
-- 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
|
||||
if cardData.ContainedObjects then
|
||||
-- process containers
|
||||
for _, deepCardData in ipairs(cardData.ContainedObjects) do
|
||||
addCardToIndex(deepCardData)
|
||||
cardCount = cardCount + 1
|
||||
if cardCount > 19 then
|
||||
cardCount = 0
|
||||
coroutine.yield(0)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- process single cards
|
||||
addCardToIndex(cardData)
|
||||
cardCount = cardCount + 1
|
||||
if cardCount > 19 then
|
||||
cardCount = 0
|
||||
coroutine.yield(0)
|
||||
end
|
||||
end
|
||||
end
|
||||
::nextBag::
|
||||
end
|
||||
|
||||
buildSupplementalIndexes()
|
||||
updatePlayerCardPanel()
|
||||
indexingDone = true
|
||||
return 1
|
||||
end
|
||||
|
||||
-- Adds a card to any indexes it should be a part of, based on its metadata.
|
||||
-- Adds a card to any indexes it should be a part of, based on its metadata
|
||||
---@param cardData table TTS object data for the card
|
||||
---@param cardMetadata table SCED metadata for the card
|
||||
function addCardToIndex(cardData, cardMetadata)
|
||||
-- use the ZoopGuid as fallback if no id present
|
||||
if cardMetadata.id == nil and cardMetadata.TtsZoopGuid then
|
||||
cardMetadata.id = cardMetadata.TtsZoopGuid
|
||||
function addCardToIndex(cardData)
|
||||
-- using the more efficient 'json.parse()' to speed this process up
|
||||
local status, cardMetadata = pcall(function() return json.parse(cardData.GMNotes) 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
|
||||
cardMetadata.id = cardMetadata.id or cardMetadata.TtsZoopGuid
|
||||
cardIdIndex[cardMetadata.id] = { data = cardData, metadata = cardMetadata }
|
||||
if (cardMetadata.alternate_ids ~= nil) then
|
||||
|
||||
-- also add data for alternate ids
|
||||
if cardMetadata.alternate_ids ~= nil then
|
||||
for _, alternateId in ipairs(cardMetadata.alternate_ids) do
|
||||
cardIdIndex[alternateId] = { data = cardData, metadata = cardMetadata }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Creates the supplemental indexes for classes, weaknesses etc.
|
||||
function buildSupplementalIndexes()
|
||||
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 cardId == cardMetadata.id then
|
||||
-- Add card to the basic weakness list, if appropriate. Some weaknesses have
|
||||
-- multiple copies, and are added multiple times
|
||||
if cardMetadata.weakness then
|
||||
table.insert(uniqueWeaknessList, cardMetadata.id)
|
||||
if cardMetadata.basicWeaknessCount ~= nil then
|
||||
for i = 1, cardMetadata.basicWeaknessCount do
|
||||
table.insert(basicWeaknessList, cardMetadata.id)
|
||||
-- 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 == card.metadata.id then
|
||||
-- Add card to the basic weakness list, if appropriate. Some weaknesses have multiple copies, and are added multiple times
|
||||
if card.metadata.weakness then
|
||||
table.insert(uniqueWeaknessList, card.metadata.id)
|
||||
if card.metadata.basicWeaknessCount ~= nil then
|
||||
for i = 1, card.metadata.basicWeaknessCount do
|
||||
table.insert(basicWeaknessList, card.metadata.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Add the card to the appropriate class and level indexes
|
||||
local isGuardian = false
|
||||
local isSeeker = false
|
||||
local isMystic = false
|
||||
local isRogue = false
|
||||
local isSurvivor = false
|
||||
local isNeutral = false
|
||||
local upgradeKey
|
||||
-- Excludes signature cards (which have no class or level) and alternate
|
||||
-- ID entries
|
||||
if (cardMetadata.class ~= nil and cardMetadata.level ~= nil) then
|
||||
isGuardian = string.match(cardMetadata.class, "Guardian")
|
||||
isSeeker = string.match(cardMetadata.class, "Seeker")
|
||||
isMystic = string.match(cardMetadata.class, "Mystic")
|
||||
isRogue = string.match(cardMetadata.class, "Rogue")
|
||||
isSurvivor = string.match(cardMetadata.class, "Survivor")
|
||||
isNeutral = string.match(cardMetadata.class, "Neutral")
|
||||
if (cardMetadata.level > 0) then
|
||||
-- Excludes signature cards (which have no class or level)
|
||||
if card.metadata.class ~= nil and card.metadata.level ~= nil then
|
||||
local upgradeKey = "-level0"
|
||||
if card.metadata.level > 0 then
|
||||
upgradeKey = "-upgrade"
|
||||
else
|
||||
upgradeKey = "-level0"
|
||||
end
|
||||
if (isGuardian) then
|
||||
table.insert(classAndLevelIndex["Guardian"..upgradeKey], cardMetadata.id)
|
||||
end
|
||||
if (isSeeker) then
|
||||
table.insert(classAndLevelIndex["Seeker"..upgradeKey], cardMetadata.id)
|
||||
end
|
||||
if (isMystic) then
|
||||
table.insert(classAndLevelIndex["Mystic"..upgradeKey], cardMetadata.id)
|
||||
end
|
||||
if (isRogue) then
|
||||
table.insert(classAndLevelIndex["Rogue"..upgradeKey], cardMetadata.id)
|
||||
end
|
||||
if (isSurvivor) then
|
||||
table.insert(classAndLevelIndex["Survivor"..upgradeKey], cardMetadata.id)
|
||||
end
|
||||
if (isNeutral) then
|
||||
table.insert(classAndLevelIndex["Neutral"..upgradeKey], cardMetadata.id)
|
||||
end
|
||||
|
||||
local cycleName = cardMetadata.cycle
|
||||
-- parse classes (separated by "|") and add the card to the appropriate class and level indices
|
||||
for str in card.metadata.class:gmatch("([^|]+)") do
|
||||
table.insert(classAndLevelIndex[str .. upgradeKey], card.metadata.id)
|
||||
end
|
||||
|
||||
-- add to cycle index
|
||||
local cycleName = card.metadata.cycle
|
||||
if cycleName ~= nil then
|
||||
cycleName = string.lower(cycleName)
|
||||
if string.match(cycleName, "return") then
|
||||
cycleName = string.sub(cycleName, 11)
|
||||
end
|
||||
if cycleName == "the night of the zealot" then
|
||||
cycleName = "core"
|
||||
end
|
||||
if cycleIndex[cycleName] == nil then
|
||||
cycleIndex[cycleName] = { }
|
||||
end
|
||||
table.insert(cycleIndex[cycleName], cardMetadata.id)
|
||||
|
||||
-- remove "return to " from cycle names
|
||||
cycleName = cycleName:gsub("return to ", "")
|
||||
|
||||
-- override cycle name for night of the zealot
|
||||
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
|
||||
cycleIndex[cycleName] = {}
|
||||
end
|
||||
table.insert(cycleIndex[cycleName], card.metadata.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- sort class and level indices
|
||||
for _, indexTable in pairs(classAndLevelIndex) do
|
||||
table.sort(indexTable, cardComparator)
|
||||
end
|
||||
|
||||
-- sort cycle indices
|
||||
for _, indexTable in pairs(cycleIndex) do
|
||||
table.sort(indexTable)
|
||||
end
|
||||
|
||||
-- sort weakness indices
|
||||
table.sort(basicWeaknessList, cardComparator)
|
||||
table.sort(uniqueWeaknessList, cardComparator)
|
||||
end
|
||||
|
||||
-- Comparison function used to sort the class card bag indexes. Sorts by card
|
||||
-- level, then name, then subname.
|
||||
-- Comparison function used to sort the class card bag indexes. Sorts by card level, then name, then subname.
|
||||
function cardComparator(id1, id2)
|
||||
local card1 = cardIdIndex[id1]
|
||||
local card2 = cardIdIndex[id2]
|
||||
|
||||
if (card1.metadata.level ~= card2.metadata.level) then
|
||||
if card1.metadata.level ~= card2.metadata.level then
|
||||
return card1.metadata.level < card2.metadata.level
|
||||
end
|
||||
if (card1.data.Nickname ~= card2.data.Nickname) then
|
||||
elseif card1.data.Nickname ~= card2.data.Nickname then
|
||||
return card1.data.Nickname < card2.data.Nickname
|
||||
else
|
||||
return card1.data.Description < card2.data.Description
|
||||
end
|
||||
return card1.data.Description < card2.data.Description
|
||||
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()
|
||||
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
|
||||
end
|
||||
|
||||
-- Returns a specific card from the bag, based on ArkhamDB ID
|
||||
-- Params table:
|
||||
-- id: String ID of the card to retrieve
|
||||
-- Return: If the indexes are still being constructed, an empty table is
|
||||
-- returned. Otherwise, a single table with the following fields
|
||||
-- cardData: TTS object data, suitable for spawning the card
|
||||
-- cardMetadata: Table of parsed metadata
|
||||
---@param params table ID of the card to retrieve
|
||||
---@return table: If the indexes are still being constructed, returns an empty table.
|
||||
-- Otherwise, a single table with the following fields
|
||||
-- data: TTS object data, suitable for spawning the card
|
||||
-- metadata: Table of parsed metadata
|
||||
function getCardById(params)
|
||||
if (not indexingDone) then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
return { }
|
||||
end
|
||||
if not isIndexReady() then return {} end
|
||||
return cardIdIndex[params.id]
|
||||
end
|
||||
|
||||
-- Returns a list of cards from the bag matching a class and level (0 or upgraded)
|
||||
-- Params table:
|
||||
-- class: String class to retrieve ("Guardian", "Seeker", etc)
|
||||
-- isUpgraded: true for upgraded cards (Level 1-5), false for Level 0
|
||||
-- Return: If the indexes are still being constructed, returns an empty table.
|
||||
-- Otherwise, a list of tables, each with the following fields
|
||||
-- cardData: TTS object data, suitable for spawning the card
|
||||
-- cardMetadata: Table of parsed metadata
|
||||
---@param params table
|
||||
-- class: String class to retrieve ("Guardian", "Seeker", etc)
|
||||
-- isUpgraded: true for upgraded cards (Level 1-5), false for Level 0
|
||||
---@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 getCardsByClassAndLevel(params)
|
||||
if (not indexingDone) then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
return { }
|
||||
end
|
||||
local upgradeKey
|
||||
if (params.upgraded) then
|
||||
if not isIndexReady() then return {} end
|
||||
|
||||
local upgradeKey = "-level0"
|
||||
if params.upgraded then
|
||||
upgradeKey = "-upgrade"
|
||||
end
|
||||
return classAndLevelIndex[params.class .. upgradeKey]
|
||||
end
|
||||
|
||||
-- Returns a list of cards from the bag matching a cycle
|
||||
---@param params table
|
||||
-- cycle: String cycle to retrieve ("The Scarlet Keys" etc.)
|
||||
-- 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
|
||||
|
||||
-- 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
|
||||
upgradeKey = "-level0"
|
||||
return card1.data.Description < card2.data.Description
|
||||
end
|
||||
return classAndLevelIndex[params.class..upgradeKey];
|
||||
end
|
||||
|
||||
function getCardsByCycle(cycleName)
|
||||
if (not indexingDone) then
|
||||
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
|
||||
return { }
|
||||
-- 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 cycleIndex[string.lower(cycleName)]
|
||||
return classValue
|
||||
end
|
||||
|
||||
-- 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.
|
||||
-- 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.
|
||||
-- Parameter array must contain these fields to define the search:
|
||||
-- name String or string fragment to search for names
|
||||
-- exact Whether the name match should be exact
|
||||
-- name: String or string fragment to search for names
|
||||
-- exact: Whether the name match should be exact
|
||||
function getCardsByName(params)
|
||||
local name = params.name
|
||||
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
|
||||
local addedCards = { }
|
||||
local addedCards = {}
|
||||
for _, cardData in pairs(cardIdIndex) do
|
||||
if (not addedCards[cardData.metadata.id]) then
|
||||
if (exact and (string.lower(cardData.data.Nickname) == string.lower(name)))
|
||||
or (not exact and string.find(string.lower(cardData.data.Nickname), string.lower(name), 1, true)) then
|
||||
table.insert(results, cardData)
|
||||
addedCards[cardData.metadata.id] = true
|
||||
table.insert(results, cardData)
|
||||
addedCards[cardData.metadata.id] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
-- Gets a random basic weakness from the bag. Once a given ID has been returned
|
||||
-- it will be removed from the list and cannot be selected again until a reload
|
||||
-- occurs or the indexes are rebuilt, which will refresh the list to include all
|
||||
-- weaknesses.
|
||||
-- Return: String ID of the selected weakness.
|
||||
-- Gets a random basic weakness from the bag. Once a given ID has been returned it will be
|
||||
-- removed from the list and cannot be selected again until a reload occurs or the indexes
|
||||
-- are rebuilt, which will refresh the list to include all weaknesses.
|
||||
---@return string: ID of the selected weakness
|
||||
function getRandomWeaknessId()
|
||||
local availableWeaknesses = buildAvailableWeaknesses()
|
||||
if (#availableWeaknesses > 0) then
|
||||
local availableWeaknesses = buildAvailableWeaknesses()
|
||||
if #availableWeaknesses > 0 then
|
||||
return availableWeaknesses[math.random(#availableWeaknesses)]
|
||||
end
|
||||
end
|
||||
|
||||
-- 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
|
||||
-- Return: Table array of weakness IDs which are valid to choose from
|
||||
function buildAvailableWeaknesses()
|
||||
local weaknessesInPlay = { }
|
||||
---@param traits? string Trait(s) to use as filter
|
||||
---@return table: Array of weakness IDs which are valid to choose from
|
||||
function buildAvailableWeaknesses(traits)
|
||||
local weaknessesInPlay = {}
|
||||
local allObjects = getAllObjects()
|
||||
for _, object in ipairs(allObjects) do
|
||||
if (object.name == "Deck") then
|
||||
if object.type == "Deck" then
|
||||
for _, cardData in ipairs(object.getData().ContainedObjects) do
|
||||
local cardMetadata = JSON.decode(cardData.GMNotes)
|
||||
incrementWeaknessCount(weaknessesInPlay, cardMetadata)
|
||||
incrementWeaknessCount(weaknessesInPlay, JSON.decode(cardData.GMNotes))
|
||||
end
|
||||
elseif (object.name == "Card") then
|
||||
local cardMetadata = JSON.decode(object.getGMNotes())
|
||||
incrementWeaknessCount(weaknessesInPlay, cardMetadata)
|
||||
elseif object.type == "Card" then
|
||||
incrementWeaknessCount(weaknessesInPlay, JSON.decode(object.getGMNotes()))
|
||||
end
|
||||
end
|
||||
|
||||
local availableWeaknesses = { }
|
||||
local availableWeaknesses = {}
|
||||
for _, weaknessId in ipairs(basicWeaknessList) do
|
||||
if (weaknessesInPlay[weaknessId] ~= nil and weaknessesInPlay[weaknessId] > 0) then
|
||||
weaknessesInPlay[weaknessId] = weaknessesInPlay[weaknessId] - 1
|
||||
else
|
||||
table.insert(availableWeaknesses, weaknessId)
|
||||
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)
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
table.insert(availableWeaknesses, weaknessId)
|
||||
end
|
||||
end
|
||||
end
|
||||
return availableWeaknesses
|
||||
@ -400,8 +488,8 @@ end
|
||||
|
||||
-- Helper function that adds one to the table entry for the number of weaknesses in play
|
||||
function incrementWeaknessCount(table, cardMetadata)
|
||||
if (isBasicWeakness(cardMetadata)) then
|
||||
if (table[cardMetadata.id] == nil) then
|
||||
if isBasicWeakness(cardMetadata) then
|
||||
if table[cardMetadata.id] == nil then
|
||||
table[cardMetadata.id] = 1
|
||||
else
|
||||
table[cardMetadata.id] = table[cardMetadata.id] + 1
|
||||
@ -411,9 +499,61 @@ end
|
||||
|
||||
function isBasicWeakness(cardMetadata)
|
||||
return cardMetadata ~= nil
|
||||
and cardMetadata.weakness
|
||||
and cardMetadata.basicWeaknessCount ~= nil
|
||||
and cardMetadata.basicWeaknessCount > 0
|
||||
and cardMetadata.weakness
|
||||
and cardMetadata.basicWeaknessCount ~= nil
|
||||
and cardMetadata.basicWeaknessCount > 0
|
||||
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")
|
@ -16,6 +16,11 @@ ContainedObjects:
|
||||
- !include 'Bag All Player Cards 15bb07/Card Reality Acid 0a1b3a.yaml'
|
||||
- !include 'Bag All Player Cards 15bb07/Card Reality Acid Reference 858b0a.yaml'
|
||||
- !include 'Bag All Player Cards 15bb07/Card Ravenous 558b0a.yaml'
|
||||
- !include 'Bag All Player Cards 15bb07/CardCustom Rex Murphy (Parallel) 0a5492.yaml'
|
||||
- !include 'Bag All Player Cards 15bb07/CardCustom Rex Murphy (Parallel Back) 0a5493.yaml'
|
||||