diff --git a/config.json b/config.json
index 4e4a66f8..46a7d5dd 100644
--- a/config.json
+++ b/config.json
@@ -22,7 +22,7 @@
},
"Lighting_path": "Lighting.json",
"LuaScript": "require(\"core/Global\")",
- "LuaScriptState": "{\"optionPanel\":[false,false,false,false,false,false,false,false]}",
+ "LuaScriptState": "{\"optionPanel\":{\"useSnapTags\":true,\"showDrawButton\":false,\"useClueClickers\":false,\"showTokenArranger\":false,\"showCleanUpHelper\":false,\"showHandHelper\":false}}",
"MusicPlayer_path": "MusicPlayer.json",
"Note": "",
"ObjectStates_order": [
diff --git a/objects/Fan-MadeAccessories.aa8b38/ChaosBagManager.023240.ttslua b/objects/Fan-MadeAccessories.aa8b38/ChaosBagManager.023240.ttslua
index 040faae9..10d54327 100644
--- a/objects/Fan-MadeAccessories.aa8b38/ChaosBagManager.023240.ttslua
+++ b/objects/Fan-MadeAccessories.aa8b38/ChaosBagManager.023240.ttslua
@@ -1,11 +1,3 @@
--- Chaos Bag Manager
--- made by: Chr1Z
--- description: for easier managing of the chaos bag (adding / removing tokens)
-information = {
- version = "1.5",
- last_updated = "24.11.2022"
-}
-
local TOKEN_URL = {
ElderSign = "https://i.imgur.com/nEmqjmj.png",
plusOne = "https://i.imgur.com/uIx8jbY.png",
@@ -61,7 +53,7 @@ buttonParameters.width = 300
buttonParameters.height = 300
local UPDATING = false
-local tokenarranger
+local tokenArranger
local name
local tokens = {}
@@ -87,11 +79,10 @@ function onLoad()
self.addContextMenuItem("More Information", function()
printToAll("------------------------------", "White")
- printToAll("Chaos Bag Manager v" .. information["version"] .. " by Chr1Z", "Orange")
- printToAll("last updated: " .. information["last_updated"], "White")
+ printToAll("Chaos Bag Manager by Chr1Z", "Orange")
end)
- tokenarranger = getObjectFromGUID("022907")
+ tokenArranger = getObjectFromGUID("022907")
end
-- get chaos bag from scripting zone and description
@@ -182,11 +173,11 @@ function spawnCallback(obj)
end
function updateTokenArranger()
- if tokenarranger and not UPDATING then
+ if tokenArranger and not UPDATING then
UPDATING = true
Wait.time(function()
UPDATING = false
- tokenarranger.call("layout")
+ tokenArranger.call("layout")
end, 1.5)
end
end
diff --git a/objects/Fan-MadeAccessories.aa8b38/HandHelper.450688.ttslua b/objects/Fan-MadeAccessories.aa8b38/HandHelper.450688.ttslua
index 4c0b4262..c186124a 100644
--- a/objects/Fan-MadeAccessories.aa8b38/HandHelper.450688.ttslua
+++ b/objects/Fan-MadeAccessories.aa8b38/HandHelper.450688.ttslua
@@ -1,12 +1,3 @@
--- Hand Helper
--- updated by: Chr1Z
--- original by: -
--- description: counts cards in your hand (all or unique), can discard a random card
-information = {
- version = "1.2",
- last_updated = "11.10.2022"
-}
-
MAT_GUIDS = { "8b081b", "bd0ff4", "383d8b", "0840d5" }
local BUTTON_PARAMETERS = {}
@@ -69,8 +60,7 @@ function onLoad(saved_data)
-- context menu to display additional information
self.addContextMenuItem("More Information", function()
printToAll("------------------------------", "White")
- printToAll("Hand Helper v" .. information["version"] .. " by Chr1Z", "Orange")
- printToAll("last updated: " .. information["last_updated"], "White")
+ printToAll("Hand Helper by Chr1Z", "Orange")
printToAll("original by Tikatoy", "White")
printToAll("Note: 'Hidden' cards can't be randomly discarded.", "Yellow")
printToAll("Set them aside beforehand!", "Yellow")
@@ -135,6 +125,11 @@ function updateValue()
self.editButton({index = 0, font_color = des and "Green" or "White", label = size})
end
+-- allows change of color via external call
+function externalColorChange(newColor)
+ changeColor(_, _, _, newColor)
+end
+
-- get index of current color and move up one step (or down for right-click)
function changeColor(_, _, isRightClick, color)
if color then
diff --git a/objects/Fan-MadeAccessories.aa8b38/TokenArranger.022907.luascriptstate b/objects/Fan-MadeAccessories.aa8b38/TokenArranger.022907.luascriptstate
index bec5a180..56ab1542 100644
--- a/objects/Fan-MadeAccessories.aa8b38/TokenArranger.022907.luascriptstate
+++ b/objects/Fan-MadeAccessories.aa8b38/TokenArranger.022907.luascriptstate
@@ -1 +1 @@
-{"":[0,11],"Auto-fail":[-100,7],"Bless":[101,8],"Cultist":[-2,4],"Curse":[-100,9],"Elder Sign":[100,2],"Elder Thing":[-4,6],"Frost":[-99,10],"Skull":[-1,3],"Tablet":[-3,5]}
+{"":[0,11],"Auto-fail":[-100,7],"Bless":[101,8],"Cultist":[-2,4],"Curse":[-101,9],"Elder Sign":[100,2],"Elder Thing":[-4,6],"Frost":[-99,10],"Skull":[-1,3],"Tablet":[-3,5]}
diff --git a/objects/Fan-MadeAccessories.aa8b38/TokenArranger.022907.ttslua b/objects/Fan-MadeAccessories.aa8b38/TokenArranger.022907.ttslua
index b215c02d..485eb56d 100644
--- a/objects/Fan-MadeAccessories.aa8b38/TokenArranger.022907.ttslua
+++ b/objects/Fan-MadeAccessories.aa8b38/TokenArranger.022907.ttslua
@@ -1,14 +1,5 @@
--- Token Arranger
--- created by: Chr1Z
--- original by: Whimsical
--- description: displays the content of the chaos bag
-information = {
- version = "1.7",
- last_updated = "13.11.2022"
-}
-
-- names of tokens in order
-local token_names = {
+local TOKEN_NAMES = {
"Elder Sign",
"Skull",
"Cultist",
@@ -23,7 +14,7 @@ local token_names = {
-- token modifiers for sorting (and order for same modifier)
-- order starts at 2 because there is a "+1" token
-local token_precedence = {
+local TOKEN_PRECEDENCE = {
["Elder Sign"] = { 100, 2 },
["Skull"] = { -1, 3 },
["Cultist"] = { -2, 4 },
@@ -54,16 +45,13 @@ inputParameters.alignment = 3
inputParameters.validation = 2
inputParameters.tab = 2
--- tag for cloned tokens
-TO_DELETE_TAG = "to_be_deleted"
-
updating = false
-function onSave() return JSON.encode(token_precedence) end
+function onSave() return JSON.encode(TOKEN_PRECEDENCE) end
function onLoad(save_state)
if save_state ~= nil then
- token_precedence = JSON.decode(save_state)
+ TOKEN_PRECEDENCE = JSON.decode(save_state)
end
-- create UI
@@ -82,7 +70,7 @@ function onLoad(save_state)
buttonParameters.click_function = attachIndex("tokenClick", i)
inputParameters.input_function = attachIndex2("tokenInput", i)
- inputParameters.value = token_precedence[token_names[i]][1]
+ inputParameters.value = TOKEN_PRECEDENCE[TOKEN_NAMES[i]][1]
self.createButton(buttonParameters)
self.createInput(inputParameters)
@@ -100,27 +88,29 @@ function onLoad(save_state)
self.addContextMenuItem("More Information", function()
printToAll("------------------------------", "White")
- printToAll("Token Arranger v" .. information["version"] .. " by Chr1Z", "Orange")
- printToAll("last updated: " .. information["last_updated"], "White")
+ printToAll("Token Arranger by Chr1Z", "Orange")
printToAll("original concept by Whimsical", "White")
end)
-- send object reference to bless/curse manager
- Wait.time(function()
- getObjectFromGUID("5933fb").setVar("tokenArranger", self)
- end, 1)
+ Wait.time(function() getObjectFromGUID("5933fb").setVar("tokenArranger", self) end, 1)
end
function onDestroy()
+ deleteCopiedTokens()
-- remove object reference from bless/curse manager
getObjectFromGUID("5933fb").setVar("tokenArranger", nil)
end
+function onPickUp()
+ deleteCopiedTokens()
+end
+
-- helper functions to carry index
function attachIndex(click_function, index)
local fn_name = click_function .. index
- _G[fn_name] = function(obj, player_color, alt_click)
- _G[click_function](obj, player_color, alt_click, index)
+ _G[fn_name] = function(obj, player_color, isRightClick)
+ _G[click_function](obj, player_color, isRightClick, index)
end
return fn_name
end
@@ -134,26 +124,23 @@ function attachIndex2(input_function, index)
end
-- click_function for buttons on chaos tokens
-function tokenClick(obj, player_color, alt_click, index)
+function tokenClick(_, _, isRightClick, index)
if not updating then
updating = true
- if alt_click then
- token_precedence[token_names[index]][1] = token_precedence[token_names[index]][1] - 1
- else
- token_precedence[token_names[index]][1] = token_precedence[token_names[index]][1] + 1
- end
- self.editInput({ index = index - 1, value = token_precedence[token_names[index]][1] })
+ local change = tonumber(isRightClick and "-1" or "1")
+ TOKEN_PRECEDENCE[TOKEN_NAMES[index]][1] = TOKEN_PRECEDENCE[TOKEN_NAMES[index]][1] + change
+ self.editInput({ index = index - 1, value = TOKEN_PRECEDENCE[TOKEN_NAMES[index]][1] })
layout()
end
end
-- input_function for input_boxes
-function tokenInput(obj, player_color, input, selected, index)
+function tokenInput(_, _, input, selected, index)
if selected == false and not updating then
updating = true
local num = tonumber(input)
if num ~= nil then
- token_precedence[token_names[index]][1] = num
+ TOKEN_PRECEDENCE[TOKEN_NAMES[index]][1] = num
end
layout()
end
@@ -194,10 +181,14 @@ function getChaosBag()
return chaosbag
end
+-- deletes previously placed tokens
+function deleteCopiedTokens()
+ for _, token in ipairs(getObjectsWithTag("to_be_deleted")) do token.destruct() end
+end
+
-- main function (delete old tokens, clone chaos bag content, sort it and position it)
function layout(_, _, isRightClick)
- -- delete previously pulled out tokens
- for _, token in ipairs(getObjectsWithTag(TO_DELETE_TAG)) do token.destruct() end
+ deleteCopiedTokens()
-- stop here if right-clicked
if isRightClick then return end
@@ -212,25 +203,24 @@ function layout(_, _, isRightClick)
smooth = false,
callback_function = function(tok)
chaos_bag.putObject(tok.clone())
- tok.addTag(TO_DELETE_TAG)
+ tok.addTag("to_be_deleted")
end
}
end
-- wait until all tokens have finished spawning
- Wait.condition(function() do_position() end,
- function() return #chaos_bag_objects == #getObjectsWithTag(TO_DELETE_TAG) end)
+ Wait.condition(function() placeTokens() end, function() return #chaos_bag_objects == #getObjectsWithTag("to_be_deleted") end)
end
-- position tokens sorted by value
-function do_position()
+function placeTokens()
local data = {}
-- create table with tokens
- for i, token in ipairs(getObjectsWithTag(TO_DELETE_TAG)) do
+ for i, token in ipairs(getObjectsWithTag("to_be_deleted")) do
local name = token.getName() or ""
local value = tonumber(name)
- local precedence = token_precedence[name]
+ local precedence = TOKEN_PRECEDENCE[name]
data[i] = {
token = token,
diff --git a/src/core/Global.ttslua b/src/core/Global.ttslua
index e415346f..53e9d6c3 100644
--- a/src/core/Global.ttslua
+++ b/src/core/Global.ttslua
@@ -11,6 +11,9 @@ optionPanel = {}
-- GUID of data helper
DATA_HELPER_GUID = "708279"
+-- GUID of fan-made accessories bag (also just called "barrel")
+BARREL_GUID = "aa8b38"
+
-- GUIDs that will not be interactable (e.g. parts of the table)
local NOT_INTERACTABLE = {
"6161b4",
@@ -634,52 +637,6 @@ function onClick_load()
UI.hide('load_button')
end
-function onClick_defaultSettings()
- print("Dummy: Load default settings")
-end
-
-function onClick_toggleOption(_, id)
- local state = self.UI.getAttribute("toggle" .. id, "isOn")
-
- -- flip state (and handle stupid "False" value)
- if state == "False" then
- state = true
- else
- state = false
- end
-
- self.UI.setAttribute("toggle" .. id, "isOn", state)
-
- id = tonumber(id)
- optionPanel[id] = state
- applyOptionPanelChange(id, state)
-end
-
--- sets the option panel to the correct state (corresponding to 'optionPanel')
-function updateOptionPanelState()
- for id, enabled in pairs(optionPanel) do
- if enabled then self.UI.setAttribute("toggle" .. id, "isOn", true) end
- end
-end
-
-function applyOptionPanelChange(id, state)
- -- option 1: Snap tags
- if id == 1 then
- playmatAPI.setLimitSnapsByType(state, "All")
-
- -- option 2: Draw 1 button
- elseif id == 2 then
- playmatAPI.showDrawButton(state, "All")
-
- -- option 3: Clickable clue counters
- elseif id == 3 then
- playmatAPI.clickableClues(state, "All")
-
- -- update master clue counter
- getObjectFromGUID("4a3aa4").setVar("useClickableCounters", state)
- end
-end
-
function onClick_toggleUi(_, title)
UI.hide('optionPanel')
UI.hide('load_ui')
@@ -825,3 +782,142 @@ function urldecode(str)
function (h) return string.char(tonumber(h, 16)) end)
return str
end
+
+---------------------------------------------------------
+-- Option Panel related functionality
+---------------------------------------------------------
+
+-- loads the default options
+function onClick_defaultSettings()
+ print("Dummy: Load default settings")
+end
+
+-- called by toggling an option
+function onClick_toggleOption(_, id)
+ local state = self.UI.getAttribute(id, "isOn")
+
+ -- flip state (and handle stupid "False" value)
+ if state == "False" then
+ state = true
+ else
+ state = false
+ end
+
+ self.UI.setAttribute(id, "isOn", state)
+ optionPanel[id] = state
+ applyOptionPanelChange(id, state)
+end
+
+-- sets the option panel to the correct state (corresponding to 'optionPanel')
+function updateOptionPanelState()
+ for id, enabled in pairs(optionPanel) do
+ if enabled then
+ self.UI.setAttribute(id, "isOn", true)
+ end
+ end
+end
+
+-- handles the applying of option selections and calls the respective functions based
+---@param id String ID of the option that was selected or deselected
+---@param state Boolean State of the option (true = enabled)
+function applyOptionPanelChange(id, state)
+ -- option: Snap tags
+ if id == "useSnapTags" then
+ playmatAPI.setLimitSnapsByType(state, "All")
+
+ -- option: Draw 1 button
+ elseif id == "showDrawButton" then
+ playmatAPI.showDrawButton(state, "All")
+
+ -- option: Clickable clue counters
+ elseif id == "useClueClickers" then
+ playmatAPI.clickableClues(state, "All")
+
+ -- update master clue counter
+ getObjectFromGUID("4a3aa4").setVar("useClickableCounters", state)
+
+ -- option: Show token arranger
+ elseif id == "showTokenArranger" then
+ -- delete previously pulled out tokens
+ for _, token in ipairs(getObjectsWithTag("to_be_deleted")) do token.destruct() end
+
+ spawnOrRemoveHelper(state, "Token Arranger", {-42.3, 1.4, -46.5})
+
+ -- option: Show clean up helper
+ elseif id == "showCleanUpHelper" then
+ spawnOrRemoveHelper(state, "Clean Up Helper", {-68, 1.6, 35.5})
+
+ -- option: Show hand helper for each player
+ elseif id == "showHandHelper" then
+ spawnOrRemoveHelper(state, "Hand Helper", {-50.84, 1.6, 7.02}, {0, 270, 0}, "White")
+ spawnOrRemoveHelper(state, "Hand Helper", {-50.90, 1.6, -25.10}, {0, 270, 0}, "Orange")
+ spawnOrRemoveHelper(state, "Hand Helper", {-34.38, 1.6, 22.44}, {0, 000, 0}, "Green")
+ spawnOrRemoveHelper(state, "Hand Helper", {-16.69, 1.6, -22.42}, {0, 180, 0}, "Red")
+
+ -- option: Show chaos bag manager
+ elseif id == "showChaosBagManager" then
+ spawnOrRemoveHelper(state, "Chaos Bag Manager", {-67.8, 1.4, -49.5})
+ end
+end
+
+-- handler for spawn / remove functions of helper objects
+---@param state Boolean Contains the state of the option: true = spawn it, false = remove it
+---@param name String Name of the helper object
+---@param position Vector Position of the object (where it will spawn or where it will be removed from)
+---@param rotation Vector Rotation of the object for spawning (default: {0, 270, 0})
+---@param color Color This is only needed for correctly setting the color of the "Hand Helper"
+function spawnOrRemoveHelper(state, name, position, rotation, color)
+ if state then
+ spawnHelperObject(name, position, rotation, color)
+ Player["White"].pingTable(position)
+ else
+ removeHelperObject(name, position)
+ end
+end
+
+-- copies the specified tool (by name) from the barrel
+---@param name String Name of the object that should be copied
+---@param position Position Desired position of the object
+function spawnHelperObject(name, position, rotation, color)
+ if rotation == nil then rotation = {0, 270, 0} end
+
+ for _, obj in ipairs(getObjectFromGUID(BARREL_GUID).getData().ContainedObjects) do
+ if obj["Nickname"] == name then
+ spawnObjectData({
+ data = obj,
+ position = position,
+ rotation = rotation,
+ callback_function = function(object)
+ if name == "Hand Helper" then
+ Wait.time(function() object.call("externalColorChange", color) end, 1)
+ elseif name == "Token Arranger" then
+ Wait.time(function() object.call("layout") end, 1)
+ end
+ end
+ })
+ return
+ end
+ end
+end
+
+-- removes the specified tool (by name) from the provided position
+---@param name String Name of the object that should be removed
+---@param position Position Position of the object
+function removeHelperObject(name, position)
+ local search = Physics.cast({
+ direction = { 0, 1, 0 },
+ max_distance = 1,
+ type = 3,
+ size = {1, 1, 1},
+ origin = position,
+ orientation = { 0, 270, 0 }
+ })
+
+ for _, obj in ipairs(search) do
+ obj = obj.hit_object
+ if obj.getName() == name then
+ obj.destruct()
+ return
+ end
+ end
+end
\ No newline at end of file
diff --git a/src/tokens/BlessCurseManager.ttslua b/src/tokens/BlessCurseManager.ttslua
index 4030db7f..84ab3f55 100644
--- a/src/tokens/BlessCurseManager.ttslua
+++ b/src/tokens/BlessCurseManager.ttslua
@@ -174,9 +174,7 @@ end
function doReset(color)
-- delete previously pulled out tokens by the token arranger
if tokenArranger then
- for _, token in ipairs(getObjectsWithTag(tokenArranger.getVar("TO_DELETE_TAG"))) do
- token.destruct()
- end
+ tokenArranger.call("deleteCopiedTokens")
end
playerColor = color
diff --git a/xml/OptionPanel.xml b/xml/OptionPanel.xml
index 019b8779..507677b4 100644
--- a/xml/OptionPanel.xml
+++ b/xml/OptionPanel.xml
@@ -3,14 +3,14 @@
-
-
-
+
+
+
-
+
-
+
@@ -20,99 +20,84 @@
-
+Options
-
+
PLAYERMAT SETTINGS
-
+
Enable snap tagsOnly cards with the tag "Asset" will snap (official cards are supported by default).
Disable this if you are having issues with custom content.
-
+
-
+
Show "Draw 1" buttonDisplays a button below the "Upkeep" button that draws a card from your deck. Useful for multi-handed solo play.
-
+
-
+
Use clickable clue-counters
- Instead of automatically counting clues in the respective area on your playermat, this displays a clickable counter for clues.
Take note of each player's clue count before changing this option!
+ Instead of automatically counting clues in the respective area on your playermat, this displays a clickable counter for clues.
-
+
-
+
FAN-MADE ACCESSORIES
-
+
- Toggle Text 4
- Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat...
+ Show "Token Arranger"
+ See the contents of the chaos bag at a glance! This tool displays a sorted table of the tokens to allow easier guessing of your odds.
-
+
-
+
- Toggle Text 5
- Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat...
+ Show "Clean Up Helper"
+ Useful for campaign-play: It resets play areas to allow continuous gameplay in the same savegame.
-
+
-
+
- Toggle Text 6
- Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat...
+ Show "Hand Helper"
+ Never count your hand cards again! This tool does that for you and can even take "Dream-Enhancing Serum" into account. Also includes a button for randomly discard a card.
-
-
-
-
-
-
-
- Group 3
-
-
-
-
- Toggle Text 7
- Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat...
-
-
+
-
+
- Toggle Text 8
- Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat...
+ Show "Chaos Bag Manager"
+ Panel for easy addition or removal of chaos tokens to the bag - very useful for EotE because of Frost tokens!
-
+