Merge pull request #226 from argonui/chaos-token-updates
Chaos Token spawning, drawing and sealing // Custom Playercolors
This commit is contained in:
commit
2e8e0aea4c
@ -63,7 +63,7 @@
|
|||||||
"IgnoreFoW": false,
|
"IgnoreFoW": false,
|
||||||
"LayoutGroupSortIndex": 0,
|
"LayoutGroupSortIndex": 0,
|
||||||
"Locked": false,
|
"Locked": false,
|
||||||
"LuaScript": "require(\"chaosbag/ChaosBag\")",
|
"LuaScript": "",
|
||||||
"LuaScriptState": "",
|
"LuaScriptState": "",
|
||||||
"MaterialIndex": -1,
|
"MaterialIndex": -1,
|
||||||
"MeasureMovement": false,
|
"MeasureMovement": false,
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
"Curse.16a9a7",
|
"Curse.16a9a7",
|
||||||
"Bless.8e3aab",
|
"Bless.8e3aab",
|
||||||
"ElderSign.0b1aca",
|
"ElderSign.0b1aca",
|
||||||
"Auto-Fail.e31821",
|
"Auto-fail.e31821",
|
||||||
"ElderThing.38609c",
|
"ElderThing.38609c",
|
||||||
"Tablet.1a1506",
|
"Tablet.1a1506",
|
||||||
"Cultist.7d6103",
|
"Cultist.7d6103",
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
"LuaScriptState": "",
|
"LuaScriptState": "",
|
||||||
"MeasureMovement": false,
|
"MeasureMovement": false,
|
||||||
"Name": "Custom_Tile",
|
"Name": "Custom_Tile",
|
||||||
"Nickname": "Auto-Fail",
|
"Nickname": "Auto-fail",
|
||||||
"Snap": true,
|
"Snap": true,
|
||||||
"Sticky": true,
|
"Sticky": true,
|
||||||
"Tooltip": true,
|
"Tooltip": true,
|
@ -15,8 +15,7 @@
|
|||||||
},
|
},
|
||||||
"ContainedObjects_order": [
|
"ContainedObjects_order": [
|
||||||
"ArkhamFantasy-PixelArtMini-Cards.e17c9e",
|
"ArkhamFantasy-PixelArtMini-Cards.e17c9e",
|
||||||
"DrawTokenButtonTooltipRenamer.cc77a8",
|
"GenericDifficultySelector.8112ff",
|
||||||
"WhimsicalsGenericDifficultySelector.05efb4",
|
|
||||||
"LuckyPenny.2ab443",
|
"LuckyPenny.2ab443",
|
||||||
"Double-SidedResource.bc81cb",
|
"Double-SidedResource.bc81cb",
|
||||||
"DescriptivePhaseTracker.b171c8",
|
"DescriptivePhaseTracker.b171c8",
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
{
|
|
||||||
"AltLookAngle": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"Autoraise": true,
|
|
||||||
"ColorDiffuse": {
|
|
||||||
"b": 0,
|
|
||||||
"g": 0,
|
|
||||||
"r": 1
|
|
||||||
},
|
|
||||||
"Description": "By Pyxel",
|
|
||||||
"DragSelectable": true,
|
|
||||||
"GMNotes": "",
|
|
||||||
"GUID": "cc77a8",
|
|
||||||
"Grid": true,
|
|
||||||
"GridProjection": false,
|
|
||||||
"Hands": false,
|
|
||||||
"HideWhenFaceDown": false,
|
|
||||||
"IgnoreFoW": false,
|
|
||||||
"LayoutGroupSortIndex": 0,
|
|
||||||
"Locked": false,
|
|
||||||
"LuaScriptState": "",
|
|
||||||
"LuaScript_path": "Fan-MadeAccessories.aa8b38/DrawTokenButtonTooltipRenamer.cc77a8.ttslua",
|
|
||||||
"MeasureMovement": false,
|
|
||||||
"Name": "Checker_red",
|
|
||||||
"Nickname": "Draw Token Button Tooltip Renamer",
|
|
||||||
"Snap": true,
|
|
||||||
"Sticky": true,
|
|
||||||
"Tooltip": true,
|
|
||||||
"Transform": {
|
|
||||||
"posX": 30.498,
|
|
||||||
"posY": 4.084,
|
|
||||||
"posZ": -20.929,
|
|
||||||
"rotX": 0,
|
|
||||||
"rotY": 270,
|
|
||||||
"rotZ": 0,
|
|
||||||
"scaleX": 1,
|
|
||||||
"scaleY": 1,
|
|
||||||
"scaleZ": 1
|
|
||||||
},
|
|
||||||
"Value": 0,
|
|
||||||
"XmlUI": ""
|
|
||||||
}
|
|
@ -1,455 +0,0 @@
|
|||||||
function onLoad()
|
|
||||||
spawnButton("symbols", "Change Tooltips",
|
|
||||||
"Changes tooltip for 'draw chaos token' buttons.", 0, 0.5, 0, 600, 400, 70)
|
|
||||||
end
|
|
||||||
|
|
||||||
function spawnButton( func, text, tool_tip, xPosition, yPosition, zPosition, button_width, button_height, fontsize )
|
|
||||||
scale = self.getScale()
|
|
||||||
scale = scale[1]
|
|
||||||
params = {
|
|
||||||
click_function = func,
|
|
||||||
function_owner = self,
|
|
||||||
label = text,
|
|
||||||
position = {scale * xPosition, yPosition, scale * zPosition},
|
|
||||||
rotation = {0, 0, 0},
|
|
||||||
width = button_width * scale,
|
|
||||||
height = button_height * scale,
|
|
||||||
font_size = fontsize * scale,
|
|
||||||
color = {1, 1, 1},
|
|
||||||
font_color = {0, 0, 0},
|
|
||||||
tooltip = tool_tip
|
|
||||||
}
|
|
||||||
self.createButton(params)
|
|
||||||
end
|
|
||||||
|
|
||||||
function symbols()
|
|
||||||
local tool = "no scenario selected"
|
|
||||||
for _, scenario in ipairs(getObjectFromGUID("fe2ae4").getObjects()) do
|
|
||||||
if scenario.getDescription() == "The Gathering" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull] -2. If you fail, after this skill test, search the encounter deck and discard pile for a [[Ghoul]] enemy, and draw it. Shuffle the encounter deck.\n\n[cultist] Reveal another token. If you fail, take 2 horror.\n\n[tablet] -4. If there is a [[Ghoul]] enemy at your location, take 1 damage and 1 horror."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull] -X. X is the number of [[Ghoul]] enemies at your location.\n\n[cultist] -1. If you fail, take 1 horror.\n\n[tablet] -2. If there is a [[Ghoul]] enemy at your location, take 1 damage.\n\n"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- midnight masks
|
|
||||||
if scenario.getDescription() == "The Midnight Masks" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the total number of doom in play.\n\n[cultist]: -2. Place 1 doom on each [[Cultist]] enemy in play. If there are no [[Cultist]] enemies in play, reveal another token.\n\n[tablet]: -4. If you fail, place all your clues on your location."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the highest number of doom on a [[Cultist]] enemy in play.\n\n[cultist]: -2. Place 1 doom on the nearest [[Cultist]] enemy.\n\n[tablet]: -3. If you fail, place 1 of your clues on your location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- devourer below
|
|
||||||
if scenario.getDescription() == "The Devourer Below" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -3. If you fail, after this skill test, search the encounter deck and discard pile for a [[Monster]] enemy, and draw it. Shuffle the encounter deck.\n\n[cultist]: -4. Place 2 doom on the nearest enemy.\n\n[tablet]: -5. If there is a [[Monster]] enemy at your location, take 1 damage and 1 horror.\n\n[elder_thing]: -7. If there is an [[Ancient One]] enemy in play, reveal another token."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the number of [[Monster]] enemies in play.\n\n[cultist]: -2. Place 1 doom on the nearest enemy.\n\n[tablet]: -3. If there is a [[Monster]] enemy at your location, take 1 damage.\n\n[elder_thing]: -5. If there is an [[Ancient One]] enemy in play, reveal another token."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- extracurricular activity symbols
|
|
||||||
if scenario.getDescription() == "Extracurricular Activity" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2. If you fail, discard the top 5 cards of your deck.\n\n[cultist]: -1 (-5 instead if there are 10 or more cards in your discard pile).\n\n[elder_thing]: -X. Discard the top 3 cards of your deck. X is the total printed cost of those discarded cards."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1. If you fail, discard the top 3 cards of your deck.\n\n[cultist]: -1 (-3 instead if there are 10 or more cards in your discard pile).\n\n[elder_thing]: -X. Discard the top 2 cards of your deck. X is the total printed cost of those discarded cards."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- The house always wins symbols
|
|
||||||
if scenario.getDescription() == "The House Always Wins" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -3. You may spend 3 resources to treat this token as a 0, instead.\n\n[cultist]: -3. If you fail, discard 3 resources.\n\n[tablet]: -2. Discard 3 resources."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -2. You may spend 2 resources to treat this token as a 0, instead.\n\n[cultist]: -3. If you succeed, gain 3 resources.\n\n[tablet]: -2. If you fail, discard 3 resources."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Miskatonic museum symbols
|
|
||||||
if scenario.getDescription() == "The Miskatonic Museum" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-4 instead if Hunting Horror is at your location.)\n\n[cultist]: -3. If you fail, search the encounter deck, discard pile, and the void for Hunting Horror and spawn it at your location, if able.\n\n[tablet]: -4. If Hunting Horror is at your location, it immediately attacks you.\n\n[elder_thing]: -5. If you fail, discard an asset you control."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if Hunting Horror is at your location.)\n\n[cultist]: -1. If you fail, search the encounter deck, discard pile, and the void for Hunting Horror and spawn it at your location, if able.\n\n[tablet]: -2. Return 1 of your clues to your current location.\n\n[elder_thing]: -3. If you fail, discard an asset you control."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- essex county express symbols
|
|
||||||
if scenario.getDescription() == "The Essex County Express" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is 1 more than the current Agenda #. \n\n[cultist]: Reveal another token. If you fail and it is your turn, lose all remaining actions and end your turn immediately.\n\n[tablet]: -4. Add 1 doom token to each Cultist enemy in play.\n\n[elder_thing]: -3. If you fail, choose and discard a card from your hand for each point you failed by."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the current Agenda #.\n\n[cultist]: -1. If you fail and it is your turn, lose all remaining actions and end your turn immediately.\n\n[tablet]: -2. Add 1 doom token to the nearest Cultist enemy.\n\n[elder_thing]: -3. If you fail, choose and discard a card from your hand."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--blood on the Altar
|
|
||||||
if scenario.getDescription() == "Blood on the Altar" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -1 for each location in play with no encounter card underneath it.\n\n[cultist]: -4. If you fail, add 1 clue from the token pool to your location.\n\n[tablet]: -3. Reveal another token.\n\n[elder_thing]: -3. Place 1 doom on the current agenda."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 for each location in play with no encounter card underneath it (max -4).\n\n[cultist]: -2. If you fail, add 1 clue from the token pool to your location.\n\n[tablet]: -2. If you are in the Hidden Chamber, reveal another token.\n\n[elder_thing]: -3. If you fail, place 1 doom on the current agenda."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--undimensioned and unseen
|
|
||||||
if scenario.getDescription() == "Undimensioned and Unseen" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 for each Brood of Yog-Sothoth in play.\n\n[cultist]: Reveal another token. If you fail this test, take 1 horror and 1 damage.\n\n[tablet]: 0. You must either remove all clue tokens from a Brood of Yog-Sothoth in play, or this test automatically fails.\n\n[elder_thing]: -5. If this token is revealed during an attack or evasion attempt against a Brood of Yog-Sothoth, it immediately attacks you."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 for each Brood of Yog-Sothoth in play.\n\n[cultist]: Reveal another token. If you fail this test, take 1 horror.\n\n[tablet]: 0. You must either remove all clue tokens from a Brood of Yog-Sothoth in play, or this token's modifier is -4 instead.\n\n[elder_thing]: -3. If this token is revealed during an attack or evasion attempt against a Brood of Yog-Sothoth, it immediately attacks you."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- where doom Awaits
|
|
||||||
if scenario.getDescription() == "Where Doom Awaits" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-5 instead if you are at an [[Altered]] location).\n\n[cultist]: Reveal another token. Cancel the effects and icons of each skill card committed to this test.\n\n[tablet]: -3. If it is Agenda 2, you automatically fail instead.\n\n[elder_thing]: -X. Discard the top 3 cards of your deck. X is the total printed cost of those discarded cards."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if you are at an [[Altered]] location).\n\n[cultist]: Reveal another token. Cancel the effects and icons of each skill card committed to this test.\n\n[tablet]: -2 (-4 instead if it is Agenda 2).\n\n[elder_thing]: -X. Discard the top 2 cards of your deck. X is the total printed cost of those discarded cards."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--lost in time and space
|
|
||||||
if scenario.getDescription() == "Lost in Time and Space" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -1 for each [[Extradimensional]] location in play.\n\n[cultist]: Reveal another token. After this skill test, discard cards from the top of the encounter deck until a location is discarded. Put that location into play and move there.\n\n[tablet]: -5. If Yog-Sothoth is in play, it attacks you after this skill test.\n\n[elder_thing]: -X. X is twice the shroud value of your location. If you fail and your location is [[Extradimensional]], discard it."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 for each [[Extradimensional]] location in play (max -5).\n\n[cultist]: Reveal another token. If you fail, after this skill test, discard cards from the top of the encounter deck until a location is discarded. Put that location into play and move there.\n\n[tablet]: -3. If Yog-Sothoth is in play, it attacks you after this skill test.\n\n[elder_thing]: -X. X is the shroud value of your location. If you fail and your location is [[Extradimensional]], discard it."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- curtain call
|
|
||||||
if scenario.getDescription() == "Curtain Call" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X, where X is the amount of horror on you. (If you have no horror on you, X is 1.)\n\n[cultist] [tablet] [elder_thing]: -5. If your location has at least 1 horror on it, take 1 horror <i>(from the token pool)</i>. If your location has no horror on it, place 1 horror on it instead."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if you have 3 or more horror on you).\n\n[cultist] [tablet] [elder_thing]: -4. If your location has at least 1 horror on it, take 1 horror <i>(from the token pool)</i>. If your location has no horror on it, place 1 horror on it instead."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Last King
|
|
||||||
if scenario.getDescription() == "The Last King" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: Reveal another token. If you fail, place 1 doom on the [[Lunatic]] enemy in play with the most remaining health.\n\n[cultist]: -3. Place 1 of your clues on your location.\n\n[tablet]: -4. Take 1 horror.\n\n[elder_thing]: -X. X is the shroud value of your location. If you fail, take 1 damage."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: Reveal another token. If you fail, place 1 doom on a [[Lunatic]] enemy in play.\n\n[cultist]: -2. If you fail, place 1 of your clues on your location.\n\n[tablet]: -4. If you fail, take 1 horror.\n\n[elder_thing]: -X. X is the shroud value of your location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Echoes Past
|
|
||||||
if scenario.getDescription() == "Echoes of the Past" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the total number of doom on enemies in play.\n\n[cultist]: -4. Place 1 doom on the nearest enemy.\n\n[tablet]: -4. Discard a random card from your hand.\n\n[elder_thing]: -4. If there is an enemy at your location, take 1 horror."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the highest number of doom on an enemy in play.\n\n[cultist]: -2. If you fail, place 1 doom on the nearest enemy.\n\n[tablet]: -2. If you fail, discard a random card from your hand.\n\n[elder_thing]: -2. If you fail and there is an enemy at your location, take 1 horror."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Unspeakable Oath
|
|
||||||
if scenario.getDescription() == "The Unspeakable Oath" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: Reveal another token. If you fail, randomly choose an enemy from among the set-aside [[Monster]] enemies and place it beneath the act deck without looking at it. (Limit once per test.)\n\n[cultist]: -X. X is the amount of horror on you. If you fail, take 1 horror.\n\n[tablet]: -X. X is the base shroud value of your location. If you fail, take 1 horror.\n\n[elder_thing]: 0. Either randomly choose an enemy from among the set-aside [[Monster]] enemies and place it beneath the act deck without looking at it, or this test automatically fails instead."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1. If you fail, randomly choose an enemy from among the set-aside [[Monster]] enemies and place it beneath the act deck without looking at it.\n\n[cultist]: -X. X is the amount of horror on you.\n\n[tablet]: -X. X is the base shroud value of your location.\n\n[elder_thing]: 0. Either randomly choose an enemy from among the set-aside [[Monster]] enemies and place it beneath the act deck without looking at it, or this test automatically fails instead."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- A Phantom of Truth
|
|
||||||
if scenario.getDescription() == "A Phantom of Truth" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the amount of doom in play.\n\n[cultist]: -2. Move each unengaged [[Byakhee]] in play once toward the nearest investigator.\n\n[tablet]: -4. Cancel the effects and icons of each skill card committed to this test.\n\n[elder_thing]: -3. If you fail, lose 1 resource for each point you failed by."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the amount of doom in play (max 5).\n\n[cultist]: -2. If you fail, move each unengaged [[Byakhee]] in play once toward the nearest investigator.\n\n[tablet]: -3. Cancel the effects and icons of each skill card committed to this test.\n\n[elder_thing]: -2. If you fail, lose 1 resource for each point you failed by."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- The Pallid Mask
|
|
||||||
if scenario.getDescription() == "The Pallid Mask" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the number of locations away from the starting location you are.\n\n[cultist]: -3. If this token is revealed during an attack and this skill test is successful, this attack deals no damage.\n\n[tablet]: -3. If there is a [[Ghoul]] or [[Geist]] enemy at your location, it readies and attacks you (if there is more than one, choose one).\n\n[elder_thing]: -4. If you fail, search the encounter deck and discard pile for a [[Ghoul]] or [[Geist]] enemy and draw it."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the number of locations away from the starting location you are (max 5).\n\n[cultist]: -2. If this token is revealed during an attack, and this skill test is successful, this attack deals 1 less damage.\n\n[tablet]: -2. If there is a ready [[Ghoul]] or [[Geist]] enemy at your location, it attacks you (if there is more than one, choose one).\n\n[elder_thing]: -3. If you fail, search the encounter deck and discard pile for a [[Ghoul]] or [[Geist]] enemy and draw it."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- Dim Carcosa
|
|
||||||
if scenario.getDescription() == "Dim Carcosa" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the amount of horror on you.\n\n[cultist]: Reveal another token. If you fail, take 2 horror.\n\n[tablet]: -5. If you fail and Hastur is in play, place 1 clue on your location <i>(from the token bank)</i>.\n\n[elder_thing]: -5. If this token is revealed during an attack or evasion attempt against a [[Monster]] or [[Ancient One]] enemy, lose 1 action."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -2 (-4 instead if you have no sanity remaining).\n\n[cultist]: Reveal another token. If you fail, take 1 horror.\n\n[tablet]: -3. If you fail and Hastur is in play, place 1 clue on your location <i>(from the token bank)</i>.\n\n[elder_thing]: -3. If this token is revealed during an attack or evasion attempt against a [[Monster]] or [[Ancient One]] enemy, lose 1 action."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if scenario.getDescription() == "Black Stars Rise" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the total amount of doom on agendas in play.\n\n[cultist]: Reveal another token. If there is an enemy with 1 or more doom on it at your location, this test automatically fails instead.\n\n[tablet]: Reveal another token. If you do not succeed by at least 1, place 1 doom on each agenda.\n\n[elder_thing]: -3. If you fail, search the encounter deck and discard pile for a [[Byakhee]] enemy and draw it."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the highest amount of doom on an agenda in play.\n\n[cultist]: Reveal another token. If this token is revealed during an attack or evasion attempt against an enemy with doom on it, this skill test automatically fails instead.\n\n[tablet]: Reveal another token. If you fail, place 1 doom on each agenda.\n\n[elder_thing]: -2. If you fail, search the encounter deck and discard pile for a [[Byakhee]] enemy and draw it."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- untamed Wilds
|
|
||||||
if scenario.getDescription() == "The Untamed Wilds" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is 1 higher than the number of vengeance points in the victory display.\n\n[cultist]: -X. X is the number of locations in play.\n\n[tablet]: -X. X is the number of cards in the exploration deck (min 3).\n\n[elder_thing]: -3. If you are poisoned, this test automatically fails instead. If you are not poisoned and you fail, put a set-aside Poisoned weakness into play in your threat area."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the number of vengeance points in the victory display.\n\n[cultist]: -X. X is the number of locations in play (max 5).\n\n[tablet]: -X. X is the number of cards in the exploration deck (max 5).\n\n[elder_thing]: -2. If you are poisoned, this test automatically fails instead."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--The doom of Eztli
|
|
||||||
if scenario.getDescription() == "The Doom of Eztli" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-4 instead if there is doom on your location).\n\n[cultist] [tablet]: -X. X is the total amount of doom on locations in play.\n\n[elder_thing]: Reveal another chaos token. Place 1 doom on your location."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if there is doom on your location).\n\n[cultist] [tablet]: -X. X is the number of locations with doom on them.\n\n[elder_thing]: Reveal another chaos token. If you fail, place 1 doom on your location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Threads of Fate
|
|
||||||
if scenario.getDescription() == "Threads of Fate" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull] : -X. X is the total number of doom in play.\n\n[cultist]: -2. If you do not succeed by at least 2, take 1 direct damage.\n\n[tablet]: -2. If you do not succeed by at least 2, place 1 doom on each [[cultist]] enemy.\n\n[elder_thing]: -3. If you fail, lose 1 of your clues."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull] : -X. X is the highest number of doom on a [[cultist]] enemy.\n\n[cultist]: -2. If you do not succeed by at least 1, take 1 damage.\n\n[tablet]: -2. If you do not succeed by at least 1, place 1 doom on the nearest [[cultist]] enemy.\n\n[elder_thing]: -2. If you fail, lose 1 of your clues."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--The boundary beyond
|
|
||||||
if scenario.getDescription() == "The Boundary Beyond" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-4 instead if you are at an [[Ancient]] location).\n\n[cultist]: Reveal another token. If you fail, place 1 doom on each [[Cultist]] enemy.\n\n[tablet]: Reveal another token. If you fail, each [[Serpent]] enemy at your location attacks you.\n\n[elder_thing]: -4. Place 1 clue <i>(from the token pool)</i> on the nearest [[Ancient]] location."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if you are at an [[Ancient]] location).\n\n[cultist]: Reveal another token. If you fail, place 1 doom on a [[Cultist]] enemy.\n\n[tablet]: Reveal another token. If you fail and there is a [[Serpent]] enemy at your location, it attacks you.\n\n[elder_thing]: -4. If you fail, place 1 clue <i>(from the token pool)</i> on the nearest [[Ancient]] location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Heart of the elders p1
|
|
||||||
if scenario.getDescription() == "Heart of the Elders" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-4 instead if you are in a [[Cave]] location).\n\n[cultist]: -3. If you fail, place 1 doom on your location.\n\n[tablet]: -3. If you are poisoned, this test automatically fails instead. If you are not poisoned and you fail, put a set-aside Poisoned weakness into play in your threat area.\n\n[elder_thing]: -4. If you fail, take 1 horror."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if you are in a [[Cave]] location).\n\n[cultist]: -2. If you fail, place 1 doom on your location.\n\n[tablet]: -2. If you are poisoned, this test automatically fails instead.\n\n[elder_thing]: -3. If you fail, take 1 horror."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- City of Archives
|
|
||||||
if scenario.getDescription() == "The City of Archives" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (if you have 5 or more cards in your hand, you automatically fail instead).\n\n[cultist] or [elder_thing]: -2. Place 1 of your clues on your location.\n\n[tablet]: -3. For each point you fail by, discard 1 random card from your hand."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if you have 5 or more cards in your hand).\n\n[cultist] or [elder_thing]: -2. If you fail, place 1 of your clues on your location.\n\n[tablet]: -3. If you fail, discard 1 random card from your hand."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Depths of Yoth
|
|
||||||
if scenario.getName() == "Scenario - Easy/Standard" then
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the current depth level.\n\n[cultist]: Reveal another token. If you fail, each [[Serpent]] enemy at your location or a connecting location heals 2 damage.\n\n[tablet]: Reveal another token. If you fail, place 1 clue on your location <i>(from the token pool)</i>.\n\n[elder_thing]: -2. If there are 3 or more vengeance points in the victory display, you automatically fail this test, instead."
|
|
||||||
end
|
|
||||||
--hard
|
|
||||||
if scenario.getName() == "Scenario - Hard/Expert" then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the current depth level. If you fail, take 1 horror.\n\n[cultist]: Reveal another token. If you fail, each [[Serpent]] enemy at your location or a connecting location heals 2 damage.\n\n[tablet]: Reveal another token. If you fail, place 1 clue on your location <i>(from the token pool)</i>.\n\n[elder_thing]: -4. If there are 3 or more vengeance points in the victory display, you automatically fail this test, instead."
|
|
||||||
end
|
|
||||||
--Shattered Aeons
|
|
||||||
if scenario.getDescription() == "Shattered Aeons" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -3 (-5 instead if the Relic of Ages is at your location).\n\n[cultist]: -3. If you do not succeed by at least 1, place 1 doom on each [[Cultist]] enemy.\n\n[tablet]: -3. If you are poisoned, this test automatically fails instead. If you are not poisoned and you fail, put a set-aside Poisoned weakness into play in your threat area.\n\n[elder_thing]: -3. Shuffle the topmost [[Hex]] treachery in the encounter discard pile into the exploration deck."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -2 (-4 instead if the Relic of Ages is at your location).\n\n[cultist]: -2. If you do not succeed by at least 1, place 1 doom on the nearest [[Cultist]] enemy.\n\n[tablet]: -2. If you are poisoned, this test automatically fails instead.\n\n[elder_thing]: -2. If you fail, shuffle the topmost [[Hex]] treachery in the encounter discard pile into the exploration deck."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--secret scenario
|
|
||||||
if scenario.getDescription() == "Turn Back Time" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X . X is the total amount of doom on locations.\n\n[elder_thing]: -6. Place 1 doom on your location."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X . X is the number of locations with doom on them.\n\n[elder_thing]: -4. If you fail, place 1 doom on your location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Dissappearance Twilight
|
|
||||||
if scenario.getDescription() == "Disappearance at the Twilight Estate" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -5. If you fail and this is an attack or evasion attempt, resolve each haunted ability on your location."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -3. If you fail and this is an attack or evasion attempt, resolve each haunted ability on your location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Witching Hour
|
|
||||||
if scenario.getDescription() == "The Witching Hour" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2. Discard cards from the top of the encounter deck equal to this test's difficulty.\n\n[tablet]: -2. If you fail, after this test resolves, draw the bottommost treachery in the encounter discard pile.\n\n[elder_thing]: -4. If you fail, ready each [[Witch]] enemy at your location and at each connecting location. Heal all damage from each of those enemies."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1. For each point you fail by, discard the top card of the encounter deck.\n\n[tablet]: -1. If you fail, after this test resolves, draw the bottommost treachery in the encounter discard pile.\n\n[elder_thing]: -3. If you fail, choose an exhausted or damaged [[Witch]] enemy at your location or at a connecting location. Ready that enemy and heal all damage from it."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Death's Doorstep
|
|
||||||
if scenario.getDescription() == "At Death's Doorstep" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-4 instead if your location is haunted).\n\n[tablet]: -3. If this is an attack or evasion attempt, resolve each haunted ability on your location.\n\n[elder_thing]: -4. If there is a [[Spectral]] enemy at your location, take 1 damage and 1 horror."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if your location is haunted).\n\n[tablet]: -2. If you fail and this is an attack or evasion attempt, resolve each haunted ability on your location.\n\n[elder_thing]: -2. If there is a [[Spectral]] enemy at your location, take 1 damage."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Secret Name
|
|
||||||
if scenario.getDescription() == "The Secret Name" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-4 instead if you are at an [[Extradimensional]] location).\n\n[cultist]: Reveal another chaos token. If you fail, discard the top 5 cards of the encounter deck.\n\n[tablet]: -3. If you fail and Nahab is in play, she attacks you <i>(regardless of her current location)</i>.\n\n[elder_thing]: -4. Resolve the hunter keyword on each enemy in play."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if you are at an [[Extradimensional]] location).\n\n[cultist]: Reveal another chaos token. If you fail, discard the top 3 cards of the encounter deck.\n\n[tablet]: -2. If you fail and Nahab is at your location, she attacks you.\n\n[elder_thing]: -3. If you fail, resolve the hunter keyword on each enemy in play."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Wages of Sin
|
|
||||||
if scenario.getDescription() == "The Wages of Sin" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the number of copies of Unfinished Business in the victory display. Reveal another token.\n\n[cultist]: -4. Until the end of the rount, each Heretic enemy in play gets +1 fight and +1 evade.\n\n[tablet]: -4. If you fail, trigger the forced ability on a copy of Unfinished Business in your threat area as if it were the end of the round.\n\n[elder_thing]: -2. If this is an attack or evasion attempt, resolve each haunted ability on your location."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is 1 higher than the number of copies of Unfinished Business in the victory display.\n\n[cultist]: -3. Until the end of the round, each Heretic enemy in play gets +1 fight and +1 evade.\n\n[tablet]: -3. If you fail, trigger the forced ability on a copy of Unfinished Business in yout threat area as if it were the end of the round.\n\n[elder_thing]: -2. If you fail and this is an attack or evasion attempt, resolve each haunted ability on your location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
-- For The Greater Good
|
|
||||||
if scenario.getDescription() == "For the Greater Good" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the total number of doom among [[Cultist]] enemies in play.\n\n[cultist]: -2. Reveal another token.\n\n[tablet]: -3. If you fail, place 1 doom on each [[Cultist]] enemy in play. If there are no [[Cultist]] enemies in play, reveal another token.\n\n[elder_thing]: -3. If you fail, move all doom from the [[Cultist]] enemy with the most doom on it to the current agenda. If no [[Cultist]] enemies in play have doom on them, reveal another token."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the highest number of doom on a [[Cultist]] enemy in play.\n\n[cultist]: -2. Reveal another token.\n\n[tablet]: -3. If you fail, place 1 doom on the nearest [[Cultist]] enemy.\n\n[elder_thing]: -3. If you fail, move 1 doom from the nearest [[Cultist]] enemy to the current agenda."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Union and Disillusion
|
|
||||||
if scenario.getDescription() == "Union and Disillusion" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -3. If this is a skill test during a <b>circle</b> action, reveal another token.\n\n[cultist]: -4. If you have no damage on you, take 1 damage. If you have no horror on you, take 1 horror.\n\n[tablet]: -4. If you fail, a [[Spectral]] enemy at your location attacks you <i>(even if it is exhausted).</i>\n\n[elder_thing]: -4. If this is a skill test during a <b>circle</b> action and you fail, resolve each haunted ability on your location."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -2. If this is a skill test during a <b>circle</b> action, reveal another token.\n\n[cultist]: -3. If you have no damage on you, take 1 damage. If you have no horror on you, take 1 horror.\n\n[tablet]: -3. If you fail, a [[Spectral]] enemy at your location attacks you <i>(even if it is exhausted).</i>\n\n[elder_thing]: -3. If this is a skill test during a <b>circle</b> action and you fail, resolve each haunted ability on your location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Clutches of Chaos
|
|
||||||
if scenario.getDescription() == "In the Clutches of Chaos" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is 1 higher than the total amount of doom and breaches on your location.\n\n[cultist]: Reveal another token. If there are fewer than 3 breaches on your location, place 1 breach on your location.\n\n[tablet]: -3. For each point you fail by, remove 1 breach from the current act.\n\n[elder_thing]: -4. If you fail, place 1 breach on a random location."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the total amount of doom and breaches on your location.\n\n[cultist]: Reveal another token. If there are fewer than 3 breaches on your location, place 1 breach on your location.\n\n[tablet]: -2. For each point you fail by, remove 1 breach from the current act.\n\n[elder_thing]: -3. If you fail, place 1 breach on a random location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Before the Black Throne
|
|
||||||
if scenario.getDescription() == "Before the Black Throne" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the amount of doom on Azathoth, to a minimum of 2.\n\n[cultist]: Reveal another token. If you fail, search the encounter deck and discard pile for a [[Cultist]] enemy and draw it. Shuffle the encounter deck.\n\n[tablet]: -3. If you fail, Azathoth attacks you.\n\n[elder_thing]: -6. If your modified skill value for this test is 0, place 1 doom on Azathoth."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is half of the doom on Azathoth (rounded up), to a minimum of 2.\n\n[cultist]: Reveal another token. If you fail, search the encounter deck and discard pile for a [[Cultist]] enemy and draw it. Shuffle the encounter deck.\n\n[tablet]: -2. If you fail, Azathoth attacks you.\n\n[elder_thing]: -4. If your modified skill value for this test is 0, place 1 doom on Azathoth."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Beyond the gates of sleep
|
|
||||||
if scenario.getDescription() == "Beyond the Gates of Sleep" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull] : -X. X is the number of cards in your hand.\n\n[cultist]: -X. X is the number of revealed [[Woods]] locations.\n\n[tablet]: -2. If this is an attack or evasion attempt against a swarming enemy, add 1 swarm card to it."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull] : -X. X is half the number of cards in your hand (rounded up).\n\n[cultist]: -X. X is the number of revealed Enchanted Woods locations.\n\n[tablet]: -2. If you fail and this is an attack or evasion attempt against a swarming enemy, add 1 swarm card to it."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Waking Nightmare
|
|
||||||
if scenario.getDescription() == "Waking Nightmare" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-4 instead if you are engaged with a [[Staff]] enemy).\n\n[cultist]: Reveal another chaos token. If it is agenda 2 or 3, make an infestation test.\n\n[elder_thing]: -X. X is 1 higher than the number of infested locations."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if you are engaged with a [[Staff]] enemy).\n\n[cultist]: Reveal another chaos token. If you fail and it is agenda 2 or 3, make an infestation test.\n\n[elder_thing]: -X. X is the number of infested locations."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--The search for kadath
|
|
||||||
if scenario.getDescription() == "The Search for Kadath" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is 1 more than the number of Signs of the Gods the investigators have uncovered.\n\n[cultist]: Reveal another token. If this token is revealed during an investigation and this skill test fails, increase that location's shroud by 2 for the remainder of the round.\n\n[tablet]: -3. If you fail, either take 1 damage and 1 horror, or place 1 doom on the current agenda.\n\n[elder_thing]: +1. The black cat points you in the right direction. If this token is revealed during an investigation and you succeed, discover 1 additional clue."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the number of Signs of the Gods the investigators have uncovered.\n\n[cultist]: Reveal another token. If this token is revealed during an investigation and this skill test fails, increase that location's shroud by 1 for the remainder of the round.\n\n[tablet]: -2. If you fail, either take 1 damage and 1 horror, or place 1 doom on the current agenda.\n\n[elder_thing]: +2. The black cat points you in the right direction. If this token is revealed during an investigation and you succeed, discover 1 additional clue."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--A thousand shapes of horror
|
|
||||||
if scenario.getDescription() == "A Thousand Shapes of Horror" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-4 instead if you are at a [[Graveyard]] location).\n\n[cultist]: Reveal another token. If you fail and The Unnamable is in play, it attacks you (regardless of its current location).\n\n[tablet]: +1. The black cat causes a distraction. If this test is successful, choose and evade an enemy at any location with a fight value of X or lower, where X is the amount you succeeded by.\n\n[elder_thing]: -3. If you fail, you must either place 1 of your clues on your location or take 1 damage."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if you are at a [[Graveyard]] location).\n\n[cultist]: Reveal another token. If you fail and The Unnamable is in play, it attacks you (regardless of its current location).\n\n[tablet]: +2. The black cat causes a distraction. If this test is successful, choose and evade an enemy at any location with a fight value of X or lower, where X is the amount you succeeded by.\n\n[elder_thing]: -2. If you fail, you must either place 1 of your clues on your location or take 1 damage."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--Dark Side of the moon
|
|
||||||
if scenario.getDescription() == "Dark Side of the Moon" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is your alarm level.\n\n[cultist]: Reveal another token. If you fail and your alarm level is higher than your modified skill value, after this skill test ends, draw the top card of the encounter deck.\n\n[tablet]: -2. If you fail, raise your alarm level by 1.\n\n[elder_thing]: 0. The black cat summons several other cats to help. If this token is revealed during an evasion attempt and you succeed, deal 2 damage to the evaded enemy."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is half your alarm level (rounded up).\n\n[cultist]: Reveal another token. If you fail and your alarm level is higher than your modified skill value, after this skill test ends, draw the top card of the encounter deck.\n\n[tablet]: -1. If you fail, raise your alarm level by 1.\n\n[elder_thing]: +1. The black cat summons several other cats to help. If this token is revealed during an evasion attempt and you succeed, deal 2 damage to the evaded enemy."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--point of no return
|
|
||||||
if scenario.getDescription() == "Point of No Return" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is 1 more than the amount of damage on this card.\n\n[cultist]: Reveal another token. If you fail, after this skill test ends, draw the top card of the encounter deck.\n\n[tablet]: 0. The black cat helps you navigate through the death-fire. If this token is revealed during an investigation and you succeed, draw 1 card.\n\n[elder_thing]: -4. If you fail by 2 or more, choose a ready enemy at your location or a connecting location. That enemy moves to your location, engages you, and makes an immediate attack."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the amount of damage on this card.\n\n[cultist]: Reveal another token. If you fail, after this skill test ends, draw the top card of the encounter deck.\n\n[tablet]: +1. The black cat helps you navigate through the death-fire. If this token is revealed during an investigation and you succeed, draw 1 card.\n\n[elder_thing]: -3. If you fail by 2 or more, choose a ready enemy at your location or a connecting location. That enemy moves to your location, engages you, and makes an immediate attack."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--where the gods dwell
|
|
||||||
if scenario.getDescription() == "Where the Gods Dwell" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the number of the current act plus the number of the current agenda.\n\n[cultist]: Reveal another token. If you fail, place 1 doom on the current agenda. This effect may cause the current agenda to advance.\n\n[tablet]: -6. If you fail, choose and reveal a copy of Nyarlathotep in your hand. It attacks you and is shuffled into the encounter deck.\n\n[elder_thing]: -1. The black cat reminds you that it's all a dream."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the number of the current act.\n\n[cultist]: Reveal another token. If you fail, place 1 doom on the current agenda.\n\n[tablet]: -4. If you fail, choose and reveal a copy of Nyarlathotep in your hand. It attacks you and is shuffled into the encounter deck.\n\n[elder_thing]: 0. The black cat reminds you that it's all a dream."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--weaver of the cosmos
|
|
||||||
if scenario.getDescription() == "Weaver of the Cosmos" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is the amount of doom on locations in play.\n\n[cultist]: Reveal another token. If you fail, and there is an [[Ancient One]] enemy at your location, it attacks you.\n\n[tablet]: -1. The black cat tears at the web with its claws. If you succeed by 2 or more, remove 1 doom from your location.\n\n[elder_thing]: -4. If this skill test fails during an attack against a [[Spider]] enemy, place 1 doom on that enemy's location."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the highest amount of doom on a location in play.\n\n[cultist]: Reveal another token. If you fail, and there is an [[Ancient One]] enemy at your location, it attacks you.\n\n[tablet]: 0. The black cat tears at the web with its claws. If you succeed by 2 or more, remove 1 doom from your location.\n\n[elder_thing]: -3. If this skill test fails during an attack against a [[Spider]] enemy, place 1 doom on that enemy's location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--pit of despair
|
|
||||||
if scenario.getDescription() == "The Pit of Despair" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-3 instead if your location is partially flooded; -4 instead if your location is fully flooded).\n\n[cultist]: -2. If your location is flooded, take 1 damage.\n\n[tablet]: -2. If you control a key, take 1 horror.\n\n[elder_thing]: -3. If The Amalgam is in the depths, put it into play engaged with you."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-2 instead if your location is partially flooded; -3 instead if your location is fully flooded).\n\n[cultist]: -2. If you fail and your location is flooded, take 1 damage.\n\n[tablet]: -2. If you fail and you control a key, take 1 horror.\n\n[elder_thing]: -3. If you fail and The Amalgam is in the depths, put it into play engaged with you."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--vanishing of elena harper
|
|
||||||
if scenario.getDescription() == "The Vanishing of Elina Harper" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is 1 more than the current agenda number.\n\n[cultist]: -2. Place 1 doom on the nearest enemy (2 doom instead if you failed).\n\n[tablet]: -3. Take 1 horror (1 horror and 1 damage instead if you failed).\n\n[elder_thing]: -4. Place 1 of your clues on your location (2 clues instead if you failed)."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the current agenda number.\n\n[cultist]: -2. If you fail, place 1 doom on the nearest enemy.\n\n[tablet]: -3. If you fail, take 1 horror.\n\n[elder_thing]: -4. If you fail, place 1 of your clues on your location."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--in too deep
|
|
||||||
if scenario.getDescription() == "In Too Deep" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 for each location to the east of your location (on the same row).\n\n[cultist]: -4. If you fail, move to the connecting location to the east, ignoring all barriers.\n\n[tablet]: -5. If you fail, choose a connecting location with no barriers between it and your location. Place 1 barrier between the two locations.\n\n[elder_thing]: -X. X is twice the number of barriers between your location and all connecting locations."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 for each location to the east of your location (on the same row).\n\n[cultist]: -2. If you fail, move to the connecting location to the east, ignoring all barriers.\n\n[tablet]: -3. If you fail, choose a connecting location with no barriers between it and your location. Place 1 barrier between the two locations.\n\n[elder_thing]: -X. X is the number of barriers between your location and all connecting locations."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--devil reef
|
|
||||||
if scenario.getDescription() == "Devil Reef" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -X. X is 1 more than the number of keys the investigators control.\n\n[cultist]: -3. If this is an attack or evasion attempt against a [[Deep One]] enemy, it engages you. (If it is already engaged with you, it disengages first, then re-engages you.)\n\n[tablet]: -4. If you are not in a vehicle, take 1 damage.\n\n[elder_thing]: -5. If your location has a key on it, take 1 horror."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -X. X is the number of keys the investigators control.\n\n[cultist]: -2. If you fail and this is an attack or evasion attempt against a [[Deep One]] enemy, it engages you. (If it is already engaged with you, it disengages first, then re-engages you.)\n\n[tablet]: -3. If you fail and you are not in a vehicle, take 1 damage.\n\n[elder_thing]: -4. If you fail and your location has a key on it, take 1 horror."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--horror in high gear
|
|
||||||
if scenario.getDescription() == "Horror in High Gear" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-4 instead if there are 6 or fewer locations remaining in the Road deck).\n\n[cultist]: -2. For each point you fail by, an investigator in your vehicle places 1 of their clues on your location.\n\n[tablet]: -3. For each point you fail by, an investigator in your vehicle loses 1 resource.\n\n[elder_thing]: -4. Resolve the hunter keyword on each enemy in play."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if there are 6 or fewer locations remaining in the Road deck).\n\n[cultist]: -1. For each point you fail by, an investigator in your vehicle places 1 of their clues on your location.\n\n[tablet]: -2. For each point you fail by, an investigator in your vehicle loses 1 resource.\n\n[elder_thing]: -4. If you fail, resolve the hunter keyword on each enemy in play."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--light in the fog
|
|
||||||
if scenario.getDescription() == "A Light in the Fog" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2. If your location is flooded, reveal an additional chaos token.\n\n[cultist]: -2. If you fail, after this test ends, increase the flood level of your location (if you cannot, take 1 horror instead).\n\n[tablet]: -3. If you fail this test and your location is flooded, take 2 damage.\n\n[elder_thing]: -4. Move the nearest unengaged enemy once toward your location. It loses aloof during this movement."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1. If your location is flooded, reveal an additional chaos token.\n\n[cultist]: -2. If you fail, after this test ends, increase the flood level of your location.\n\n[tablet]: -3. If you fail this test and your location is flooded, take 1 damage.\n\n[elder_thing]: -4. If you fail, move the nearest ready unengaged enemy once toward your location. It loses aloof during this movement."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--lair of dagon
|
|
||||||
if scenario.getDescription() == "The Lair of Dagon" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 for each key on this card.\n\n[cultist]: -2. Reveal an additional chaos token. If you reveal 1 or more [curse] tokens during this test, you automatically fail.\n\n[tablet]: -3. Place each key you control on your location and take 1 damage.\n\n[elder_thing]: -4. Add 2 [curse] tokens to the chaos bag."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 for each key on this card.\n\n[cultist]: 0. Reveal an additional chaos token. If you reveal 1 or more [curse] tokens during this test, you automatically fail.\n\n[tablet]: -3. If you fail, place each key you control on your location.\n\n[elder_thing]: -4. If you fail, add 1 [curse] token to the chaos bag."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
--into the maelstrom
|
|
||||||
if scenario.getDescription() == "Into the Maelstrom" then
|
|
||||||
if scenario.is_face_down == true then
|
|
||||||
tool = "Hard / Expert\n\n[skull]: -2 (-4 instead if there are 4 or more unflooded [[Y'ha-nthlei]] locations in play).\n\n[cultist]: -4. If you fail, place 1 doom on the current agenda (this may cause the current agenda to advance).\n\n[tablet]: -5. If you fail, you must either increase the flood level of your location or take 1 damage.\n\n[elder_thing]: -6. If you fail and there is a key on your location, take 1 horror."
|
|
||||||
else
|
|
||||||
tool = "Easy / Standard\n\n[skull]: -1 (-3 instead if there are 4 or more unflooded [[Y'ha-nthlei]] locations in play).\n\n[cultist]: -3. If you fail, place 1 doom on the current agenda (this may cause the current agenda to advance).\n\n[tablet]: -4. If you fail, you must either increase the flood level of your location or take 1 damage.\n\n[elder_thing]: -5. If you fail and there is a key on your location, take 1 horror."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
getObjectFromGUID("8b081b").editButton({index = 6, tooltip = tool})
|
|
||||||
getObjectFromGUID("bd0ff4").editButton({index = 6, tooltip = tool})
|
|
||||||
getObjectFromGUID("383d8b").editButton({index = 6, tooltip = tool})
|
|
||||||
getObjectFromGUID("0840d5").editButton({index = 6, tooltip = tool})
|
|
||||||
end
|
|
@ -22,7 +22,7 @@
|
|||||||
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/965354846165100486/3DC8FCEF364B30758B09EF96AF9458F2B8E64D56/",
|
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/965354846165100486/3DC8FCEF364B30758B09EF96AF9458F2B8E64D56/",
|
||||||
"WidthScale": 0
|
"WidthScale": 0
|
||||||
},
|
},
|
||||||
"Description": "click to set chaos token difficulty",
|
"Description": "Define difficulties in this object's script.",
|
||||||
"DragSelectable": true,
|
"DragSelectable": true,
|
||||||
"GMNotes": "",
|
"GMNotes": "",
|
||||||
"GUID": "8112ff",
|
"GUID": "8112ff",
|
||||||
@ -34,7 +34,7 @@
|
|||||||
"LayoutGroupSortIndex": 0,
|
"LayoutGroupSortIndex": 0,
|
||||||
"Locked": false,
|
"Locked": false,
|
||||||
"LuaScriptState": "",
|
"LuaScriptState": "",
|
||||||
"LuaScript_path": "Fan-MadeAccessories.aa8b38/WhimsicalsGenericDifficultySelector.05efb4/GenericDifficultySelector.8112ff.ttslua",
|
"LuaScript_path": "Fan-MadeAccessories.aa8b38/GenericDifficultySelector.8112ff.ttslua",
|
||||||
"MeasureMovement": false,
|
"MeasureMovement": false,
|
||||||
"Name": "Custom_Tile",
|
"Name": "Custom_Tile",
|
||||||
"Nickname": "Generic Difficulty Selector",
|
"Nickname": "Generic Difficulty Selector",
|
||||||
@ -54,4 +54,4 @@
|
|||||||
},
|
},
|
||||||
"Value": 0,
|
"Value": 0,
|
||||||
"XmlUI": ""
|
"XmlUI": ""
|
||||||
}
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
-- edit the "tokenData" table to change the preset difficulties
|
||||||
|
-- list of valid ids: 'p1', '0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8',
|
||||||
|
-- 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue', 'bless', 'curse', 'frost'
|
||||||
|
|
||||||
|
local tokenData = {
|
||||||
|
Easy = { 'p1', 'p1', '0', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'skull', 'skull', 'cultist', 'red', 'blue' },
|
||||||
|
Standard = { 'p1', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'm3', 'm4', 'skull', 'skull', 'cultist', 'red', 'blue' },
|
||||||
|
Hard = { '0', '0', '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm5', 'skull', 'skull', 'cultist', 'red', 'blue' },
|
||||||
|
Expert = { '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm4', 'm5', 'm6', 'm8', 'skull', 'skull', 'cultist', 'red', 'blue' }
|
||||||
|
}
|
||||||
|
|
||||||
|
-- create buttons on startup
|
||||||
|
function onLoad()
|
||||||
|
local z_offset = -0.15
|
||||||
|
for difficulty, _ in pairs(tokenData) do
|
||||||
|
local clickFunction = difficulty:lower() .. "Click"
|
||||||
|
self.setVar(clickFunction, function() clickFun(difficulty) end)
|
||||||
|
|
||||||
|
self.createButton({
|
||||||
|
label = difficulty,
|
||||||
|
function_owner = self,
|
||||||
|
click_function = clickFunction,
|
||||||
|
position = { 0, 0.1, z_offset },
|
||||||
|
rotation = { 0, 0, 0 },
|
||||||
|
scale = { 0.47, 1, 0.47 },
|
||||||
|
height = 200,
|
||||||
|
width = 1150,
|
||||||
|
font_size = 100,
|
||||||
|
color = { 0.87, 0.8, 0.70 },
|
||||||
|
font_color = { 0, 0, 0 }
|
||||||
|
})
|
||||||
|
z_offset = z_offset + 0.20
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function clickFun(difficulty)
|
||||||
|
Global.call("setChaosBagState", tokenData[difficulty])
|
||||||
|
end
|
@ -1,57 +0,0 @@
|
|||||||
{
|
|
||||||
"AltLookAngle": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"Autoraise": true,
|
|
||||||
"Bag": {
|
|
||||||
"Order": 0
|
|
||||||
},
|
|
||||||
"ColorDiffuse": {
|
|
||||||
"b": 0,
|
|
||||||
"g": 0.36652,
|
|
||||||
"r": 0.70588
|
|
||||||
},
|
|
||||||
"ContainedObjects_order": [
|
|
||||||
"GenericDifficultySelector.8112ff",
|
|
||||||
"TokenImageProvider.162580",
|
|
||||||
"TokenList.297f5e",
|
|
||||||
"GenericDifficultySelectorInstructions13.c32992"
|
|
||||||
],
|
|
||||||
"ContainedObjects_path": "WhimsicalsGenericDifficultySelector.05efb4",
|
|
||||||
"Description": "",
|
|
||||||
"DragSelectable": true,
|
|
||||||
"GMNotes": "",
|
|
||||||
"GUID": "05efb4",
|
|
||||||
"Grid": true,
|
|
||||||
"GridProjection": false,
|
|
||||||
"Hands": false,
|
|
||||||
"HideWhenFaceDown": false,
|
|
||||||
"IgnoreFoW": false,
|
|
||||||
"LayoutGroupSortIndex": 0,
|
|
||||||
"Locked": false,
|
|
||||||
"LuaScript": "",
|
|
||||||
"LuaScriptState": "",
|
|
||||||
"MaterialIndex": -1,
|
|
||||||
"MeasureMovement": false,
|
|
||||||
"MeshIndex": -1,
|
|
||||||
"Name": "Bag",
|
|
||||||
"Nickname": "Whimsical's Generic Difficulty Selector",
|
|
||||||
"Snap": true,
|
|
||||||
"Sticky": true,
|
|
||||||
"Tooltip": true,
|
|
||||||
"Transform": {
|
|
||||||
"posX": 29.073,
|
|
||||||
"posY": 3.901,
|
|
||||||
"posZ": -21.285,
|
|
||||||
"rotX": 0,
|
|
||||||
"rotY": 0,
|
|
||||||
"rotZ": 0,
|
|
||||||
"scaleX": 1,
|
|
||||||
"scaleY": 1,
|
|
||||||
"scaleZ": 1
|
|
||||||
},
|
|
||||||
"Value": 0,
|
|
||||||
"XmlUI": ""
|
|
||||||
}
|
|
@ -1,169 +0,0 @@
|
|||||||
---
|
|
||||||
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
|
||||||
--- Created by Whimsical.
|
|
||||||
--- DateTime: 2021-08-05 6:14 p.m.
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
local tags = {
|
|
||||||
bag = "chaosBag",
|
|
||||||
provider = "token_list_provider",
|
|
||||||
tokens = "token_image_provider"
|
|
||||||
}
|
|
||||||
|
|
||||||
---@class ChaosToken
|
|
||||||
---@field name string
|
|
||||||
---@field image string
|
|
||||||
local _ = {}
|
|
||||||
|
|
||||||
---@type table<string|number, ChaosToken>
|
|
||||||
local sources
|
|
||||||
|
|
||||||
---@type table<string, any[]>
|
|
||||||
local tokens
|
|
||||||
|
|
||||||
---@param source TTSObject
|
|
||||||
local LoadSource = function (source)
|
|
||||||
tokens = source:getTable("chaos_tokens")
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param token ChaosToken
|
|
||||||
---@param position Vector
|
|
||||||
---@param chaosBag TTSObject
|
|
||||||
---@return number
|
|
||||||
local SpawnToken = function(token, position, chaosBag)
|
|
||||||
spawnObject {
|
|
||||||
type = "Custom_Tile",
|
|
||||||
position = position,
|
|
||||||
scale = { 0.81, 1.0, 0.81 },
|
|
||||||
rotation = { 0, 270, 0 },
|
|
||||||
---@param object TTSObject
|
|
||||||
callback_function = function(object, _, _)
|
|
||||||
object:setName(token.name)
|
|
||||||
chaosBag:putObject(object)
|
|
||||||
end
|
|
||||||
}:setCustomObject {
|
|
||||||
image = token.image,
|
|
||||||
type = 2,
|
|
||||||
thickness = 0.1
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param chaosBag TTSObject
|
|
||||||
local emptyBag = function(chaosBag)
|
|
||||||
local object = chaosBag:getObjects()
|
|
||||||
local pos = self:getPosition()
|
|
||||||
pos.y = pos.y+1
|
|
||||||
|
|
||||||
for _, object in ipairs(object) do
|
|
||||||
chaosBag:takeObject {
|
|
||||||
guid = object.guid,
|
|
||||||
position = pos,
|
|
||||||
---@param item TTSObject
|
|
||||||
callback_function = function (item) item:destruct() end
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param difficulty string
|
|
||||||
local clickFun= function (difficulty)
|
|
||||||
local chaosBag = getObjectsWithTag(tags.bag)[1]
|
|
||||||
|
|
||||||
emptyBag(chaosBag)
|
|
||||||
|
|
||||||
local loading = tokens[difficulty]
|
|
||||||
local pos = self:getPosition()
|
|
||||||
|
|
||||||
for _, token_id in ipairs(loading) do
|
|
||||||
if type(token_id)=="string" then token_id = token_id:lower() end
|
|
||||||
|
|
||||||
local token = sources[token_id]
|
|
||||||
|
|
||||||
if (token==nil) then
|
|
||||||
error("Could not find token \"" .. token_id .. "\".")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
SpawnToken(token, pos, chaosBag)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
---@param difficulty string
|
|
||||||
local MakeClickFun = function(difficulty)
|
|
||||||
return function ()
|
|
||||||
clickFun(difficulty)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param label string
|
|
||||||
---@param z_offset number|nil
|
|
||||||
local makeButton = function(label , z_offset)
|
|
||||||
z_offset = z_offset or -0.15
|
|
||||||
|
|
||||||
_G[label:lower() .. "Click"] = MakeClickFun(label)
|
|
||||||
|
|
||||||
self:createButton({
|
|
||||||
label = label,
|
|
||||||
function_owner = self,
|
|
||||||
click_function = label:lower() .. "Click",
|
|
||||||
position = {0, 0.1, z_offset},
|
|
||||||
rotation = {0, 0, 0},
|
|
||||||
scale = {0.47, 1, 0.47},
|
|
||||||
height = 200,
|
|
||||||
width = 1150,
|
|
||||||
font_size = 100,
|
|
||||||
color = {0.87, 0.8, 0.70},
|
|
||||||
font_color = {0, 0, 0}
|
|
||||||
})
|
|
||||||
return z_offset + 0.20
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param source TTSObject
|
|
||||||
local CreateButtons= function(source)
|
|
||||||
self:clearButtons()
|
|
||||||
|
|
||||||
local z_offset
|
|
||||||
for difficulty,_ in pairs(tokens) do
|
|
||||||
z_offset = makeButton(difficulty, z_offset)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
function LoadTokens()
|
|
||||||
---@type TTSObject[]
|
|
||||||
local image_sources = getObjectsWithTag(tags.tokens)
|
|
||||||
|
|
||||||
if (#image_sources<=0) then
|
|
||||||
error("Cannot find images_sources")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
sources = image_sources[1]:getTable("sources")
|
|
||||||
|
|
||||||
if (tokens~=nil) then CreateButtons() return end
|
|
||||||
|
|
||||||
local source = getObjectsWithTag(tags.provider)
|
|
||||||
|
|
||||||
if (#source<=0) then return end
|
|
||||||
|
|
||||||
LoadSource(source[1])
|
|
||||||
|
|
||||||
CreateButtons()
|
|
||||||
end
|
|
||||||
|
|
||||||
function onload()
|
|
||||||
Timer.create {
|
|
||||||
identifier = self:getGUID(),
|
|
||||||
function_name = "LoadTokens"
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
---@param provider TTSObject
|
|
||||||
function onObjectSpawn(provider)
|
|
||||||
if (not provider:hasTag(tags.provider)) then return end
|
|
||||||
|
|
||||||
LoadSource(provider)
|
|
||||||
|
|
||||||
CreateButtons()
|
|
||||||
end
|
|
@ -1,137 +0,0 @@
|
|||||||
{
|
|
||||||
"AltLookAngle": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"Autoraise": true,
|
|
||||||
"ColorDiffuse": {
|
|
||||||
"b": 1,
|
|
||||||
"g": 1,
|
|
||||||
"r": 1
|
|
||||||
},
|
|
||||||
"Description": "Tool for create custom chaos bag configurations.\n - The actual difficulty selector: click a difficulty to fill the chaos bag.\n- Token Image Provider: edit in scripting editor to add new token types. Cut and Paste to save.\n- Token List: edit in scripting editor to customize difficulties. Cut and Paste to save.\n\nReference of Token codes on following pages:",
|
|
||||||
"DragSelectable": true,
|
|
||||||
"GMNotes": "",
|
|
||||||
"GUID": "c32992",
|
|
||||||
"Grid": true,
|
|
||||||
"GridProjection": false,
|
|
||||||
"Hands": false,
|
|
||||||
"HideWhenFaceDown": false,
|
|
||||||
"IgnoreFoW": false,
|
|
||||||
"LayoutGroupSortIndex": 0,
|
|
||||||
"Locked": false,
|
|
||||||
"LuaScript": "",
|
|
||||||
"LuaScriptState": "",
|
|
||||||
"MeasureMovement": false,
|
|
||||||
"Name": "Notecard",
|
|
||||||
"Nickname": "Generic Difficulty Selector Instructions 1/3",
|
|
||||||
"Snap": true,
|
|
||||||
"States": {
|
|
||||||
"2": {
|
|
||||||
"AltLookAngle": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"Autoraise": true,
|
|
||||||
"ColorDiffuse": {
|
|
||||||
"b": 1,
|
|
||||||
"g": 1,
|
|
||||||
"r": 1
|
|
||||||
},
|
|
||||||
"Description": "1 — -8: Numeric tokens (Don't place quotes around these).\r\n\"S\": Skull.\r\n\"C\": Cultist.\r\n\"T\": Tablet.\r\n\"E\": Elder Thing.\r\n\"Fr\": Frost.",
|
|
||||||
"DragSelectable": true,
|
|
||||||
"GMNotes": "",
|
|
||||||
"GUID": "eab766",
|
|
||||||
"Grid": true,
|
|
||||||
"GridProjection": false,
|
|
||||||
"Hands": false,
|
|
||||||
"HideWhenFaceDown": false,
|
|
||||||
"IgnoreFoW": false,
|
|
||||||
"LayoutGroupSortIndex": 0,
|
|
||||||
"Locked": false,
|
|
||||||
"LuaScript": "",
|
|
||||||
"LuaScriptState": "",
|
|
||||||
"MeasureMovement": false,
|
|
||||||
"Name": "Notecard",
|
|
||||||
"Nickname": "Generic Difficulty Selector Instructions 2/3",
|
|
||||||
"Snap": true,
|
|
||||||
"Sticky": true,
|
|
||||||
"Tooltip": true,
|
|
||||||
"Transform": {
|
|
||||||
"posX": 3.29240441,
|
|
||||||
"posY": 1.33262193,
|
|
||||||
"posZ": 56.0586357,
|
|
||||||
"rotX": 359.9792,
|
|
||||||
"rotY": 89.99884,
|
|
||||||
"rotZ": 359.983215,
|
|
||||||
"scaleX": 1,
|
|
||||||
"scaleY": 1,
|
|
||||||
"scaleZ": 1
|
|
||||||
},
|
|
||||||
"Value": 0,
|
|
||||||
"XmlUI": ""
|
|
||||||
},
|
|
||||||
"3": {
|
|
||||||
"AltLookAngle": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"Autoraise": true,
|
|
||||||
"ColorDiffuse": {
|
|
||||||
"b": 1,
|
|
||||||
"g": 1,
|
|
||||||
"r": 1
|
|
||||||
},
|
|
||||||
"Description": "\"*\": Elder Sign.\r\n\"F\": Auto-fail.\r\n\"+\": Bless.\r\n\"-\": Curse.",
|
|
||||||
"DragSelectable": true,
|
|
||||||
"GMNotes": "",
|
|
||||||
"GUID": "309295",
|
|
||||||
"Grid": true,
|
|
||||||
"GridProjection": false,
|
|
||||||
"Hands": false,
|
|
||||||
"HideWhenFaceDown": false,
|
|
||||||
"IgnoreFoW": false,
|
|
||||||
"LayoutGroupSortIndex": 0,
|
|
||||||
"Locked": false,
|
|
||||||
"LuaScript": "",
|
|
||||||
"LuaScriptState": "",
|
|
||||||
"MeasureMovement": false,
|
|
||||||
"Name": "Notecard",
|
|
||||||
"Nickname": "Generic Difficulty Selector Instructions 3/3",
|
|
||||||
"Snap": true,
|
|
||||||
"Sticky": true,
|
|
||||||
"Tooltip": true,
|
|
||||||
"Transform": {
|
|
||||||
"posX": 3.29240441,
|
|
||||||
"posY": 1.33262193,
|
|
||||||
"posZ": 56.0586357,
|
|
||||||
"rotX": 359.9792,
|
|
||||||
"rotY": 89.9988556,
|
|
||||||
"rotZ": 359.983215,
|
|
||||||
"scaleX": 1,
|
|
||||||
"scaleY": 1,
|
|
||||||
"scaleZ": 1
|
|
||||||
},
|
|
||||||
"Value": 0,
|
|
||||||
"XmlUI": ""
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"Sticky": true,
|
|
||||||
"Tooltip": true,
|
|
||||||
"Transform": {
|
|
||||||
"posX": 13.505,
|
|
||||||
"posY": 3.625,
|
|
||||||
"posZ": 30.273,
|
|
||||||
"rotX": 0,
|
|
||||||
"rotY": 90,
|
|
||||||
"rotZ": 0,
|
|
||||||
"scaleX": 1,
|
|
||||||
"scaleY": 1,
|
|
||||||
"scaleZ": 1
|
|
||||||
},
|
|
||||||
"Value": 0,
|
|
||||||
"XmlUI": ""
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
{
|
|
||||||
"AltLookAngle": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"Autoraise": true,
|
|
||||||
"ColorDiffuse": {
|
|
||||||
"b": 1,
|
|
||||||
"g": 1,
|
|
||||||
"r": 1
|
|
||||||
},
|
|
||||||
"Description": "",
|
|
||||||
"DragSelectable": true,
|
|
||||||
"GMNotes": "",
|
|
||||||
"GUID": "162580",
|
|
||||||
"Grid": true,
|
|
||||||
"GridProjection": false,
|
|
||||||
"Hands": false,
|
|
||||||
"HideWhenFaceDown": false,
|
|
||||||
"IgnoreFoW": false,
|
|
||||||
"LayoutGroupSortIndex": 0,
|
|
||||||
"Locked": false,
|
|
||||||
"LuaScriptState": "",
|
|
||||||
"LuaScript_path": "Fan-MadeAccessories.aa8b38/WhimsicalsGenericDifficultySelector.05efb4/TokenImageProvider.162580.ttslua",
|
|
||||||
"MeasureMovement": false,
|
|
||||||
"Name": "Checker_white",
|
|
||||||
"Nickname": "Token Image Provider",
|
|
||||||
"Snap": true,
|
|
||||||
"Sticky": true,
|
|
||||||
"Tags": [
|
|
||||||
"token_image_provider"
|
|
||||||
],
|
|
||||||
"Tooltip": true,
|
|
||||||
"Transform": {
|
|
||||||
"posX": 13.194,
|
|
||||||
"posY": 3.807,
|
|
||||||
"posZ": 28.835,
|
|
||||||
"rotX": 0,
|
|
||||||
"rotY": 270,
|
|
||||||
"rotZ": 180,
|
|
||||||
"scaleX": 1,
|
|
||||||
"scaleY": 1,
|
|
||||||
"scaleZ": 1
|
|
||||||
},
|
|
||||||
"Value": 0,
|
|
||||||
"XmlUI": ""
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
---
|
|
||||||
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
|
||||||
--- Created by Whimsical.
|
|
||||||
--- DateTime: 2021-08-05 6:51 p.m.
|
|
||||||
---
|
|
||||||
|
|
||||||
---@param name string
|
|
||||||
---@param image string
|
|
||||||
---@return ChaosToken
|
|
||||||
local MakeToken = function (name, image)
|
|
||||||
return {
|
|
||||||
name = name,
|
|
||||||
image = image
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
sources = {
|
|
||||||
[1] = MakeToken("+1", "https://i.imgur.com/uIx8jbY.png"),
|
|
||||||
[0] = MakeToken("0", "https://i.imgur.com/btEtVfd.png"),
|
|
||||||
[-1] = MakeToken("-1", "https://i.imgur.com/w3XbrCC.png"),
|
|
||||||
[-2] = MakeToken("-2", "https://i.imgur.com/bfTg2hb.png"),
|
|
||||||
[-3] = MakeToken("-3", "https://i.imgur.com/yfs8gHq.png"),
|
|
||||||
[-4] = MakeToken("-4", "https://i.imgur.com/qrgGQRD.png"),
|
|
||||||
[-5] = MakeToken("-5", "https://i.imgur.com/3Ym1IeG.png"),
|
|
||||||
[-6] = MakeToken("-6", "https://i.imgur.com/c9qdSzS.png"),
|
|
||||||
[-7] = MakeToken("-7", "https://i.imgur.com/4WRD42n.png"),
|
|
||||||
[-8] = MakeToken("-8", "https://i.imgur.com/9t3rPTQ.png"),
|
|
||||||
["s"] = MakeToken("Skull", "https://i.imgur.com/stbBxtx.png"),
|
|
||||||
["c"] = MakeToken("Cultist", "https://i.imgur.com/VzhJJaH.png"),
|
|
||||||
["t"] = MakeToken("Tablet", "https://i.imgur.com/1plY463.png"),
|
|
||||||
["e"] = MakeToken("Elder Thing", "https://i.imgur.com/ttnspKt.png"),
|
|
||||||
["*"] = MakeToken("Elder Sign", "https://i.imgur.com/nEmqjmj.png"),
|
|
||||||
["f"] = MakeToken("Auto-fail", "https://i.imgur.com/lns4fhz.png"),
|
|
||||||
["+"] = MakeToken("Bless", "http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/"),
|
|
||||||
["-"] = MakeToken("Curse", "http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/"),
|
|
||||||
["fr"] = MakeToken("Frost", "http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/"),
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
{
|
|
||||||
"AltLookAngle": {
|
|
||||||
"x": 0,
|
|
||||||
"y": 0,
|
|
||||||
"z": 0
|
|
||||||
},
|
|
||||||
"Autoraise": true,
|
|
||||||
"ColorDiffuse": {
|
|
||||||
"b": 0,
|
|
||||||
"g": 0,
|
|
||||||
"r": 0
|
|
||||||
},
|
|
||||||
"Description": "",
|
|
||||||
"DragSelectable": true,
|
|
||||||
"GMNotes": "",
|
|
||||||
"GUID": "297f5e",
|
|
||||||
"Grid": true,
|
|
||||||
"GridProjection": false,
|
|
||||||
"Hands": false,
|
|
||||||
"HideWhenFaceDown": false,
|
|
||||||
"IgnoreFoW": false,
|
|
||||||
"LayoutGroupSortIndex": 0,
|
|
||||||
"Locked": false,
|
|
||||||
"LuaScriptState": "",
|
|
||||||
"LuaScript_path": "Fan-MadeAccessories.aa8b38/WhimsicalsGenericDifficultySelector.05efb4/TokenList.297f5e.ttslua",
|
|
||||||
"MeasureMovement": false,
|
|
||||||
"Name": "Checker_black",
|
|
||||||
"Nickname": "Token List",
|
|
||||||
"Snap": true,
|
|
||||||
"Sticky": true,
|
|
||||||
"Tags": [
|
|
||||||
"mlc_memory_object",
|
|
||||||
"token_list_provider"
|
|
||||||
],
|
|
||||||
"Tooltip": true,
|
|
||||||
"Transform": {
|
|
||||||
"posX": 12.984,
|
|
||||||
"posY": 4.045,
|
|
||||||
"posZ": 29.828,
|
|
||||||
"rotX": 0,
|
|
||||||
"rotY": 270,
|
|
||||||
"rotZ": 206,
|
|
||||||
"scaleX": 1,
|
|
||||||
"scaleY": 1,
|
|
||||||
"scaleZ": 1
|
|
||||||
},
|
|
||||||
"Value": 0,
|
|
||||||
"XmlUI": ""
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
--- Generated by EmmyLua(https://github.com/EmmyLua)
|
|
||||||
--- Created by Whimsical.
|
|
||||||
--- DateTime: 2021-08-05 7:19 p.m.
|
|
||||||
---
|
|
||||||
|
|
||||||
chaos_tokens = {
|
|
||||||
Easy = {1, 1, 0, 0, -1, -1, -1, -2, -2, "S", "S", "C", "T", "F", "*"},
|
|
||||||
Standard = {1, 0, 0, -1, -1, -1, -2, -2, -3, -4, "S", "S", "C", "T", "F", "*"},
|
|
||||||
Hard = {0, 0, -1, -1, -2, -2, -3, -4, -4, -5, "Fr", "Fr", "S", "S", "C", "T", "F", "*"},
|
|
||||||
Expert = {0, -1, -2, -2, -3, -4, -4, -5, -7, "Fr", "Fr", "Fr", "S", "S", "C", "T", "F", "*"}
|
|
||||||
}
|
|
@ -2,7 +2,6 @@
|
|||||||
-- specific setup (different for each playmat)
|
-- specific setup (different for each playmat)
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
PLAYER_COLOR = "White"
|
|
||||||
PLAY_ZONE_POSITION = { x = -54.5, y = 4, z = 19 }
|
PLAY_ZONE_POSITION = { x = -54.5, y = 4, z = 19 }
|
||||||
PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 }
|
PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 }
|
||||||
TRASHCAN_GUID = "147e80"
|
TRASHCAN_GUID = "147e80"
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
-- specific setup (different for each playmat)
|
-- specific setup (different for each playmat)
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
PLAYER_COLOR = "Orange"
|
|
||||||
PLAY_ZONE_POSITION = { x = -54.5, y = 4, z = -19 }
|
PLAY_ZONE_POSITION = { x = -54.5, y = 4, z = -19 }
|
||||||
PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 }
|
PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 }
|
||||||
TRASHCAN_GUID = "f7b6c8"
|
TRASHCAN_GUID = "f7b6c8"
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
-- specific setup (different for each playmat)
|
-- specific setup (different for each playmat)
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
PLAYER_COLOR = "Green"
|
|
||||||
PLAY_ZONE_POSITION = { x = -26.5, y = 4, z = 26.5 }
|
PLAY_ZONE_POSITION = { x = -26.5, y = 4, z = 26.5 }
|
||||||
PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 }
|
PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 }
|
||||||
TRASHCAN_GUID = "5f896a"
|
TRASHCAN_GUID = "5f896a"
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
-- specific setup (different for each playmat)
|
-- specific setup (different for each playmat)
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
PLAYER_COLOR = "Red"
|
|
||||||
PLAY_ZONE_POSITION = { x = -26.5, y = 4, z = -26.5 }
|
PLAY_ZONE_POSITION = { x = -26.5, y = 4, z = -26.5 }
|
||||||
PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 }
|
PLAY_ZONE_SCALE = { x = 32, y = 5, z = 12 }
|
||||||
TRASHCAN_GUID = "4b8594"
|
TRASHCAN_GUID = "4b8594"
|
||||||
|
@ -1,30 +1,10 @@
|
|||||||
local TOKEN_URL = {
|
local TOKEN_IDS = {
|
||||||
ElderSign = "https://i.imgur.com/nEmqjmj.png",
|
|
||||||
plusOne = "https://i.imgur.com/uIx8jbY.png",
|
|
||||||
Zero = "https://i.imgur.com/btEtVfd.png",
|
|
||||||
minusOne = "https://i.imgur.com/w3XbrCC.png",
|
|
||||||
minusTwo = "https://i.imgur.com/bfTg2hb.png",
|
|
||||||
minusThree = "https://i.imgur.com/yfs8gHq.png",
|
|
||||||
minusFour = "https://i.imgur.com/qrgGQRD.png",
|
|
||||||
minusFive = "https://i.imgur.com/3Ym1IeG.png",
|
|
||||||
minusSix = "https://i.imgur.com/c9qdSzS.png",
|
|
||||||
minusSeven = "https://i.imgur.com/4WRD42n.png",
|
|
||||||
minusEight = "https://i.imgur.com/9t3rPTQ.png",
|
|
||||||
Skull = "https://i.imgur.com/stbBxtx.png",
|
|
||||||
Cultist = "https://i.imgur.com/VzhJJaH.png",
|
|
||||||
Tablet = "https://i.imgur.com/1plY463.png",
|
|
||||||
ElderThing = "https://i.imgur.com/ttnspKt.png",
|
|
||||||
AutoFail = "https://i.imgur.com/lns4fhz.png",
|
|
||||||
Frost = "http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/"
|
|
||||||
}
|
|
||||||
|
|
||||||
local TOKEN_NAMES = {
|
|
||||||
-- first row
|
-- first row
|
||||||
"plusOne", "Zero", "minusOne", "minusTwo", "minusThree", "minusFour",
|
"p1", "0", "m1", "m2", "m3", "m4",
|
||||||
-- second row
|
-- second row
|
||||||
"minusFive", "minusSix", "minusSeven", "minusEight", "Frost",
|
"m5", "m6", "m7", "m8", "frost",
|
||||||
-- third row
|
-- third row
|
||||||
"ElderSign", "Skull", "Cultist", "Tablet", "ElderThing", "AutoFail"
|
"blue", "skull", "cultist", "tablet", "elder", "red"
|
||||||
}
|
}
|
||||||
|
|
||||||
local BUTTON_TOOLTIP = {
|
local BUTTON_TOOLTIP = {
|
||||||
@ -52,9 +32,6 @@ buttonParameters.color = { 0, 0, 0, 0 }
|
|||||||
buttonParameters.width = 300
|
buttonParameters.width = 300
|
||||||
buttonParameters.height = 300
|
buttonParameters.height = 300
|
||||||
|
|
||||||
local UPDATING = false
|
|
||||||
local tokenArranger
|
|
||||||
|
|
||||||
local name
|
local name
|
||||||
local tokens = {}
|
local tokens = {}
|
||||||
|
|
||||||
@ -76,108 +53,30 @@ function onLoad()
|
|||||||
|
|
||||||
self.createButton(buttonParameters)
|
self.createButton(buttonParameters)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.addContextMenuItem("More Information", function()
|
|
||||||
printToAll("------------------------------", "White")
|
|
||||||
printToAll("Chaos Bag Manager by Chr1Z", "Orange")
|
|
||||||
end)
|
|
||||||
|
|
||||||
tokenArranger = getObjectFromGUID("022907")
|
|
||||||
end
|
|
||||||
|
|
||||||
-- get chaos bag from scripting zone and description
|
|
||||||
function getChaosBag()
|
|
||||||
local chaosbag = nil
|
|
||||||
local chaosbag_zone = getObjectFromGUID("83ef06")
|
|
||||||
|
|
||||||
-- error handling: scripting zone not found
|
|
||||||
if chaosbag_zone == nil then
|
|
||||||
printToAll("Zone for chaos bag detection couldn't be found.", "Red")
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
for _, v in ipairs(chaosbag_zone.getObjects()) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- error handling: chaos bag not found
|
|
||||||
if chaosbag == nil then
|
|
||||||
printToAll("Chaos bag couldn't be found.", "Red")
|
|
||||||
end
|
|
||||||
return chaosbag
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- click function for buttons
|
-- click function for buttons
|
||||||
function buttonClick(index, isRightClick)
|
function buttonClick(index, isRightClick)
|
||||||
chaosbag = getChaosBag()
|
local tokenId = TOKEN_IDS[index]
|
||||||
|
|
||||||
-- error handling: chaos bag not found
|
|
||||||
if chaosbag == nil then return end
|
|
||||||
|
|
||||||
name = BUTTON_TOOLTIP[index]
|
|
||||||
tokens = {}
|
|
||||||
for _, v in ipairs(chaosbag.getObjects()) do
|
|
||||||
if v.name == name then table.insert(tokens, v.guid) end
|
|
||||||
end
|
|
||||||
|
|
||||||
token = TOKEN_NAMES[index]
|
|
||||||
if isRightClick then
|
if isRightClick then
|
||||||
-- error handling: no matching token found
|
Global.call("removeChaosToken", tokenId)
|
||||||
if #tokens == 0 then
|
else
|
||||||
printToAll("No " .. name .. " tokens in the chaos bag.", "Yellow")
|
local tokens = {}
|
||||||
return
|
local name = BUTTON_TOOLTIP[index]
|
||||||
|
local chaosbag = Global.call("findChaosBag")
|
||||||
|
|
||||||
|
for _, v in ipairs(chaosbag.getObjects()) do
|
||||||
|
if v.name == name then table.insert(tokens, v.guid) end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- remove token
|
|
||||||
chaosbag.takeObject({
|
|
||||||
guid = tokens[1],
|
|
||||||
position = self.getPosition(),
|
|
||||||
smooth = false,
|
|
||||||
callback_function = removeCallback
|
|
||||||
})
|
|
||||||
else
|
|
||||||
-- spawn token (only 8 frost tokens allowed)
|
-- spawn token (only 8 frost tokens allowed)
|
||||||
if token == "Frost" and #tokens == 8 then
|
if tokenId == "frost" and #tokens == 8 then
|
||||||
printToAll("The maximum of 8 Frost tokens is already in the bag.", "Yellow")
|
printToAll("The maximum of 8 Frost tokens is already in the bag.", "Yellow")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local obj = spawnObject({
|
Global.call("spawnChaosToken", tokenId)
|
||||||
type = 'Custom_Tile',
|
printToAll("Adding " .. name .. " token (in bag: " .. #tokens + 1 .. ")", "White")
|
||||||
position = chaosbag.getPosition() + Vector(0, 1, 0),
|
|
||||||
rotation = { x = 0, y = 260, z = 0 },
|
|
||||||
callback_function = spawnCallback
|
|
||||||
})
|
|
||||||
obj.setCustomObject({
|
|
||||||
type = 2,
|
|
||||||
image = TOKEN_URL[token],
|
|
||||||
thickness = 0.1
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
updateTokenArranger()
|
|
||||||
end
|
|
||||||
|
|
||||||
function removeCallback(obj)
|
|
||||||
printToAll("Removing " .. name .. " token (in bag: " .. #tokens - 1 .. ")", "White")
|
|
||||||
obj.destruct()
|
|
||||||
end
|
|
||||||
|
|
||||||
function spawnCallback(obj)
|
|
||||||
obj.scale { 0.81, 1, 0.81 }
|
|
||||||
obj.setName(name)
|
|
||||||
printToAll("Adding " .. name .. " token (in bag: " .. #tokens + 1 .. ")", "White")
|
|
||||||
end
|
|
||||||
|
|
||||||
function updateTokenArranger()
|
|
||||||
if tokenArranger and not UPDATING then
|
|
||||||
UPDATING = true
|
|
||||||
Wait.time(function()
|
|
||||||
UPDATING = false
|
|
||||||
tokenArranger.call("layout")
|
|
||||||
end, 1.5)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -2,13 +2,10 @@
|
|||||||
Cleans up the table for the next scenario in a campaign:
|
Cleans up the table for the next scenario in a campaign:
|
||||||
- sets counters to default values (resources and doom) or trauma values (health and sanity, if not disabled) from campaign log
|
- sets counters to default values (resources and doom) or trauma values (health and sanity, if not disabled) from campaign log
|
||||||
- puts everything on playmats and hands into respective trashcans
|
- puts everything on playmats and hands into respective trashcans
|
||||||
- use the IGNORE_TAG to exclude objects from tidying (default: "CleanUpHelper_Ignore")
|
- use the IGNORE_TAG to exclude objects from tidying (default: "CleanUpHelper_Ignore")]]
|
||||||
--]]
|
|
||||||
|
|
||||||
local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi")
|
local tokenSpawnTrackerApi = require("core/token/TokenSpawnTrackerApi")
|
||||||
|
local playmatApi = require("playermat/PlaymatApi")
|
||||||
-- enable this for debugging
|
|
||||||
local SHOW_RAYS = false
|
|
||||||
|
|
||||||
-- these objects will be ignored
|
-- these objects will be ignored
|
||||||
local IGNORE_GUIDS = {
|
local IGNORE_GUIDS = {
|
||||||
@ -81,9 +78,7 @@ buttonParameters.function_owner = self
|
|||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
function onSave()
|
function onSave()
|
||||||
return JSON.encode({
|
return JSON.encode({ options = options })
|
||||||
options = options
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function onLoad(savedData)
|
function onLoad(savedData)
|
||||||
@ -213,7 +208,7 @@ function resetSkillTrackers()
|
|||||||
if obj ~= nil then
|
if obj ~= nil then
|
||||||
obj.call("updateStats", { 1, 1, 1, 1 })
|
obj.call("updateStats", { 1, 1, 1, 1 })
|
||||||
else
|
else
|
||||||
printToAll("Skill tracker number " .. i .. " could not be found.", "Yellow")
|
printToAll("Skill tracker for " .. COLORS[i] .. " playmat could not be found.", "Yellow")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -296,7 +291,7 @@ function discardHands()
|
|||||||
for i = 1, 4 do
|
for i = 1, 4 do
|
||||||
local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[i])
|
local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[i])
|
||||||
if trashcan == nil then return end
|
if trashcan == nil then return end
|
||||||
local hand = Player[COLORS[i]].getHandObjects()
|
local hand = Player[playmatApi.getPlayerColor(COLORS[i])].getHandObjects()
|
||||||
for j = #hand, 1, -1 do
|
for j = #hand, 1, -1 do
|
||||||
trashcan.putObject(hand[j])
|
trashcan.putObject(hand[j])
|
||||||
end
|
end
|
||||||
@ -339,7 +334,7 @@ function tidyPlayerMatCoroutine()
|
|||||||
local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[i])
|
local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[i])
|
||||||
if trashcan == nil then
|
if trashcan == nil then
|
||||||
printToAll("Trashcan for " .. COLORS[i] .. " playmat could not be found!", "Red")
|
printToAll("Trashcan for " .. COLORS[i] .. " playmat could not be found!", "Red")
|
||||||
return
|
return 1
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, entry in ipairs(findObjects(i)) do
|
for _, entry in ipairs(findObjects(i)) do
|
||||||
@ -390,7 +385,7 @@ function findObjects(num)
|
|||||||
size = PHYSICS_SCALE[num],
|
size = PHYSICS_SCALE[num],
|
||||||
origin = PHYSICS_POSITION[num],
|
origin = PHYSICS_POSITION[num],
|
||||||
orientation = { 0, PHYSICS_ROTATION[num], 0 },
|
orientation = { 0, PHYSICS_ROTATION[num], 0 },
|
||||||
debug = SHOW_RAYS
|
debug = false
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
local playmatAPI = require("playermat/PlaymatApi")
|
local playmatApi = require("playermat/PlaymatApi")
|
||||||
|
|
||||||
|
-- forward declaration of variables that are used across functions
|
||||||
local matColor, handColor, loopId, hovering
|
local matColor, handColor, loopId, hovering
|
||||||
|
|
||||||
function onLoad()
|
function onLoad()
|
||||||
@ -62,8 +64,8 @@ end
|
|||||||
|
|
||||||
-- updates the matcolor and handcolor variable
|
-- updates the matcolor and handcolor variable
|
||||||
function updateColors()
|
function updateColors()
|
||||||
matColor = playmatAPI.getMatColorByPosition(self.getPosition())
|
matColor = playmatApi.getMatColorByPosition(self.getPosition())
|
||||||
handColor = playmatAPI.getHandColor(matColor)
|
handColor = playmatApi.getPlayerColor(matColor)
|
||||||
self.setName(handColor .. " Hand Helper")
|
self.setName(handColor .. " Hand Helper")
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -78,7 +80,7 @@ function updateValue(toggle)
|
|||||||
if Player[handColor].getHandCount() == 0 then return end
|
if Player[handColor].getHandCount() == 0 then return end
|
||||||
|
|
||||||
-- get state of "Dream-Enhancing Serum" from playermat and update button label
|
-- get state of "Dream-Enhancing Serum" from playermat and update button label
|
||||||
local des = playmatAPI.isDES(matColor)
|
local des = playmatApi.isDES(matColor)
|
||||||
if toggle then des = not des end
|
if toggle then des = not des end
|
||||||
self.editButton({ index = 1, label = "DES: " .. (des and "✓" or "✗") })
|
self.editButton({ index = 1, label = "DES: " .. (des and "✓" or "✗") })
|
||||||
|
|
||||||
@ -110,5 +112,5 @@ end
|
|||||||
|
|
||||||
-- discards a random non-hidden card from hand
|
-- discards a random non-hidden card from hand
|
||||||
function discardRandom()
|
function discardRandom()
|
||||||
playmatAPI.doDiscardOne(matColor)
|
playmatApi.doDiscardOne(matColor)
|
||||||
end
|
end
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
local playmatAPI = require("playermat/PlaymatApi")
|
local playmatApi = require("playermat/PlaymatApi")
|
||||||
|
|
||||||
-- forward declaration of variables that are used across functions
|
-- forward declaration of variables that are used across functions
|
||||||
local matColor
|
local matColor, handColor, setAsidePosition, setAsideRotation, drawDeckPosition
|
||||||
local setAsidePosition
|
|
||||||
local setAsideRotation
|
|
||||||
local drawDeckPosition
|
|
||||||
|
|
||||||
local quickParameters = {}
|
local quickParameters = {}
|
||||||
quickParameters.function_owner = self
|
quickParameters.function_owner = self
|
||||||
@ -102,10 +99,11 @@ end
|
|||||||
|
|
||||||
-- start the search (change UI, set handCards aside, draw cards)
|
-- start the search (change UI, set handCards aside, draw cards)
|
||||||
function startSearch(messageColor, number)
|
function startSearch(messageColor, number)
|
||||||
matColor = playmatAPI.getMatColorByPosition(self.getPosition())
|
matColor = playmatApi.getMatColorByPosition(self.getPosition())
|
||||||
|
handColor = playmatApi.getPlayerColor(matColor)
|
||||||
|
|
||||||
-- get draw deck
|
-- get draw deck
|
||||||
local drawDeck = playmatAPI.getDrawDeck(matColor)
|
local drawDeck = playmatApi.getDrawDeck(matColor)
|
||||||
if drawDeck == nil then
|
if drawDeck == nil then
|
||||||
printToColor(matColor .. " draw deck could not be found!", messageColor, "Red")
|
printToColor(matColor .. " draw deck could not be found!", messageColor, "Red")
|
||||||
return
|
return
|
||||||
@ -121,8 +119,8 @@ function startSearch(messageColor, number)
|
|||||||
end
|
end
|
||||||
|
|
||||||
-- get position and rotation for set aside cards
|
-- get position and rotation for set aside cards
|
||||||
local handData = Player[matColor].getHandTransform()
|
local handData = Player[handColor].getHandTransform()
|
||||||
local handCards = Player[matColor].getHandObjects()
|
local handCards = Player[handColor].getHandObjects()
|
||||||
setAsidePosition = handData.position + offset * handData.right
|
setAsidePosition = handData.position + offset * handData.right
|
||||||
setAsideRotation = { handData.rotation.x, handData.rotation.y + 180, 180 }
|
setAsideRotation = { handData.rotation.x, handData.rotation.y + 180, 180 }
|
||||||
|
|
||||||
@ -136,18 +134,18 @@ function startSearch(messageColor, number)
|
|||||||
local object = v.hit_object
|
local object = v.hit_object
|
||||||
if object.tag == "Card" and not object.is_face_down then
|
if object.tag == "Card" and not object.is_face_down then
|
||||||
object.flip()
|
object.flip()
|
||||||
Wait.time(function() drawDeck = playmatAPI.getDrawDeck(matColor) end, 1)
|
Wait.time(function() drawDeck = playmatApi.getDrawDeck(matColor) end, 1)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Wait.time(function() drawDeck.deal(number, matColor) end, 1)
|
Wait.time(function() drawDeck.deal(number, handColor) end, 1)
|
||||||
searchView()
|
searchView()
|
||||||
end
|
end
|
||||||
|
|
||||||
-- place handCards back into deck and optionally shuffle
|
-- place handCards back into deck and optionally shuffle
|
||||||
function endSearch(_, _, isRightClick)
|
function endSearch(_, _, isRightClick)
|
||||||
local handCards = Player[matColor].getHandObjects()
|
local handCards = Player[handColor].getHandObjects()
|
||||||
|
|
||||||
for i = #handCards, 1, -1 do
|
for i = #handCards, 1, -1 do
|
||||||
handCards[i].setPosition(drawDeckPosition + Vector(0, 6 - i * 0.3, 0))
|
handCards[i].setPosition(drawDeckPosition + Vector(0, 6 - i * 0.3, 0))
|
||||||
@ -156,7 +154,7 @@ function endSearch(_, _, isRightClick)
|
|||||||
|
|
||||||
if not isRightClick then
|
if not isRightClick then
|
||||||
Wait.time(function()
|
Wait.time(function()
|
||||||
local deck = playmatAPI.getDrawDeck(matColor)
|
local deck = playmatApi.getDrawDeck(matColor)
|
||||||
if deck ~= nil then
|
if deck ~= nil then
|
||||||
deck.shuffle()
|
deck.shuffle()
|
||||||
end
|
end
|
||||||
@ -168,11 +166,11 @@ function endSearch(_, _, isRightClick)
|
|||||||
local obj = v.hit_object
|
local obj = v.hit_object
|
||||||
if obj.tag == "Deck" then
|
if obj.tag == "Deck" then
|
||||||
Wait.time(function()
|
Wait.time(function()
|
||||||
obj.deal(#obj.getObjects(), matColor)
|
obj.deal(#obj.getObjects(), handColor)
|
||||||
end, 1)
|
end, 1)
|
||||||
break
|
break
|
||||||
elseif obj.tag == "Card" then
|
elseif obj.tag == "Card" then
|
||||||
obj.setPosition(Player[matColor].getHandTransform().position)
|
obj.setPosition(Player[handColor].getHandTransform().position)
|
||||||
obj.flip()
|
obj.flip()
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
@ -374,7 +374,7 @@ end
|
|||||||
function onTokenDataChanged(parameters)
|
function onTokenDataChanged(parameters)
|
||||||
local tokenData = parameters.tokenData or {}
|
local tokenData = parameters.tokenData or {}
|
||||||
local currentScenario = parameters.currentScenario or ""
|
local currentScenario = parameters.currentScenario or ""
|
||||||
local useFrontData = parameters.useFrontData or true
|
local useFrontData = parameters.useFrontData
|
||||||
|
|
||||||
-- only update if this data is new
|
-- only update if this data is new
|
||||||
local info = currentScenario .. tostring(useFrontData)
|
local info = currentScenario .. tostring(useFrontData)
|
||||||
|
@ -24,7 +24,7 @@ do
|
|||||||
|
|
||||||
-- updates the laid out tokens
|
-- updates the laid out tokens
|
||||||
TokenArrangerApi.layout = function()
|
TokenArrangerApi.layout = function()
|
||||||
callIfExistent("layout")
|
Wait.time(function() callIfExistent("layout") end, 0.1)
|
||||||
end
|
end
|
||||||
|
|
||||||
return TokenArrangerApi
|
return TokenArrangerApi
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
require("arkhamdb/DeckImporterUi")
|
require("arkhamdb/DeckImporterUi")
|
||||||
require("playercards/PlayerCardSpawner")
|
require("playercards/PlayerCardSpawner")
|
||||||
|
|
||||||
|
local playmatApi = require("playermat/PlaymatApi")
|
||||||
local playAreaApi = require("core/PlayAreaApi")
|
local playAreaApi = require("core/PlayAreaApi")
|
||||||
local arkhamDb = require("arkhamdb/ArkhamDb")
|
local arkhamDb = require("arkhamdb/ArkhamDb")
|
||||||
local zones = require("playermat/Zones")
|
local zones = require("playermat/Zones")
|
||||||
@ -184,7 +185,8 @@ end
|
|||||||
---@param deck Object Callback-provided spawned deck object
|
---@param deck Object Callback-provided spawned deck object
|
||||||
---@param playerColor String Color of the player to draw the cards to
|
---@param playerColor String Color of the player to draw the cards to
|
||||||
function deckSpawned(deck, playerColor)
|
function deckSpawned(deck, playerColor)
|
||||||
local handPos = Player[playerColor].getHandTransform(1).position -- Only one hand zone per player
|
local player = Player[playmatApi.getPlayerColor(playerColor)]
|
||||||
|
local handPos = player.getHandTransform(1).position -- Only one hand zone per player
|
||||||
local deckCards = deck.getData().ContainedObjects
|
local deckCards = deck.getData().ContainedObjects
|
||||||
-- Process in reverse order so taking cards out doesn't upset the indexing
|
-- Process in reverse order so taking cards out doesn't upset the indexing
|
||||||
for i = #deckCards, 1, -1 do
|
for i = #deckCards, 1, -1 do
|
||||||
|
@ -1,9 +1,4 @@
|
|||||||
local tokenArrangerApi = require("accessories/TokenArrangerApi")
|
local tokenArrangerApi = require("accessories/TokenArrangerApi")
|
||||||
|
|
||||||
local IMAGE_URL = {
|
|
||||||
Bless = "http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/",
|
|
||||||
Curse = "http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/"
|
|
||||||
}
|
|
||||||
|
|
||||||
-- common button parameters
|
-- common button parameters
|
||||||
local buttonParamaters = {}
|
local buttonParamaters = {}
|
||||||
@ -12,11 +7,21 @@ buttonParamaters.color = { 0, 0, 0, 0 }
|
|||||||
buttonParamaters.width = 700
|
buttonParamaters.width = 700
|
||||||
buttonParamaters.height = 700
|
buttonParamaters.height = 700
|
||||||
|
|
||||||
local altState = false
|
local altState = false
|
||||||
local MODE = { [false] = "Add / Remove", [true] = "Take / Return" }
|
local MODE = {
|
||||||
local BUTTON_COLOR = { [false] = { 0.4, 0.4, 0.4 }, [true] = { 0.9, 0.9, 0.9 } }
|
[false] = "Add / Remove",
|
||||||
local FONT_COLOR = { [false] = { 1, 1, 1 }, [true] = { 0, 0, 0 } }
|
[true] = "Take / Return"
|
||||||
local whitespace = " "
|
}
|
||||||
|
local BUTTON_COLOR = {
|
||||||
|
[false] = { 0.4, 0.4, 0.4 },
|
||||||
|
[true] = { 0.9, 0.9, 0.9 }
|
||||||
|
}
|
||||||
|
local FONT_COLOR = {
|
||||||
|
[false] = { 1, 1, 1 },
|
||||||
|
[true] = { 0, 0, 0 }
|
||||||
|
}
|
||||||
|
local whitespace = " "
|
||||||
|
local updating
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
-- creating buttons and menus + initializing tables
|
-- creating buttons and menus + initializing tables
|
||||||
@ -71,8 +76,7 @@ end
|
|||||||
|
|
||||||
function initializeState()
|
function initializeState()
|
||||||
-- count tokens in the bag
|
-- count tokens in the bag
|
||||||
local chaosbag = getChaosBag()
|
local chaosbag = Global.call("findChaosBag")
|
||||||
if chaosbag == nil then return end
|
|
||||||
local tokens = {}
|
local tokens = {}
|
||||||
for _, v in ipairs(chaosbag.getObjects()) do
|
for _, v in ipairs(chaosbag.getObjects()) do
|
||||||
if v.name == "Bless" then
|
if v.name == "Bless" then
|
||||||
@ -101,23 +105,19 @@ function initializeState()
|
|||||||
end
|
end
|
||||||
|
|
||||||
function broadcastCount(token)
|
function broadcastCount(token)
|
||||||
local count = getTokenCount(token)
|
local count = formatTokenCount(token)
|
||||||
if count == "(0/0)" then return end
|
if count == "(0/0)" then return end
|
||||||
broadcastToAll(token .. " Tokens " .. count, "White")
|
broadcastToAll(token .. " Tokens " .. count, "White")
|
||||||
end
|
end
|
||||||
|
|
||||||
function printStatus(color)
|
function printStatus(color)
|
||||||
broadcastToColor("Curse Tokens " .. getTokenCount("Curse"), color, "White")
|
broadcastToColor("Curse Tokens " .. formatTokenCount("Curse"), color, "White")
|
||||||
broadcastToColor("Bless Tokens " .. getTokenCount("Bless"), color, "White")
|
broadcastToColor("Bless Tokens " .. formatTokenCount("Bless"), color, "White")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- context menu function 1
|
-- context menu function 1
|
||||||
function doRemove(color)
|
function doRemove(color)
|
||||||
local chaosbag = getChaosBag()
|
local chaosbag = Global.call("findChaosBag")
|
||||||
if chaosbag == nil then
|
|
||||||
broadcastToAll("Chaos bag not found!", "Red")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- remove tokens from chaos bag
|
-- remove tokens from chaos bag
|
||||||
local count = { Bless = 0, Curse = 0 }
|
local count = { Bless = 0, Curse = 0 }
|
||||||
@ -132,33 +132,16 @@ function doRemove(color)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
broadcastToColor("Removed " .. count["Bless"] .. " Bless and " ..
|
broadcastToColor("Removed " .. count.Bless .. " Bless and " ..
|
||||||
count["Curse"] .. " Curse tokens from the chaos bag.", color, "White")
|
count.Curse .. " Curse tokens from the chaos bag.", color, "White")
|
||||||
|
broadcastToColor("Removed " .. removeTakenTokens("Bless") .. " Bless and " ..
|
||||||
-- removing tokens that were 'taken'
|
removeTakenTokens("Curse") .. " Curse tokens from play.", color, "White")
|
||||||
local function removeType(type)
|
|
||||||
local count = 0
|
|
||||||
for _, guid in ipairs(tokensTaken[type]) do
|
|
||||||
local token = getObjectFromGUID(guid)
|
|
||||||
if token ~= nil then
|
|
||||||
token.destruct()
|
|
||||||
count = count + 1
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return count
|
|
||||||
end
|
|
||||||
|
|
||||||
broadcastToColor("Removed " .. removeType("Bless") .. " Bless and " ..
|
|
||||||
removeType("Curse") .. " Curse tokens from play.", color, "White")
|
|
||||||
|
|
||||||
doReset(color)
|
doReset(color)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- context menu function 2
|
-- context menu function 2
|
||||||
function doReset(color)
|
function doReset(color)
|
||||||
-- delete previously pulled out tokens by the token arranger
|
|
||||||
tokenArrangerApi.deleteCopiedTokens()
|
|
||||||
|
|
||||||
playerColor = color
|
playerColor = color
|
||||||
numInPlay = { Bless = 0, Curse = 0 }
|
numInPlay = { Bless = 0, Curse = 0 }
|
||||||
tokensTaken = { Bless = {}, Curse = {} }
|
tokensTaken = { Bless = {}, Curse = {} }
|
||||||
@ -166,6 +149,19 @@ function doReset(color)
|
|||||||
tokenArrangerApi.layout()
|
tokenArrangerApi.layout()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- removing tokens that were 'taken'
|
||||||
|
function removeTakenTokens(type)
|
||||||
|
local count = 0
|
||||||
|
for _, guid in ipairs(tokensTaken[type]) do
|
||||||
|
local token = getObjectFromGUID(guid)
|
||||||
|
if token ~= nil then
|
||||||
|
token.destruct()
|
||||||
|
count = count + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return count
|
||||||
|
end
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
-- click functions
|
-- click functions
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
@ -248,25 +244,35 @@ function callFunctions(token, isRightClick)
|
|||||||
if success ~= 0 then tokenArrangerApi.layout() end
|
if success ~= 0 then tokenArrangerApi.layout() end
|
||||||
end
|
end
|
||||||
|
|
||||||
function getChaosBag()
|
-- returns a formatted string with information about the provided token type (bless / curse)
|
||||||
local zone = getObjectFromGUID("83ef06")
|
function formatTokenCount(type)
|
||||||
if zone == nil then printToAll("Zone for chaosbag not found!", "Red") return end
|
if type == nil then type = mode end
|
||||||
|
return "(" .. (numInPlay[type] - #tokensTaken[type]) .. "/" .. #tokensTaken[type] .. ")"
|
||||||
|
end
|
||||||
|
|
||||||
local items = zone.getObjects()
|
-- called by cards that seal bless/curse tokens
|
||||||
local chaosbag = nil
|
---@param param Table This contains the type and guid of the sealed token
|
||||||
for _, v in ipairs(items) do
|
function sealedToken(param)
|
||||||
if v.getDescription() == "Chaos Bag" then
|
table.insert(tokensTaken[param.type], param.guid)
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
broadcastCount(param.type)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- called by cards that seal bless/curse tokens
|
||||||
|
---@param param Table This contains the type and guid of the released token
|
||||||
|
function releasedToken(param)
|
||||||
|
for i, v in ipairs(tokensTaken[param.type]) do
|
||||||
|
if v == param.guid then
|
||||||
|
table.remove(tokensTaken[param.type], i)
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if chaosbag == nil then printToColor("No chaos bag found", playerColor) end
|
if not updating then
|
||||||
return chaosbag
|
updating = true
|
||||||
end
|
Wait.frames(function()
|
||||||
|
broadcastCount(param.type)
|
||||||
function getTokenCount(type)
|
updating = false
|
||||||
if type == nil then type = mode end
|
end, 1)
|
||||||
return "(" .. (numInPlay[type] - #tokensTaken[type]) .. "/" .. #tokensTaken[type] .. ")"
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
@ -278,39 +284,13 @@ function addToken(type)
|
|||||||
printToColor("10 tokens already in play, not adding any.", playerColor)
|
printToColor("10 tokens already in play, not adding any.", playerColor)
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
return spawnToken(type)
|
numInPlay[type] = numInPlay[type] + 1
|
||||||
end
|
printToAll("Adding " .. type .. " token " .. formatTokenCount(type))
|
||||||
|
return Global.call("spawnChaosToken", type)
|
||||||
function spawnToken(type)
|
|
||||||
local chaosbag = getChaosBag()
|
|
||||||
if chaosbag == nil then
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
local pos = chaosbag.getPosition()
|
|
||||||
local obj = spawnObject({
|
|
||||||
type = 'Custom_Tile',
|
|
||||||
position = { pos.x, pos.y + 1, pos.z },
|
|
||||||
callback_function = function(obj)
|
|
||||||
obj.setName(type)
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
numInPlay[type] = numInPlay[type] + 1
|
|
||||||
printToAll("Adding " .. type .. " token " .. getTokenCount(type))
|
|
||||||
end
|
|
||||||
})
|
|
||||||
obj.setCustomObject({
|
|
||||||
type = 2,
|
|
||||||
image = IMAGE_URL[type],
|
|
||||||
thickness = 0.1,
|
|
||||||
})
|
|
||||||
obj.scale { 0.81, 1, 0.81 }
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function takeToken(type, remove)
|
function takeToken(type, remove)
|
||||||
local chaosbag = getChaosBag()
|
local chaosbag = Global.call("findChaosBag")
|
||||||
if chaosbag == nil then
|
|
||||||
broadcastToAll("Chaos bag not found!", "Red")
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
if not remove and not SEAL_CARD_MESSAGE then
|
if not remove and not SEAL_CARD_MESSAGE then
|
||||||
broadcastToColor("For sealing tokens on cards try right-clicking on the card for seal options.", playerColor)
|
broadcastToColor("For sealing tokens on cards try right-clicking on the card for seal options.", playerColor)
|
||||||
SEAL_CARD_MESSAGE = true
|
SEAL_CARD_MESSAGE = true
|
||||||
@ -334,11 +314,11 @@ function takeToken(type, remove)
|
|||||||
callback_function = function(obj)
|
callback_function = function(obj)
|
||||||
if remove then
|
if remove then
|
||||||
numInPlay[type] = numInPlay[type] - 1
|
numInPlay[type] = numInPlay[type] - 1
|
||||||
printToAll("Removing " .. type .. " token " .. getTokenCount(type))
|
printToAll("Removing " .. type .. " token " .. formatTokenCount(type))
|
||||||
obj.destruct()
|
obj.destruct()
|
||||||
else
|
else
|
||||||
table.insert(tokensTaken[type], obj.getGUID())
|
table.insert(tokensTaken[type], obj.getGUID())
|
||||||
printToAll("Taking " .. type .. " token " .. getTokenCount(type))
|
printToAll("Taking " .. type .. " token " .. formatTokenCount(type))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
@ -355,12 +335,12 @@ function returnToken(type)
|
|||||||
printToColor("Couldn't find token " .. guid .. ", not returning to bag", playerColor)
|
printToColor("Couldn't find token " .. guid .. ", not returning to bag", playerColor)
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
local chaosbag = getChaosBag()
|
local chaosbag = Global.call("findChaosBag")
|
||||||
if chaosbag == nil then
|
if chaosbag == nil then
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
chaosbag.putObject(token)
|
chaosbag.putObject(token)
|
||||||
printToAll("Returning " .. type .. " token " .. getTokenCount(type))
|
printToAll("Returning " .. type .. " token " .. formatTokenCount(type))
|
||||||
end
|
end
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
@ -400,7 +380,7 @@ function addMenuOptions(playerColor, hoveredObject)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function sealToken(type, playerColor, enemy)
|
function sealToken(type, playerColor, enemy)
|
||||||
local chaosbag = getChaosBag()
|
local chaosbag = Global.call("findChaosBag")
|
||||||
if chaosbag == nil then return end
|
if chaosbag == nil then return end
|
||||||
local pos = enemy.getPosition()
|
local pos = enemy.getPosition()
|
||||||
|
|
||||||
@ -414,7 +394,7 @@ function sealToken(type, playerColor, enemy)
|
|||||||
Wait.frames(function()
|
Wait.frames(function()
|
||||||
table.insert(sealedTokens[enemy.getGUID()], obj)
|
table.insert(sealedTokens[enemy.getGUID()], obj)
|
||||||
table.insert(tokensTaken[type], obj.getGUID())
|
table.insert(tokensTaken[type], obj.getGUID())
|
||||||
printToColor("Sealing " .. type .. " token " .. getTokenCount(type), playerColor)
|
printToColor("Sealing " .. type .. " token " .. formatTokenCount(type), playerColor)
|
||||||
end, 1)
|
end, 1)
|
||||||
end
|
end
|
||||||
})
|
})
|
||||||
@ -425,7 +405,7 @@ function sealToken(type, playerColor, enemy)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function releaseToken(type, playerColor, enemy)
|
function releaseToken(type, playerColor, enemy)
|
||||||
local chaosbag = getChaosBag()
|
local chaosbag = Global.call("findChaosBag")
|
||||||
if chaosbag == nil then return end
|
if chaosbag == nil then return end
|
||||||
local tokens = sealedTokens[enemy.getGUID()]
|
local tokens = sealedTokens[enemy.getGUID()]
|
||||||
if tokens == nil or #tokens == 0 then return end
|
if tokens == nil or #tokens == 0 then return end
|
||||||
@ -438,7 +418,7 @@ function releaseToken(type, playerColor, enemy)
|
|||||||
if v == guid then
|
if v == guid then
|
||||||
table.remove(tokensTaken[type], j)
|
table.remove(tokensTaken[type], j)
|
||||||
table.remove(tokens, i)
|
table.remove(tokens, i)
|
||||||
printToColor("Releasing " .. type .. " token" .. getTokenCount(type), playerColor)
|
printToColor("Releasing " .. type .. " token" .. formatTokenCount(type), playerColor)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
24
src/chaosbag/BlessCurseManagerApi.ttslua
Normal file
24
src/chaosbag/BlessCurseManagerApi.ttslua
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
do
|
||||||
|
local BlessCurseManagerApi = {}
|
||||||
|
local MANAGER_GUID = "5933fb"
|
||||||
|
|
||||||
|
-- removes all taken tokens and resets the counts
|
||||||
|
BlessCurseManagerApi.removeTakenTokensAndReset = function()
|
||||||
|
local BlessCurseManager = getObjectFromGUID(MANAGER_GUID)
|
||||||
|
Wait.time(function() BlessCurseManager.call("removeType", "Bless") end, 0.05)
|
||||||
|
Wait.time(function() BlessCurseManager.call("removeType", "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)
|
||||||
|
BlessCurseManagerApi.sealedToken = function(type, guid)
|
||||||
|
getObjectFromGUID(MANAGER_GUID).call("sealedToken", { type = type, guid = guid })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- updates the internal count (called by cards that seal bless/curse tokens)
|
||||||
|
BlessCurseManagerApi.releasedToken = function(type, guid)
|
||||||
|
getObjectFromGUID(MANAGER_GUID).call("releasedToken", { type = type, guid = guid })
|
||||||
|
end
|
||||||
|
|
||||||
|
return BlessCurseManagerApi
|
||||||
|
end
|
@ -1,9 +0,0 @@
|
|||||||
-- automatically add correct names to tokens that enter the chaos bag
|
|
||||||
function filterObjectEnter(obj)
|
|
||||||
local props = obj.getCustomObject()
|
|
||||||
if props ~= nil and props.image ~= nil then
|
|
||||||
obj.setName(Global.call("getTokenName", { url = props.image }))
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
@ -34,6 +34,9 @@ local hideTitleSplashWaitFunctionId = nil
|
|||||||
local playmatApi = require("playermat/PlaymatApi")
|
local playmatApi = require("playermat/PlaymatApi")
|
||||||
local tokenManager = require("core/token/TokenManager")
|
local tokenManager = require("core/token/TokenManager")
|
||||||
local playAreaAPI = require("core/PlayAreaApi")
|
local playAreaAPI = require("core/PlayAreaApi")
|
||||||
|
local mythosAreaApi = require("core/MythosAreaApi")
|
||||||
|
local tokenArrangerApi = require("accessories/TokenArrangerApi")
|
||||||
|
local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi")
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
-- data for tokens
|
-- data for tokens
|
||||||
@ -47,87 +50,46 @@ TOKEN_DATA = {
|
|||||||
clue = {image = "http://cloud-3.steamusercontent.com/ugc/1758068501357164917/1D06F1DC4D6888B6F57124BD2AFE20D0B0DA15A8/", scale = {0.15, 0.15, 0.15}}
|
clue = {image = "http://cloud-3.steamusercontent.com/ugc/1758068501357164917/1D06F1DC4D6888B6F57124BD2AFE20D0B0DA15A8/", scale = {0.15, 0.15, 0.15}}
|
||||||
}
|
}
|
||||||
|
|
||||||
IMAGE_TOKEN_MAP = {
|
ID_URL_MAP = {
|
||||||
["https://i.imgur.com/nEmqjmj.png"] = "Elder Sign",
|
['blue'] = {name = "Elder Sign", url = 'https://i.imgur.com/nEmqjmj.png'},
|
||||||
["https://i.imgur.com/uIx8jbY.png"] = "+1",
|
['p1'] = {name = "+1", url = 'https://i.imgur.com/uIx8jbY.png'},
|
||||||
["https://i.imgur.com/btEtVfd.png"] = "0",
|
['0'] = {name = "0", url = 'https://i.imgur.com/btEtVfd.png'},
|
||||||
["https://i.imgur.com/w3XbrCC.png"] = "-1",
|
['m1'] = {name = "-1", url = 'https://i.imgur.com/w3XbrCC.png'},
|
||||||
["https://i.imgur.com/bfTg2hb.png"] = "-2",
|
['m2'] = {name = "-2", url = 'https://i.imgur.com/bfTg2hb.png'},
|
||||||
["https://i.imgur.com/yfs8gHq.png"] = "-3",
|
['m3'] = {name = "-3", url = 'https://i.imgur.com/yfs8gHq.png'},
|
||||||
["https://i.imgur.com/qrgGQRD.png"] = "-4",
|
['m4'] = {name = "-4", url = 'https://i.imgur.com/qrgGQRD.png'},
|
||||||
["https://i.imgur.com/3Ym1IeG.png"] = "-5",
|
['m5'] = {name = "-5", url = 'https://i.imgur.com/3Ym1IeG.png'},
|
||||||
["https://i.imgur.com/c9qdSzS.png"] = "-6",
|
['m6'] = {name = "-6", url = 'https://i.imgur.com/c9qdSzS.png'},
|
||||||
["https://i.imgur.com/4WRD42n.png"] = "-7",
|
['m7'] = {name = "-7", url = 'https://i.imgur.com/4WRD42n.png'},
|
||||||
["https://i.imgur.com/9t3rPTQ.png"] = "-8",
|
['m8'] = {name = "-8", url = 'https://i.imgur.com/9t3rPTQ.png'},
|
||||||
["https://i.imgur.com/stbBxtx.png"] = "Skull",
|
['skull'] = {name = "Skull", url = 'https://i.imgur.com/stbBxtx.png'},
|
||||||
["https://i.imgur.com/VzhJJaH.png"] = "Cultist",
|
['cultist'] = {name = "Cultist", url = 'https://i.imgur.com/VzhJJaH.png'},
|
||||||
["https://i.imgur.com/1plY463.png"] = "Tablet",
|
['tablet'] = {name = "Tablet", url = 'https://i.imgur.com/1plY463.png'},
|
||||||
["https://i.imgur.com/ttnspKt.png"] = "Elder Thing",
|
['elder'] = {name = "Elder Thing", url = 'https://i.imgur.com/ttnspKt.png'},
|
||||||
["https://i.imgur.com/lns4fhz.png"] = "Auto-fail",
|
['red'] = {name = "Auto-fail", url = 'https://i.imgur.com/lns4fhz.png'},
|
||||||
["http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/"] = "Bless",
|
['bless'] = {name = "Bless", url = 'http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/'},
|
||||||
["http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/"] = "Curse",
|
['curse'] = {name = "Curse", url = 'http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/'},
|
||||||
["http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/"] = "Frost"
|
['frost'] = {name = "Frost", url = 'http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/'}
|
||||||
}
|
}
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
-- data for chaos token stat tracker
|
-- data for chaos token stat tracker
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
local maxSquid = 0
|
local MAT_GUID_TO_COLOR = {
|
||||||
|
["Overall"] = "Overall",
|
||||||
MAT_GUID_TO_COLOUR = {
|
["8b081b"] = "White",
|
||||||
["8b081b"] = "White",
|
["bd0ff4"] = "Orange",
|
||||||
["bd0ff4"] = "Orange",
|
["383d8b"] = "Green",
|
||||||
["383d8b"] = "Green",
|
["0840d5"] = "Red"
|
||||||
["0840d5"] = "Red"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
local personalStats = {
|
local tokenDrawingStats = {
|
||||||
["8b081b"] = {},
|
["Overall"] = {},
|
||||||
["bd0ff4"] = {},
|
["8b081b"] = {},
|
||||||
["383d8b"] = {},
|
["bd0ff4"] = {},
|
||||||
["0840d5"] = {}
|
["383d8b"] = {},
|
||||||
}
|
["0840d5"] = {}
|
||||||
|
|
||||||
local overallStats = {
|
|
||||||
-- cultist
|
|
||||||
["https://i.imgur.com/VzhJJaH.png"] = 0,
|
|
||||||
-- skull
|
|
||||||
["https://i.imgur.com/stbBxtx.png"] = 0,
|
|
||||||
-- tablet
|
|
||||||
["https://i.imgur.com/1plY463.png"] = 0,
|
|
||||||
-- curse
|
|
||||||
["http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/"] = 0,
|
|
||||||
-- tentacle
|
|
||||||
["https://i.imgur.com/lns4fhz.png"] = 0,
|
|
||||||
-- minus eight
|
|
||||||
["https://i.imgur.com/9t3rPTQ.png"] = 0,
|
|
||||||
-- minus seven
|
|
||||||
["https://i.imgur.com/4WRD42n.png"] = 0,
|
|
||||||
-- minus six
|
|
||||||
["https://i.imgur.com/c9qdSzS.png"] = 0,
|
|
||||||
-- minus five
|
|
||||||
["https://i.imgur.com/3Ym1IeG.png"] = 0,
|
|
||||||
-- minus four
|
|
||||||
["https://i.imgur.com/qrgGQRD.png"] = 0,
|
|
||||||
-- minus three
|
|
||||||
["https://i.imgur.com/yfs8gHq.png"] = 0,
|
|
||||||
-- minus two
|
|
||||||
["https://i.imgur.com/bfTg2hb.png"] = 0,
|
|
||||||
-- minus one
|
|
||||||
["https://i.imgur.com/w3XbrCC.png"] = 0,
|
|
||||||
-- zero
|
|
||||||
["https://i.imgur.com/btEtVfd.png"] = 0,
|
|
||||||
-- plus one
|
|
||||||
["https://i.imgur.com/uIx8jbY.png"] = 0,
|
|
||||||
-- elder thing
|
|
||||||
["https://i.imgur.com/ttnspKt.png"] = 0,
|
|
||||||
-- bless
|
|
||||||
["http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/"] = 0,
|
|
||||||
-- elder sign
|
|
||||||
["https://i.imgur.com/nEmqjmj.png"] = 0,
|
|
||||||
-- frost
|
|
||||||
["http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/"] = 0,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
@ -270,13 +232,24 @@ end
|
|||||||
-- chaos token drawing
|
-- chaos token drawing
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
-- checks scripting zone for chaos bag
|
-- checks scripting zone for chaos bag (also called by a lot of objects!)
|
||||||
function findChaosBag()
|
function findChaosBag()
|
||||||
for _, item in ipairs(getObjectFromGUID("83ef06").getObjects()) do
|
local chaosbag_zone = getObjectFromGUID("83ef06")
|
||||||
|
|
||||||
|
-- error handling: scripting zone not found
|
||||||
|
if chaosbag_zone == nil then
|
||||||
|
printToAll("Zone for chaos bag detection couldn't be found.", "Red")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, item in ipairs(chaosbag_zone.getObjects()) do
|
||||||
if item.getDescription() == "Chaos Bag" then
|
if item.getDescription() == "Chaos Bag" then
|
||||||
return item
|
return item
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- error handling: chaos bag not found
|
||||||
|
printToAll("Chaos bag couldn't be found.", "Red")
|
||||||
end
|
end
|
||||||
|
|
||||||
function returnChaosTokens()
|
function returnChaosTokens()
|
||||||
@ -290,22 +263,20 @@ end
|
|||||||
-- 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 Boolean. True if the bag is manipulated, false if it should be blocked.
|
---@return Boolean. True if the bag is manipulated, false if it should be blocked.
|
||||||
function canTouchChaosTokens()
|
function canTouchChaosTokens()
|
||||||
for color, searching in pairs(bagSearchers) do
|
for color, searching in pairs(bagSearchers) do
|
||||||
if searching then
|
if searching then
|
||||||
broadcastToAll("Someone is searching the chaos bag, can't touch the tokens", "Red")
|
broadcastToAll("Someone is searching the chaos bag, can't touch the tokens.", "Red")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
function drawChaostoken(params)
|
-- called by playermats (by the "Draw chaos token" button)
|
||||||
if not canTouchChaosTokens() then
|
function drawChaosToken(params)
|
||||||
return
|
if not canTouchChaosTokens() then return end
|
||||||
end
|
|
||||||
|
|
||||||
local mat = params[1]
|
local mat = params[1]
|
||||||
local tokenOffset = params[2]
|
local tokenOffset = params[2]
|
||||||
@ -320,6 +291,7 @@ function drawChaostoken(params)
|
|||||||
end
|
end
|
||||||
|
|
||||||
chaosTokensLastMat = mat
|
chaosTokensLastMat = mat
|
||||||
|
|
||||||
-- if we have left clicked and have no tokens OR if we have right clicked
|
-- if we have left clicked and have no tokens OR if we have right clicked
|
||||||
if isRightClick or #chaosTokens == 0 then
|
if isRightClick or #chaosTokens == 0 then
|
||||||
if #chaosbag.getObjects() == 0 then return end
|
if #chaosbag.getObjects() == 0 then return end
|
||||||
@ -328,11 +300,18 @@ function drawChaostoken(params)
|
|||||||
-- add the token to the list, compute new position based on list length
|
-- add the token to the list, compute new position based on list length
|
||||||
tokenOffset[1] = tokenOffset[1] + (0.17 * #chaosTokens)
|
tokenOffset[1] = tokenOffset[1] + (0.17 * #chaosTokens)
|
||||||
local token = chaosbag.takeObject({
|
local token = chaosbag.takeObject({
|
||||||
index = 0,
|
|
||||||
position = mat.positionToWorld(tokenOffset),
|
position = mat.positionToWorld(tokenOffset),
|
||||||
rotation = mat.getRotation(),
|
rotation = mat.getRotation()
|
||||||
callback_function = function(obj) trackChaosToken(obj, mat.getGUID()) end
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- get data for token description
|
||||||
|
local name = token.getName()
|
||||||
|
local tokenData = mythosAreaApi.returnTokenData().tokenData or {}
|
||||||
|
local specificData = tokenData[name] or {}
|
||||||
|
token.setDescription(specificData.description or "")
|
||||||
|
|
||||||
|
-- track the chaos token (for stat tracker and future returning)
|
||||||
|
trackChaosToken(name, mat.getGUID())
|
||||||
chaosTokens[#chaosTokens + 1] = token
|
chaosTokens[#chaosTokens + 1] = token
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
@ -355,64 +334,50 @@ end
|
|||||||
-- chaos token stat tracker
|
-- chaos token stat tracker
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
function trackChaosToken(token, matGUID)
|
function trackChaosToken(tokenName, matGUID)
|
||||||
local image = token.getCustomObject().image
|
tokenDrawingStats["Overall"][tokenName] = (tokenDrawingStats["Overall"][tokenName] or 0) + 1
|
||||||
overallStats[image] = (overallStats[image] or 0) + 1
|
tokenDrawingStats[matGUID][tokenName] = (tokenDrawingStats[matGUID][tokenName] or 0) + 1
|
||||||
personalStats[matGUID][image] = (personalStats[matGUID][image] or 0) + 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Left-click: print stats, Right-click: reset stats
|
||||||
function handleStatTrackerClick(_, _, isRightClick)
|
function handleStatTrackerClick(_, _, isRightClick)
|
||||||
if isRightClick then
|
if isRightClick then
|
||||||
resetChaosTokenStats()
|
for key, _ in pairs(tokenDrawingStats) do
|
||||||
|
tokenDrawingStats[key] = {}
|
||||||
|
end
|
||||||
else
|
else
|
||||||
printChaosTokenStats()
|
local squidKing = "Nobody"
|
||||||
end
|
local maxSquid = 0
|
||||||
end
|
local playerColor, playerName
|
||||||
|
|
||||||
|
for key, personalStats in pairs(tokenDrawingStats) do
|
||||||
|
if personalStats ~= {} then
|
||||||
|
if key == "Overall" then
|
||||||
|
playerColor = "White"
|
||||||
|
playerName = "Overall"
|
||||||
|
else
|
||||||
|
playerColor = playmatApi.getPlayerColor(MAT_GUID_TO_COLOR[key])
|
||||||
|
playerName = Player[playerColor].steam_name or playerColor
|
||||||
|
|
||||||
function resetChaosTokenStats()
|
local playerSquidCount = personalStats["Auto-fail"] or 0
|
||||||
for key, _ in pairs(overallStats) do
|
if playerSquidCount > maxSquid then
|
||||||
overallStats[key] = 0
|
squidKing = playerName
|
||||||
end
|
maxSquid = playerSquidCount
|
||||||
for playerKey, _ in pairs(personalStats) do
|
end
|
||||||
for key, value in pairs(overallStats) do
|
end
|
||||||
personalStats[playerKey][key] = value
|
|
||||||
end
|
printToAll("------------------------------")
|
||||||
end
|
printToAll(playerName .. " Stats", playerColor)
|
||||||
end
|
|
||||||
|
for tokenName, value in pairs(personalStats) do
|
||||||
function printChaosTokenStats()
|
if value then
|
||||||
local squidKing = "Nobody"
|
printToAll(tokenName .. ': ' .. tostring(value))
|
||||||
printToAll("")
|
end
|
||||||
printToAll("Overall Stats")
|
end
|
||||||
printToAll("------------------------------")
|
end
|
||||||
printNonZeroTokenPairs(overallStats)
|
|
||||||
printToAll("")
|
|
||||||
printToAll("Individual Stats")
|
|
||||||
printToAll("------------------------------")
|
|
||||||
for matGUID, _ in pairs(personalStats) do
|
|
||||||
local playerColour = MAT_GUID_TO_COLOUR[matGUID]
|
|
||||||
local playerSquidCount = personalStats[matGUID]["https://i.imgur.com/lns4fhz.png"] or 0
|
|
||||||
local playerName = playerColour
|
|
||||||
if Player[playerColour].seated then
|
|
||||||
playerName = Player[playerColour].steam_name
|
|
||||||
end
|
|
||||||
|
|
||||||
printToAll(playerName .. " Stats", playerColour)
|
|
||||||
printNonZeroTokenPairs(personalStats[matGUID])
|
|
||||||
|
|
||||||
if playerSquidCount > maxSquid then
|
|
||||||
squidKing = playerName
|
|
||||||
maxSquid = playerSquidCount
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToAll(squidKing .. " is an auto-fail magnet.", {255, 0, 0})
|
|
||||||
end
|
|
||||||
|
|
||||||
function printNonZeroTokenPairs(theTable)
|
|
||||||
for key, value in pairs(theTable) do
|
|
||||||
if value ~= 0 then
|
|
||||||
printToAll(IMAGE_TOKEN_MAP[key] .. ': ' .. tostring(value))
|
|
||||||
end
|
end
|
||||||
|
printToAll("------------------------------")
|
||||||
|
printToAll(squidKing .. " is an auto-fail magnet.", {255, 0, 0})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -473,63 +438,44 @@ end
|
|||||||
-- called for adding chaos tokens
|
-- called for adding chaos tokens
|
||||||
---@param object object Usually "self"
|
---@param object object Usually "self"
|
||||||
---@param key string Name of the scenario
|
---@param key string Name of the scenario
|
||||||
---@param mode string diffculty (e.g. "hard" or "expert")
|
---@param mode string difficulty (e.g. "hard" or "expert")
|
||||||
function fillContainer(args)
|
function fillContainer(args)
|
||||||
chaosbag = findChaosBag()
|
local data = getDataValue('modeData', args.key)
|
||||||
|
if data == nil then return end
|
||||||
|
|
||||||
if chaosbag ~= nil then
|
local value = data[args.mode]
|
||||||
local data = getDataValue('modeData', args.key)
|
if value == nil or value.token == nil then return end
|
||||||
if data == nil then return end
|
|
||||||
|
|
||||||
local value = data[args.mode]
|
local tokenList = {}
|
||||||
if value == nil or value.token == nil then return end
|
|
||||||
|
|
||||||
local pos = chaosbag.getPosition()
|
for _, tokenId in ipairs(value.token) do
|
||||||
if args.object ~= nil then
|
table.insert(tokenList, tokenId)
|
||||||
pos = args.object.getPosition()
|
end
|
||||||
|
|
||||||
|
if value.append ~= nil then
|
||||||
|
for _, tokenId in ipairs(value.append) do
|
||||||
|
table.insert(tokenList, tokenId)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- empty the chaos bag
|
-- randomly choose tokens for specific Carcosa scenarios in standalone
|
||||||
for _, item in ipairs(chaosbag.getObjects()) do
|
if value.random then
|
||||||
destroyObject(chaosbag.takeObject({}))
|
local n = #value.random
|
||||||
end
|
if n > 0 then
|
||||||
|
for _, tokenId in ipairs(value.random[math.random(1, n)]) do
|
||||||
for _, token in ipairs(value.token) do
|
table.insert(tokenList, tokenId)
|
||||||
local obj = spawnChaosToken(token, pos)
|
|
||||||
if obj ~= nil then
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
if value.append ~= nil then
|
setChaosBagState(tokenList)
|
||||||
for _, token in ipairs(value.append) do
|
|
||||||
local obj = spawnChaosToken(token, pos)
|
|
||||||
if obj ~= nil then
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- randomly choose tokens for specific Carcosa scenarios in standalone
|
if value.message then
|
||||||
if value.random then
|
broadcastToAll(value.message)
|
||||||
local n = #value.random
|
end
|
||||||
if n > 0 then
|
|
||||||
for _, token in ipairs(value.random[math.random(1, n)]) do
|
|
||||||
local obj = spawnChaosToken(token, pos)
|
|
||||||
if obj ~= nil then
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if value.message then
|
if value.warning then
|
||||||
broadcastToAll(value.message)
|
broadcastToAll(value.warning, { 1, 0.5, 0.5 })
|
||||||
end
|
|
||||||
|
|
||||||
if value.warning then
|
|
||||||
broadcastToAll(value.warning, { 1, 0.5, 0.5 })
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -554,52 +500,112 @@ function getDataValue(storage, key)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function spawnChaosToken(id, pos)
|
-- respawns the chaos bag with a new state of tokens
|
||||||
local url = getChaosTokenImageURL(id)
|
---@param tokenList Table List of chaos token ids
|
||||||
if url ~= '' then
|
function setChaosBagState(tokenList)
|
||||||
local obj = spawnObject({
|
if not canTouchChaosTokens() then return end
|
||||||
|
|
||||||
|
local chaosbag = findChaosBag()
|
||||||
|
local chaosbagData = chaosbag.getData()
|
||||||
|
local reserveData = getObjectFromGUID("106418").getData()
|
||||||
|
local tokenCache = {}
|
||||||
|
local containedObjects = {}
|
||||||
|
|
||||||
|
-- create a temporary copy of the data for each chaos token
|
||||||
|
for _, objData in ipairs(reserveData.ContainedObjects) do
|
||||||
|
tokenCache[objData.Nickname] = objData
|
||||||
|
end
|
||||||
|
|
||||||
|
-- iterate over tokenlist and insert specified tokens into new table
|
||||||
|
for _, tokenId in ipairs(tokenList) do
|
||||||
|
local tokenName = ID_URL_MAP[tokenId].name
|
||||||
|
table.insert(containedObjects, tokenCache[tokenName])
|
||||||
|
end
|
||||||
|
|
||||||
|
-- overwrite chaos bag content and respawn it
|
||||||
|
chaosbagData.ContainedObjects = containedObjects
|
||||||
|
chaosbag.destruct()
|
||||||
|
spawnObjectData({data = chaosbagData})
|
||||||
|
|
||||||
|
-- remove tokens that are still in play
|
||||||
|
for _, token in pairs(chaosTokens) do
|
||||||
|
if token ~= nil then token.destruct() end
|
||||||
|
end
|
||||||
|
chaosTokens = {}
|
||||||
|
chaosTokensLastMat = nil
|
||||||
|
|
||||||
|
-- reset bless / curse manager
|
||||||
|
blessCurseManagerApi.removeTakenTokensAndReset()
|
||||||
|
|
||||||
|
printToAll("Chaos bag set to chosen difficulty.", "Green")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- spawns the specified chaos token and puts it into the chaos bag
|
||||||
|
---@param id String ID of the chaos token
|
||||||
|
function spawnChaosToken(id)
|
||||||
|
if not canTouchChaosTokens() then return end
|
||||||
|
|
||||||
|
id = id:lower()
|
||||||
|
local chaosbag = findChaosBag()
|
||||||
|
local url = ID_URL_MAP[id].url or ""
|
||||||
|
|
||||||
|
if url ~= "" then
|
||||||
|
return spawnObject({
|
||||||
type = 'Custom_Tile',
|
type = 'Custom_Tile',
|
||||||
position = {pos.x, pos.y + 3, pos.z},
|
position = { 0.49, 3, 0 },
|
||||||
rotation = {0, 260, 0}
|
scale = { 0.81, 1.0, 0.81 },
|
||||||
})
|
rotation = {0, 270, 0},
|
||||||
obj.setCustomObject({
|
callback_function = function(obj)
|
||||||
|
obj.setName(ID_URL_MAP[id].name)
|
||||||
|
chaosbag.putObject(obj)
|
||||||
|
tokenArrangerApi.layout()
|
||||||
|
end
|
||||||
|
}).setCustomObject({
|
||||||
type = 2,
|
type = 2,
|
||||||
image = url,
|
image = url,
|
||||||
thickness = 0.1
|
thickness = 0.1
|
||||||
})
|
})
|
||||||
obj.scale {0.81, 1, 0.81}
|
|
||||||
obj.setName(getTokenName({ url=url }))
|
|
||||||
return obj
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- chaos bag needs this for renaming chaos tokens
|
-- removes the specified chaos token from the chaos bag
|
||||||
function getTokenName(params)
|
---@param id String ID of the chaos token
|
||||||
local name = IMAGE_TOKEN_MAP[params.url]
|
function removeChaosToken(id)
|
||||||
if name == nil then name = "" end
|
if not canTouchChaosTokens() then return end
|
||||||
return name
|
|
||||||
|
local tokens = {}
|
||||||
|
local chaosbag = findChaosBag()
|
||||||
|
local name = ID_URL_MAP[id].name
|
||||||
|
|
||||||
|
for _, v in ipairs(chaosbag.getObjects()) do
|
||||||
|
if v.name == name then table.insert(tokens, v.guid) end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- error handling: no matching token found
|
||||||
|
if #tokens == 0 then
|
||||||
|
printToAll("No " .. name .. " tokens in the chaos bag.", "Yellow")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
chaosbag.takeObject({
|
||||||
|
guid = tokens[1],
|
||||||
|
smooth = false,
|
||||||
|
callback_function = function(obj)
|
||||||
|
obj.destruct()
|
||||||
|
tokenArrangerApi.layout()
|
||||||
|
end
|
||||||
|
})
|
||||||
|
printToAll("Removing " .. name .. " token (in bag: " .. #tokens - 1 .. ")", "White")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- returns the image url for a chaos token (identified by the "id")
|
-- empty the chaos bag
|
||||||
function getChaosTokenImageURL(id)
|
function emptyChaosBag()
|
||||||
if id == 'p1' then return 'https://i.imgur.com/uIx8jbY.png' end
|
if not canTouchChaosTokens() then return end
|
||||||
if id == '0' then return 'https://i.imgur.com/btEtVfd.png' end
|
|
||||||
if id == 'm1' then return 'https://i.imgur.com/w3XbrCC.png' end
|
local chaosbag = findChaosBag()
|
||||||
if id == 'm2' then return 'https://i.imgur.com/bfTg2hb.png' end
|
for _, object in ipairs(chaosbag.getObjects()) do
|
||||||
if id == 'm3' then return 'https://i.imgur.com/yfs8gHq.png' end
|
chaosbag.takeObject({callback_function = function(item) item.destruct() end})
|
||||||
if id == 'm4' then return 'https://i.imgur.com/qrgGQRD.png' end
|
end
|
||||||
if id == 'm5' then return 'https://i.imgur.com/3Ym1IeG.png' end
|
|
||||||
if id == 'm6' then return 'https://i.imgur.com/c9qdSzS.png' end
|
|
||||||
if id == 'm7' then return 'https://i.imgur.com/4WRD42n.png' end
|
|
||||||
if id == 'm8' then return 'https://i.imgur.com/9t3rPTQ.png' end
|
|
||||||
if id == 'skull' then return 'https://i.imgur.com/stbBxtx.png' end
|
|
||||||
if id == 'cultist' then return 'https://i.imgur.com/VzhJJaH.png' end
|
|
||||||
if id == 'tablet' then return 'https://i.imgur.com/1plY463.png' end
|
|
||||||
if id == 'elder' then return 'https://i.imgur.com/ttnspKt.png' end
|
|
||||||
if id == 'red' then return 'https://i.imgur.com/lns4fhz.png' end
|
|
||||||
if id == 'blue' then return 'https://i.imgur.com/nEmqjmj.png' end
|
|
||||||
if id == 'frost' then return 'http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/' end
|
|
||||||
return ''
|
|
||||||
end
|
end
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
@ -62,7 +62,10 @@ function onCollisionEnter(collisionInfo)
|
|||||||
-- trigger update if a change was detected and push new data
|
-- trigger update if a change was detected and push new data
|
||||||
if updateNeeded then
|
if updateNeeded then
|
||||||
local metadata = JSON.decode(object.getGMNotes()) or {}
|
local metadata = JSON.decode(object.getGMNotes()) or {}
|
||||||
if not metadata["tokens"] then return end
|
if not metadata["tokens"] then
|
||||||
|
tokenData = {}
|
||||||
|
return
|
||||||
|
end
|
||||||
tokenData = metadata["tokens"][(useFrontData and "front" or "back")]
|
tokenData = metadata["tokens"][(useFrontData and "front" or "back")]
|
||||||
fireTokenDataChangedEvent()
|
fireTokenDataChangedEvent()
|
||||||
end
|
end
|
||||||
|
219
src/playercards/CardsThatSealTokens.ttslua
Normal file
219
src/playercards/CardsThatSealTokens.ttslua
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
--[[ Library for cards that seal tokens
|
||||||
|
This file is used to add sealing option to cards' context menu.
|
||||||
|
Valid options (set before requiring this file):
|
||||||
|
|
||||||
|
UPDATE_ON_HOVER --@type: boolean
|
||||||
|
- 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
|
||||||
|
- example usage: "Unrelenting" (to only display valid tokens)
|
||||||
|
|
||||||
|
SHOW_SINGLE_RELEASE --@type: boolean
|
||||||
|
- enables an entry in the context menu
|
||||||
|
- this entry allows releasing a single token
|
||||||
|
- example usage: "Holy Spear" (to keep the other tokens and just release one)
|
||||||
|
|
||||||
|
SHOW_MULTI_RELEASE --@type: number (amount of tokens to release at once)
|
||||||
|
- enables an entry in the context menu
|
||||||
|
- this enty allows releasing of multiple tokens at once
|
||||||
|
- example usage: "Nephthys" (to release 3 bless tokens at once)
|
||||||
|
|
||||||
|
SHOW_MULTI_SEAL --@type: number (amount of tokens to seal at once)
|
||||||
|
- enables an entry in the context menu
|
||||||
|
- this entry allows sealing of multiple tokens at once
|
||||||
|
- example usage: "Holy Spear" (to seal two bless tokens at once)
|
||||||
|
|
||||||
|
VALID_TOKENS --@type: table ([tokenName] = true)
|
||||||
|
- this table defines which tokens should be abled to be sealed
|
||||||
|
- needs to be defined for each card -> even if empty
|
||||||
|
- example usage: "The Chthonian Stone"
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Skull"] = true,
|
||||||
|
> ["Cultist"] = true,
|
||||||
|
> ["Tablet"] = true,
|
||||||
|
> ["Elder Thing"] = true,
|
||||||
|
> }
|
||||||
|
|
||||||
|
INVALID_TOKENS --@type: table ([tokenName] = true)
|
||||||
|
- this table defines which tokens are invalid for sealing
|
||||||
|
- only needs to be defined if needed
|
||||||
|
- usually combined with empty "VALID_TOKENS" table
|
||||||
|
- example usage: "Protective Incantation" (not allowed to seal Auto-fail)
|
||||||
|
|
||||||
|
----------------------------------------------------------
|
||||||
|
Example 1: Crystalline Elder Sign
|
||||||
|
This card can only seal the "+1" or "Elder Sign" token,
|
||||||
|
it does not need specific options for multi-sealing or releasing.
|
||||||
|
Thus it should be implemented like this:
|
||||||
|
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["+1"] = true,
|
||||||
|
> ["Elder Sign"] = true
|
||||||
|
> }
|
||||||
|
> require ("playercards/CardsThatSealTokens") -- includes a space after "require" to not executing bundling
|
||||||
|
----------------------------------------------------------
|
||||||
|
Example 2: Holy Spear
|
||||||
|
This card features the following abilities (just listing the relevant parts):
|
||||||
|
- releasing a single bless token
|
||||||
|
- sealing two bless tokens
|
||||||
|
Thus it should be implemented like this:
|
||||||
|
|
||||||
|
> VALID_TOKENS = {
|
||||||
|
> ["Bless"] = true
|
||||||
|
> }
|
||||||
|
> SHOW_SINGLE_RELEASE = true
|
||||||
|
> SHOW_MULTI_SEAL = 2
|
||||||
|
> require ("playercards/CardsThatSealTokens") -- includes a space after "require" to not executing bundling
|
||||||
|
----------------------------------------------------------]]
|
||||||
|
|
||||||
|
local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi")
|
||||||
|
local tokenArrangerApi = require("accessories/TokenArrangerApi")
|
||||||
|
local sealedTokens = {}
|
||||||
|
local ID_URL_MAP = {}
|
||||||
|
local tokensInBag = {}
|
||||||
|
|
||||||
|
function onSave() return JSON.encode(sealedTokens) end
|
||||||
|
|
||||||
|
function onLoad(savedData)
|
||||||
|
sealedTokens = JSON.decode(savedData) or {}
|
||||||
|
ID_URL_MAP = Global.getTable("ID_URL_MAP")
|
||||||
|
generateContextMenu()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- builds the context menu
|
||||||
|
function generateContextMenu()
|
||||||
|
-- conditional single or multi release options
|
||||||
|
if SHOW_SINGLE_RELEASE then
|
||||||
|
self.addContextMenuItem("Release token", releaseOneToken)
|
||||||
|
elseif SHOW_MULTI_RELEASE then
|
||||||
|
self.addContextMenuItem("Release " .. SHOW_MULTI_RELEASE .. " token(s)", releaseMultipleTokens)
|
||||||
|
else
|
||||||
|
self.addContextMenuItem("Release token(s)", releaseAllTokens)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- main context menu options to seal tokens
|
||||||
|
for _, map in pairs(ID_URL_MAP) do
|
||||||
|
if (VALID_TOKENS[map.name] ~= nil) or (UPDATE_ON_HOVER and tokensInBag[map.name] and not INVALID_TOKENS[map.name]) then
|
||||||
|
if not SHOW_MULTI_SEAL then
|
||||||
|
self.addContextMenuItem("Seal " .. map.name, function(playerColor)
|
||||||
|
sealToken(map.name, playerColor)
|
||||||
|
end)
|
||||||
|
else
|
||||||
|
self.addContextMenuItem("Seal " .. SHOW_MULTI_SEAL .. " " .. map.name, function(playerColor)
|
||||||
|
readBag()
|
||||||
|
local allowed = true
|
||||||
|
local notFound
|
||||||
|
|
||||||
|
for name, _ in pairs(VALID_TOKENS) do
|
||||||
|
if (tokensInBag[name] or 0) < SHOW_MULTI_SEAL then
|
||||||
|
allowed = false
|
||||||
|
notFound = name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if allowed then
|
||||||
|
for i = 1, SHOW_MULTI_SEAL do
|
||||||
|
sealToken(map.name, playerColor)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
printToColor("Not enough " .. notFound .. " tokens in the chaos bag.", playerColor)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- generates a list of chaos tokens that is in the chaos bag
|
||||||
|
function readBag()
|
||||||
|
local chaosbag = Global.call("findChaosBag")
|
||||||
|
tokensInBag = {}
|
||||||
|
|
||||||
|
for _, token in ipairs(chaosbag.getObjects()) do
|
||||||
|
tokensInBag[token.name] = (tokensInBag[token.name] or 0) + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- native event from TTS - used to update the context menu for cards like "Unrelenting"
|
||||||
|
function onHover()
|
||||||
|
if UPDATE_ON_HOVER then
|
||||||
|
readBag()
|
||||||
|
self.clearContextMenu()
|
||||||
|
generateContextMenu()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- seals the named token on this card
|
||||||
|
function sealToken(name, playerColor)
|
||||||
|
if not Global.call("canTouchChaosTokens") then return end
|
||||||
|
local chaosbag = Global.call("findChaosBag")
|
||||||
|
for i, obj in ipairs(chaosbag.getObjects()) do
|
||||||
|
if obj.name == name then
|
||||||
|
chaosbag.takeObject({
|
||||||
|
position = self.getPosition() + Vector(0, 0.5 + 0.1 * #sealedTokens, 0),
|
||||||
|
rotation = self.getRotation(),
|
||||||
|
index = i - 1,
|
||||||
|
smooth = false,
|
||||||
|
callback_function = function(token)
|
||||||
|
local guid = token.getGUID()
|
||||||
|
table.insert(sealedTokens, guid)
|
||||||
|
tokenArrangerApi.layout()
|
||||||
|
if name == "Bless" or name == "Curse" then
|
||||||
|
blessCurseManagerApi.sealedToken(name, guid)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
printToColor(name .. " token not found in chaos bag", playerColor)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- release the last sealed token
|
||||||
|
function releaseOneToken(playerColor)
|
||||||
|
if not Global.call("canTouchChaosTokens") then return end
|
||||||
|
if #sealedTokens == 0 then
|
||||||
|
printToColor("No sealed token(s) found", playerColor)
|
||||||
|
else
|
||||||
|
printToColor("Releasing token", playerColor)
|
||||||
|
putTokenAway(table.remove(sealedTokens))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- release multiple tokens at once
|
||||||
|
function releaseMultipleTokens(playerColor)
|
||||||
|
if SHOW_MULTI_RELEASE >= #sealedTokens then
|
||||||
|
for i = 1, SHOW_MULTI_RELEASE do
|
||||||
|
releaseOneToken(playerColor)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
printToColor("Not enough " .. name .. " tokens sealed.", playerColor)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- releases all sealed tokens
|
||||||
|
function releaseAllTokens(playerColor)
|
||||||
|
if not Global.call("canTouchChaosTokens") then return end
|
||||||
|
if #sealedTokens == 0 then
|
||||||
|
printToColor("No sealed token(s) found", playerColor)
|
||||||
|
else
|
||||||
|
printToColor("Releasing token(s)", playerColor)
|
||||||
|
for _, guid in ipairs(sealedTokens) do
|
||||||
|
putTokenAway(guid)
|
||||||
|
end
|
||||||
|
sealedTokens = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- returns the token (referenced by GUID) to the chaos bag
|
||||||
|
function putTokenAway(guid)
|
||||||
|
local token = getObjectFromGUID(guid)
|
||||||
|
if not token then return end
|
||||||
|
|
||||||
|
local name = token.getName()
|
||||||
|
local chaosbag = Global.call("findChaosBag")
|
||||||
|
chaosbag.putObject(token)
|
||||||
|
tokenArrangerApi.layout()
|
||||||
|
if name == "Bless" or name == "Curse" then
|
||||||
|
blessCurseManagerApi.releasedToken(name, guid)
|
||||||
|
end
|
||||||
|
end
|
@ -1,65 +1,6 @@
|
|||||||
VALID_TOKENS = {
|
VALID_TOKENS = {
|
||||||
["+1"]=true,
|
["+1"] = true,
|
||||||
["Elder Sign"]=true
|
["Elder Sign"] = true
|
||||||
}
|
}
|
||||||
|
|
||||||
function onload()
|
require("playercards/CardsThatSealTokens")
|
||||||
chaosbag = getChaosBag()
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if VALID_TOKENS[name] ~= nil then
|
|
||||||
self.addContextMenuItem("Seal " .. name, function(playerColor) sealToken(url, playerColor) end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
printToColor("Releasing token", playerColor)
|
|
||||||
for i,obj in ipairs(sealedTokens) do
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
|
||||||
sealedTokens = { }
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,81 +1,5 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
mode = "Curse"
|
["Curse"] = true
|
||||||
chaosbag = getChaosBag()
|
}
|
||||||
manager = getObjectFromGUID("5933fb")
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
require("playercards/CardsThatSealTokens")
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens, true)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == mode then
|
|
||||||
self.addContextMenuItem("Seal " .. mode, function(playerColor) sealToken(url, playerColor) end, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
local guid = obj.getGUID()
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
table.insert(tokensTaken[mode], guid)
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Sealing " .. mode .. " token " .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
if #sealedTokens == 0 then return end
|
|
||||||
local token = sealedTokens[#sealedTokens]
|
|
||||||
if token ~= nil then
|
|
||||||
local guid = token.getGUID()
|
|
||||||
chaosbag.putObject(token)
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
for i,v in ipairs(tokensTaken[mode]) do
|
|
||||||
if v == guid then
|
|
||||||
table.remove(tokensTaken[mode], i)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Releasing " .. mode .. " token" .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(sealedTokens)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,60 +1,5 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
chaosbag = getChaosBag()
|
["Elder Sign"] = true
|
||||||
sealedTokens = { }
|
}
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
require("playercards/CardsThatSealTokens")
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == "Elder Sign" then
|
|
||||||
self.addContextMenuItem("Seal Elder Sign", function(playerColor) sealToken(url, playerColor) end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
printToColor("Releasing token", playerColor)
|
|
||||||
for i,obj in ipairs(sealedTokens) do
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
|
||||||
sealedTokens = { }
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,81 +1,7 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
mode = "Curse"
|
["Curse"] = true
|
||||||
chaosbag = getChaosBag()
|
}
|
||||||
manager = getObjectFromGUID("5933fb")
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
SHOW_SINGLE_RELEASE = true
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens, true)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == mode then
|
|
||||||
self.addContextMenuItem("Seal " .. mode, function(playerColor) sealToken(url, playerColor) end, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
require("playercards/CardsThatSealTokens")
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
local guid = obj.getGUID()
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
table.insert(tokensTaken[mode], guid)
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Sealing " .. mode .. " token " .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
if #sealedTokens == 0 then return end
|
|
||||||
local token = sealedTokens[#sealedTokens]
|
|
||||||
if token ~= nil then
|
|
||||||
local guid = token.getGUID()
|
|
||||||
chaosbag.putObject(token)
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
for i,v in ipairs(tokensTaken[mode]) do
|
|
||||||
if v == guid then
|
|
||||||
table.remove(tokensTaken[mode], i)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Releasing " .. mode .. " token" .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(sealedTokens)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,81 +1,7 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
mode = "Bless"
|
["Bless"] = true
|
||||||
chaosbag = getChaosBag()
|
}
|
||||||
manager = getObjectFromGUID("5933fb")
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
SHOW_SINGLE_RELEASE = true
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens, true)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == mode then
|
|
||||||
self.addContextMenuItem("Seal " .. mode, function(playerColor) sealToken(url, playerColor) end, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
require("playercards/CardsThatSealTokens")
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
local guid = obj.getGUID()
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
table.insert(tokensTaken[mode], guid)
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Sealing " .. mode .. " token " .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
if #sealedTokens == 0 then return end
|
|
||||||
local token = sealedTokens[#sealedTokens]
|
|
||||||
if token ~= nil then
|
|
||||||
local guid = token.getGUID()
|
|
||||||
chaosbag.putObject(token)
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
for i,v in ipairs(tokensTaken[mode]) do
|
|
||||||
if v == guid then
|
|
||||||
table.remove(tokensTaken[mode], i)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Releasing " .. mode .. " token" .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(sealedTokens)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,81 +1,7 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
mode = "Curse"
|
["Curse"] = true
|
||||||
chaosbag = getChaosBag()
|
}
|
||||||
manager = getObjectFromGUID("5933fb")
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
SHOW_SINGLE_RELEASE = true
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens, true)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == mode then
|
|
||||||
self.addContextMenuItem("Seal " .. mode, function(playerColor) sealToken(url, playerColor) end, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
require("playercards/CardsThatSealTokens")
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
local guid = obj.getGUID()
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
table.insert(tokensTaken[mode], guid)
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Sealing " .. mode .. " token " .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
if #sealedTokens == 0 then return end
|
|
||||||
local token = sealedTokens[#sealedTokens]
|
|
||||||
if token ~= nil then
|
|
||||||
local guid = token.getGUID()
|
|
||||||
chaosbag.putObject(token)
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
for i,v in ipairs(tokensTaken[mode]) do
|
|
||||||
if v == guid then
|
|
||||||
table.remove(tokensTaken[mode], i)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Releasing " .. mode .. " token" .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(sealedTokens)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,93 +1,8 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
mode = "Bless"
|
["Bless"] = true
|
||||||
chaosbag = getChaosBag()
|
}
|
||||||
manager = getObjectFromGUID("5933fb")
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
SHOW_SINGLE_RELEASE = true
|
||||||
self.clearContextMenu()
|
SHOW_MULTI_SEAL = 2
|
||||||
self.addContextMenuItem("Release Token", releaseTokens, true)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == mode then
|
|
||||||
self.addContextMenuItem("Seal 2 " .. mode, function(playerColor) sealToken(url, playerColor) end, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
require("playercards/CardsThatSealTokens")
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
local indexes = {}
|
|
||||||
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
table.insert(indexes, obj.index)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if #indexes < 2 then
|
|
||||||
printToColor("Fewer than 2 " .. name .. " tokens in bag", playerColor)
|
|
||||||
return
|
|
||||||
end
|
|
||||||
table.sort(indexes)
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=indexes[#indexes],
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 2, pos.z },
|
|
||||||
index=indexes[#indexes-1],
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
local guid = obj.getGUID()
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
table.insert(tokensTaken[mode], guid)
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Sealing " .. mode .. " token " .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
if #sealedTokens == 0 then return end
|
|
||||||
local token = sealedTokens[#sealedTokens]
|
|
||||||
if token ~= nil then
|
|
||||||
local guid = token.getGUID()
|
|
||||||
chaosbag.putObject(token)
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
for i,v in ipairs(tokensTaken[mode]) do
|
|
||||||
if v == guid then
|
|
||||||
table.remove(tokensTaken[mode], i)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Releasing " .. mode .. " token" .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(sealedTokens)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,81 +1,7 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
mode = "Bless"
|
["Bless"] = true
|
||||||
chaosbag = getChaosBag()
|
}
|
||||||
manager = getObjectFromGUID("5933fb")
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
SHOW_MULTI_RELEASE = 3
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens, true)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == mode then
|
|
||||||
self.addContextMenuItem("Seal " .. mode, function(playerColor) sealToken(url, playerColor) end, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
require("playercards/CardsThatSealTokens")
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
local guid = obj.getGUID()
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
table.insert(tokensTaken[mode], guid)
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Sealing " .. mode .. " token " .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
if #sealedTokens == 0 then return end
|
|
||||||
local token = sealedTokens[#sealedTokens]
|
|
||||||
if token ~= nil then
|
|
||||||
local guid = token.getGUID()
|
|
||||||
chaosbag.putObject(token)
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
for i,v in ipairs(tokensTaken[mode]) do
|
|
||||||
if v == guid then
|
|
||||||
table.remove(tokensTaken[mode], i)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Releasing " .. mode .. " token" .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(sealedTokens)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,75 +1,9 @@
|
|||||||
function onload()
|
VALID_TOKENS = {}
|
||||||
chaosbag = getChaosBag()
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
readBag()
|
|
||||||
end
|
|
||||||
|
|
||||||
function readBag(playerColor)
|
INVALID_TOKENS = {
|
||||||
if playerColor ~= nil then
|
["Auto-fail"] = true
|
||||||
printToColor("Reading chaos bag", playerColor)
|
}
|
||||||
end
|
|
||||||
|
|
||||||
local tokensInBag = { }
|
UPDATE_ON_HOVER = true
|
||||||
for i,token in ipairs(chaosbag.getObjects()) do
|
|
||||||
if token.name ~= nil and token.name ~= "" then
|
|
||||||
tokensInBag[token.name] = true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
require("playercards/CardsThatSealTokens")
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if tokensInBag[name] and name ~= "Auto-fail" then
|
|
||||||
self.addContextMenuItem("Seal " .. name, function(playerColor) sealToken(url, playerColor) end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.addContextMenuItem("Read Chaos Bag", readBag)
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
printToColor("Releasing token", playerColor)
|
|
||||||
for i,obj in ipairs(sealedTokens) do
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
|
||||||
sealedTokens = { }
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,81 +1,5 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
mode = "Bless"
|
["Bless"] = true
|
||||||
chaosbag = getChaosBag()
|
}
|
||||||
manager = getObjectFromGUID("5933fb")
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
require("playercards/CardsThatSealTokens")
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens, true)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == mode then
|
|
||||||
self.addContextMenuItem("Seal " .. mode, function(playerColor) sealToken(url, playerColor) end, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
local guid = obj.getGUID()
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
table.insert(tokensTaken[mode], guid)
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Sealing " .. mode .. " token " .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
if #sealedTokens == 0 then return end
|
|
||||||
local token = sealedTokens[#sealedTokens]
|
|
||||||
if token ~= nil then
|
|
||||||
local guid = token.getGUID()
|
|
||||||
chaosbag.putObject(token)
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
for i,v in ipairs(tokensTaken[mode]) do
|
|
||||||
if v == guid then
|
|
||||||
table.remove(tokensTaken[mode], i)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Releasing " .. mode .. " token" .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(sealedTokens)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,81 +1,7 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
mode = "Bless"
|
["Bless"] = true
|
||||||
chaosbag = getChaosBag()
|
}
|
||||||
manager = getObjectFromGUID("5933fb")
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
SHOW_SINGLE_RELEASE = true
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens, true)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == mode then
|
|
||||||
self.addContextMenuItem("Seal " .. mode, function(playerColor) sealToken(url, playerColor) end, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
require("playercards/CardsThatSealTokens")
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
local guid = obj.getGUID()
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
table.insert(tokensTaken[mode], guid)
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Sealing " .. mode .. " token " .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
if #sealedTokens == 0 then return end
|
|
||||||
local token = sealedTokens[#sealedTokens]
|
|
||||||
if token ~= nil then
|
|
||||||
local guid = token.getGUID()
|
|
||||||
chaosbag.putObject(token)
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
for i,v in ipairs(tokensTaken[mode]) do
|
|
||||||
if v == guid then
|
|
||||||
table.remove(tokensTaken[mode], i)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Releasing " .. mode .. " token" .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(sealedTokens)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,60 +1,5 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
chaosbag = getChaosBag()
|
["Auto-fail"] = true
|
||||||
sealedTokens = { }
|
}
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
require("playercards/CardsThatSealTokens")
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == "Auto-fail" then
|
|
||||||
self.addContextMenuItem("Seal Auto-fail", function(playerColor) sealToken(url, playerColor) end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
printToColor("Releasing token", playerColor)
|
|
||||||
for i,obj in ipairs(sealedTokens) do
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
|
||||||
sealedTokens = { }
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,60 +1,5 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
chaosbag = getChaosBag()
|
["Elder Sign"] = true
|
||||||
sealedTokens = { }
|
}
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
require("playercards/CardsThatSealTokens")
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == "Elder Sign" then
|
|
||||||
self.addContextMenuItem("Seal Elder Sign", function(playerColor) sealToken(url, playerColor) end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
printToColor("Releasing token", playerColor)
|
|
||||||
for i,obj in ipairs(sealedTokens) do
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
|
||||||
sealedTokens = { }
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,45 +1,7 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
chaosbag = getChaosBag()
|
["0"] = true
|
||||||
IMAGE_TOKEN_MAP = { }
|
}
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
SHOW_SINGLE_RELEASE = true
|
||||||
self.clearContextMenu()
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == "0" then
|
|
||||||
self.addContextMenuItem("Seal 0", function(playerColor) sealToken(url, playerColor) end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
require("playercards/CardsThatSealTokens")
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,81 +1,7 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
mode = "Bless"
|
["Bless"] = true
|
||||||
chaosbag = getChaosBag()
|
}
|
||||||
manager = getObjectFromGUID("5933fb")
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
SHOW_SINGLE_RELEASE = true
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens, true)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == mode then
|
|
||||||
self.addContextMenuItem("Seal " .. mode, function(playerColor) sealToken(url, playerColor) end, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
require("playercards/CardsThatSealTokens")
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
local guid = obj.getGUID()
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
table.insert(tokensTaken[mode], guid)
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Sealing " .. mode .. " token " .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
if #sealedTokens == 0 then return end
|
|
||||||
local token = sealedTokens[#sealedTokens]
|
|
||||||
if token ~= nil then
|
|
||||||
local guid = token.getGUID()
|
|
||||||
chaosbag.putObject(token)
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
for i,v in ipairs(tokensTaken[mode]) do
|
|
||||||
if v == guid then
|
|
||||||
table.remove(tokensTaken[mode], i)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", mode)
|
|
||||||
printToAll("Releasing " .. mode .. " token" .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
|
|
||||||
table.remove(sealedTokens)
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,67 +1,8 @@
|
|||||||
VALID_TOKENS = {
|
VALID_TOKENS = {
|
||||||
Skull=true,
|
["Skull"] = true,
|
||||||
Cultist=true,
|
["Cultist"] = true,
|
||||||
Tablet=true,
|
["Tablet"] = true,
|
||||||
["Elder Thing"]=true
|
["Elder Thing"] = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
function onload()
|
require("playercards/CardsThatSealTokens")
|
||||||
chaosbag = getChaosBag()
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if VALID_TOKENS[name] ~= nil then
|
|
||||||
self.addContextMenuItem("Seal " .. name, function(playerColor) sealToken(url, playerColor) end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
printToColor("Releasing token", playerColor)
|
|
||||||
for i,obj in ipairs(sealedTokens) do
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
|
||||||
sealedTokens = { }
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,67 +1,8 @@
|
|||||||
VALID_TOKENS = {
|
VALID_TOKENS = {
|
||||||
Skull=true,
|
["Skull"] = true,
|
||||||
Cultist=true,
|
["Cultist"] = true,
|
||||||
Tablet=true,
|
["Tablet"] = true,
|
||||||
["Elder Thing"]=true
|
["Elder Thing"] = true,
|
||||||
}
|
}
|
||||||
|
|
||||||
function onload()
|
require("playercards/CardsThatSealTokens")
|
||||||
chaosbag = getChaosBag()
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if VALID_TOKENS[name] ~= nil then
|
|
||||||
self.addContextMenuItem("Seal " .. name, function(playerColor) sealToken(url, playerColor) end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
printToColor("Releasing token", playerColor)
|
|
||||||
for i,obj in ipairs(sealedTokens) do
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
|
||||||
sealedTokens = { }
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,60 +1,5 @@
|
|||||||
function onload()
|
VALID_TOKENS = {
|
||||||
chaosbag = getChaosBag()
|
["Elder Sign"] = true
|
||||||
sealedTokens = { }
|
}
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
-- add menu items
|
require("playercards/CardsThatSealTokens")
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Token", releaseTokens)
|
|
||||||
for url,name in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if name == "Elder Sign" then
|
|
||||||
self.addContextMenuItem("Seal Elder Sign", function(playerColor) sealToken(url, playerColor) end)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
printToColor("Releasing token", playerColor)
|
|
||||||
for i,obj in ipairs(sealedTokens) do
|
|
||||||
chaosbag.putObject(obj)
|
|
||||||
end
|
|
||||||
sealedTokens = { }
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
@ -1,97 +1,6 @@
|
|||||||
function onload()
|
VALID_TOKENS = {}
|
||||||
chaosbag = getChaosBag()
|
INVALID_TOKENS = {}
|
||||||
manager = getObjectFromGUID("5933fb")
|
|
||||||
sealedTokens = { }
|
|
||||||
IMAGE_TOKEN_MAP = { }
|
|
||||||
for i,v in pairs(Global.getVar("IMAGE_TOKEN_MAP")) do
|
|
||||||
IMAGE_TOKEN_MAP[i] = v
|
|
||||||
end
|
|
||||||
|
|
||||||
readBag()
|
UPDATE_ON_HOVER = true
|
||||||
end
|
|
||||||
|
|
||||||
function sealToken(url, playerColor)
|
require("playercards/CardsThatSealTokens")
|
||||||
local pos = self.getPosition()
|
|
||||||
|
|
||||||
local name = IMAGE_TOKEN_MAP[url]
|
|
||||||
for i,obj in ipairs(chaosbag.getObjects()) do
|
|
||||||
if obj.name == name then
|
|
||||||
chaosbag.takeObject({
|
|
||||||
position={ pos.x, pos.y + 1, pos.z },
|
|
||||||
index=i-1,
|
|
||||||
smooth=false,
|
|
||||||
callback_function=_sealToken
|
|
||||||
})
|
|
||||||
return
|
|
||||||
end
|
|
||||||
end
|
|
||||||
printToColor(name .. " token not found in bag", playerColor)
|
|
||||||
end
|
|
||||||
|
|
||||||
function _sealToken(obj)
|
|
||||||
table.insert(sealedTokens, obj)
|
|
||||||
local guid = obj.getGUID()
|
|
||||||
local name = obj.getName()
|
|
||||||
if name == "Bless" or name == "Curse" then
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
table.insert(tokensTaken[name], guid)
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", name)
|
|
||||||
printToAll("Sealing " .. name .. " token " .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function releaseTokens(playerColor)
|
|
||||||
if #sealedTokens == 0 then return end
|
|
||||||
for i,token in ipairs(sealedTokens) do
|
|
||||||
local guid = token.getGUID()
|
|
||||||
local name = token.getName()
|
|
||||||
chaosbag.putObject(token)
|
|
||||||
if name == "Bless" or name == "Curse" then
|
|
||||||
local tokensTaken = manager.getVar("tokensTaken")
|
|
||||||
for i,v in ipairs(tokensTaken[name]) do
|
|
||||||
if v == guid then
|
|
||||||
table.remove(tokensTaken[name], i)
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
manager.setVar("tokensTaken", tokensTaken)
|
|
||||||
manager.setVar("mode", name)
|
|
||||||
printToAll("Releasing " .. name .. " token" .. manager.call("getTokenCount"))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
sealedTokens = { }
|
|
||||||
end
|
|
||||||
|
|
||||||
function getChaosBag()
|
|
||||||
local items = getObjectFromGUID("83ef06").getObjects()
|
|
||||||
local chaosbag = nil
|
|
||||||
for i,v in ipairs(items) do
|
|
||||||
if v.getDescription() == "Chaos Bag" then
|
|
||||||
chaosbag = getObjectFromGUID(v.getGUID())
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if chaosbag == nil then printToAll("No chaos bag found") end
|
|
||||||
return chaosbag
|
|
||||||
end
|
|
||||||
|
|
||||||
function readBag()
|
|
||||||
-- add menu items
|
|
||||||
self.clearContextMenu()
|
|
||||||
self.addContextMenuItem("Release Tokens", releaseTokens)
|
|
||||||
|
|
||||||
local bagTokens = { }
|
|
||||||
local tokens = chaosbag.getObjects()
|
|
||||||
for i,token in ipairs(tokens) do
|
|
||||||
bagTokens[token.name] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
for url,token in pairs(IMAGE_TOKEN_MAP) do
|
|
||||||
if bagTokens[token] then
|
|
||||||
self.addContextMenuItem("Seal " .. token, function(playerColor) sealToken(url, playerColor) end, true)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
self.addContextMenuItem("Refresh Seal Options", readBag)
|
|
||||||
end
|
|
||||||
|
@ -67,7 +67,7 @@ isDES = false
|
|||||||
function onSave()
|
function onSave()
|
||||||
return JSON.encode({
|
return JSON.encode({
|
||||||
zoneID = zoneID,
|
zoneID = zoneID,
|
||||||
playerColor = PLAYER_COLOR,
|
playerColor = playerColor,
|
||||||
activeInvestigatorId = activeInvestigatorId,
|
activeInvestigatorId = activeInvestigatorId,
|
||||||
isDrawButtonVisible = isDrawButtonVisible
|
isDrawButtonVisible = isDrawButtonVisible
|
||||||
})
|
})
|
||||||
@ -80,6 +80,7 @@ function onLoad(save_state)
|
|||||||
STAT_TRACKER = getObjectFromGUID(STAT_TRACKER_GUID)
|
STAT_TRACKER = getObjectFromGUID(STAT_TRACKER_GUID)
|
||||||
RESOURCE_COUNTER = getObjectFromGUID(RESOURCE_COUNTER_GUID)
|
RESOURCE_COUNTER = getObjectFromGUID(RESOURCE_COUNTER_GUID)
|
||||||
|
|
||||||
|
-- button creation
|
||||||
for i = 1, 6 do
|
for i = 1, 6 do
|
||||||
makeDiscardButton(DISCARD_BUTTON_OFFSETS[i], {-3.85, 3, 10.38}, i)
|
makeDiscardButton(DISCARD_BUTTON_OFFSETS[i], {-3.85, 3, 10.38}, i)
|
||||||
end
|
end
|
||||||
@ -94,7 +95,7 @@ function onLoad(save_state)
|
|||||||
})
|
})
|
||||||
|
|
||||||
self.createButton({
|
self.createButton({
|
||||||
click_function = "drawChaostokenButton",
|
click_function = "drawChaosTokenButton",
|
||||||
function_owner = self,
|
function_owner = self,
|
||||||
position = {1.85, 0, -0.74},
|
position = {1.85, 0, -0.74},
|
||||||
rotation = {0, -45, 0},
|
rotation = {0, -45, 0},
|
||||||
@ -113,10 +114,11 @@ function onLoad(save_state)
|
|||||||
font_size = 180
|
font_size = 180
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- save state loading
|
||||||
local state = JSON.decode(save_state)
|
local state = JSON.decode(save_state)
|
||||||
if state ~= nil then
|
if state ~= nil then
|
||||||
zoneID = state.zoneID
|
zoneID = state.zoneID
|
||||||
PLAYER_COLOR = state.playerColor
|
playerColor = state.playerColor
|
||||||
activeInvestigatorId = state.activeInvestigatorId
|
activeInvestigatorId = state.activeInvestigatorId
|
||||||
isDrawButtonVisible = state.isDrawButtonVisible
|
isDrawButtonVisible = state.isDrawButtonVisible
|
||||||
end
|
end
|
||||||
@ -133,15 +135,6 @@ end
|
|||||||
-- utility functions
|
-- utility functions
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
function log(message)
|
|
||||||
if DEBUG then print(message) end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- send messages to player who clicked button if no seated player found
|
|
||||||
function setMessageColor(color)
|
|
||||||
messageColor = Player[PLAYER_COLOR].seated and PLAYER_COLOR or color
|
|
||||||
end
|
|
||||||
|
|
||||||
function spawnDeckZone()
|
function spawnDeckZone()
|
||||||
spawnObject({
|
spawnObject({
|
||||||
position = self.positionToWorld({-1.4, 0, 0.3 }),
|
position = self.positionToWorld({-1.4, 0, 0.3 }),
|
||||||
@ -165,7 +158,9 @@ function searchArea(origin, size)
|
|||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
function doNotReady(card) return card.getVar("do_not_ready") or false end
|
function doNotReady(card)
|
||||||
|
return card.getVar("do_not_ready") or false
|
||||||
|
end
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
-- Discard buttons
|
-- Discard buttons
|
||||||
@ -231,19 +226,18 @@ end
|
|||||||
-- Upkeep button
|
-- Upkeep button
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
function doUpkeep(_, color, alt_click)
|
function doUpkeep(_, clickedByColor, isRightClick)
|
||||||
setMessageColor(color)
|
-- right-click allow color changing
|
||||||
|
if isRightClick then
|
||||||
-- right-click binds to new player color
|
changeColor(clickedByColor)
|
||||||
if alt_click then
|
|
||||||
PLAYER_COLOR = color
|
|
||||||
printToColor("Upkeep button bound to " .. color, color)
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local forcedLearning = false
|
-- send messages to player who clicked button if no seated player found
|
||||||
|
messageColor = Player[playerColor].seated and playerColor or clickedByColor
|
||||||
|
|
||||||
-- unexhaust cards in play zone, flip action tokens and find forcedLearning
|
-- unexhaust cards in play zone, flip action tokens and find forcedLearning
|
||||||
|
local forcedLearning = false
|
||||||
for _, v in ipairs(searchArea(PLAY_ZONE_POSITION, PLAY_ZONE_SCALE)) do
|
for _, v in ipairs(searchArea(PLAY_ZONE_POSITION, PLAY_ZONE_SCALE)) do
|
||||||
local obj = v.hit_object
|
local obj = v.hit_object
|
||||||
if obj.getDescription() == "Action Token" and obj.is_face_down then
|
if obj.getDescription() == "Action Token" and obj.is_face_down then
|
||||||
@ -304,7 +298,7 @@ function doUpkeep(_, color, alt_click)
|
|||||||
if forcedLearning then
|
if forcedLearning then
|
||||||
printToColor("Wow, did you really take 'Versatile' to play Patrice with 'Forced Learning'? Choose which draw replacement effect takes priority and draw cards accordingly.", messageColor)
|
printToColor("Wow, did you really take 'Versatile' to play Patrice with 'Forced Learning'? Choose which draw replacement effect takes priority and draw cards accordingly.", messageColor)
|
||||||
else
|
else
|
||||||
local handSize = #Player[PLAYER_COLOR].getHandObjects()
|
local handSize = #Player[playerColor].getHandObjects()
|
||||||
if handSize < 5 then
|
if handSize < 5 then
|
||||||
local cardsToDraw = 5 - handSize
|
local cardsToDraw = 5 - handSize
|
||||||
printToColor("Drawing " .. cardsToDraw .. " cards (Patrice)", messageColor)
|
printToColor("Drawing " .. cardsToDraw .. " cards (Patrice)", messageColor)
|
||||||
@ -328,7 +322,8 @@ end
|
|||||||
|
|
||||||
-- function for "draw 1 button" (that can be added via option panel)
|
-- function for "draw 1 button" (that can be added via option panel)
|
||||||
function doDrawOne(_, color)
|
function doDrawOne(_, color)
|
||||||
setMessageColor(color)
|
-- send messages to player who clicked button if no seated player found
|
||||||
|
messageColor = Player[playerColor].seated and playerColor or color
|
||||||
drawCardsWithReshuffle(1)
|
drawCardsWithReshuffle(1)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -351,7 +346,7 @@ function drawCardsWithReshuffle(numCards)
|
|||||||
end
|
end
|
||||||
|
|
||||||
if topCard ~= nil then
|
if topCard ~= nil then
|
||||||
topCard.deal(numCards, PLAYER_COLOR)
|
topCard.deal(numCards, playerColor)
|
||||||
numCards = numCards - 1
|
numCards = numCards - 1
|
||||||
if numCards == 0 then return end
|
if numCards == 0 then return end
|
||||||
end
|
end
|
||||||
@ -402,7 +397,7 @@ end
|
|||||||
|
|
||||||
function drawCards(numCards)
|
function drawCards(numCards)
|
||||||
if drawDeck == nil then return end
|
if drawDeck == nil then return end
|
||||||
drawDeck.deal(numCards, PLAYER_COLOR)
|
drawDeck.deal(numCards, playerColor)
|
||||||
end
|
end
|
||||||
|
|
||||||
function shuffleDiscardIntoDeck()
|
function shuffleDiscardIntoDeck()
|
||||||
@ -415,8 +410,7 @@ end
|
|||||||
|
|
||||||
-- discard a random non-hidden card from hand
|
-- discard a random non-hidden card from hand
|
||||||
function doDiscardOne()
|
function doDiscardOne()
|
||||||
local handColor = getHandColor()
|
local hand = Player[playerColor].getHandObjects()
|
||||||
local hand = Player[handColor].getHandObjects()
|
|
||||||
if #hand == 0 then
|
if #hand == 0 then
|
||||||
broadcastToAll("Cannot discard from empty hand!", "Red")
|
broadcastToAll("Cannot discard from empty hand!", "Red")
|
||||||
else
|
else
|
||||||
@ -444,18 +438,72 @@ function doDiscardOne()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- gets the hand color of the closest seated player (by roughly cutting the table into quarters)
|
---------------------------------------------------------
|
||||||
function getHandColor()
|
-- color related functions
|
||||||
for _, handColor in ipairs(Player.getAvailableColors()) do
|
---------------------------------------------------------
|
||||||
local handPosition = Player[handColor].getHandTransform().position
|
|
||||||
|
|
||||||
if (PLAYER_COLOR == "White" and handPosition.x < -42 and handPosition.z > 0)
|
-- changes the player color
|
||||||
or (PLAYER_COLOR == "Orange" and handPosition.x < -42 and handPosition.z < 0)
|
function changeColor(clickedByColor)
|
||||||
or (PLAYER_COLOR == "Green" and handPosition.x > -42 and handPosition.z > 0)
|
local colorList = {
|
||||||
or (PLAYER_COLOR == "Red" and handPosition.x > -42 and handPosition.z < 0) then
|
"White",
|
||||||
return handColor
|
"Brown",
|
||||||
|
"Red",
|
||||||
|
"Orange",
|
||||||
|
"Yellow",
|
||||||
|
"Green",
|
||||||
|
"Teal",
|
||||||
|
"Blue",
|
||||||
|
"Purple",
|
||||||
|
"Pink"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- remove existing colors from the list of choices
|
||||||
|
for _, existingColor in ipairs(Player.getAvailableColors()) do
|
||||||
|
for i, newColor in ipairs(colorList) do
|
||||||
|
if existingColor == newColor then
|
||||||
|
table.remove(colorList, i)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- show the option dialog for color selection to the player that triggered this
|
||||||
|
Player[clickedByColor].showOptionsDialog("Select a new color:", colorList, _, function(color)
|
||||||
|
local HAND_ZONE_GUIDS = {
|
||||||
|
"a70eee", -- White
|
||||||
|
"5fe087", -- Orange
|
||||||
|
"0285cc", -- Green
|
||||||
|
"be2f17" -- Red
|
||||||
|
}
|
||||||
|
local index
|
||||||
|
local startPos = self.getPosition()
|
||||||
|
|
||||||
|
-- get respective hand zone by position
|
||||||
|
if startPos.x < -42 then
|
||||||
|
if startPos.z > 0 then
|
||||||
|
index = 1
|
||||||
|
else
|
||||||
|
index = 2
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if startPos.z > 0 then
|
||||||
|
index = 3
|
||||||
|
else
|
||||||
|
index = 4
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- update the color of the hand zone
|
||||||
|
local handZone = getObjectFromGUID(HAND_ZONE_GUIDS[index])
|
||||||
|
handZone.setValue(color)
|
||||||
|
|
||||||
|
-- if the seated player clicked this, reseat him to the new color
|
||||||
|
if clickedByColor == playerColor then
|
||||||
|
Player[playerColor].changeColor(color)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- update the internal variable
|
||||||
|
playerColor = color
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
@ -722,8 +770,8 @@ end
|
|||||||
-- calls to 'Global' / functions for calls from outside
|
-- calls to 'Global' / functions for calls from outside
|
||||||
---------------------------------------------------------
|
---------------------------------------------------------
|
||||||
|
|
||||||
function drawChaostokenButton(_, _, isRightClick)
|
function drawChaosTokenButton(_, _, isRightClick)
|
||||||
Global.call("drawChaostoken", {self, DRAWN_CHAOS_TOKEN_OFFSET, isRightClick})
|
Global.call("drawChaosToken", {self, DRAWN_CHAOS_TOKEN_OFFSET, isRightClick})
|
||||||
end
|
end
|
||||||
|
|
||||||
function drawEncountercard(_, _, isRightClick)
|
function drawEncountercard(_, _, isRightClick)
|
||||||
|
@ -43,9 +43,9 @@ do
|
|||||||
|
|
||||||
-- Returns the color of the player's hand that is seated next to the playermat
|
-- Returns the color of the player's hand that is seated next to the playermat
|
||||||
---@param matColor String Color of the playermat
|
---@param matColor String Color of the playermat
|
||||||
PlaymatApi.getHandColor = function(matColor)
|
PlaymatApi.getPlayerColor = function(matColor)
|
||||||
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
||||||
return mat.call("getHandColor")
|
return mat.getVar("playerColor")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat
|
-- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat
|
||||||
|
Loading…
Reference in New Issue
Block a user