Merge pull request #102 from argonui/cleanuphelper

Clean Up Helper: XML UI for options + code cleanup
This commit is contained in:
Chr1Z 2022-12-17 11:00:10 +01:00 committed by GitHub
commit e2a5164a7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 228 additions and 128 deletions

View File

@ -22,7 +22,24 @@
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/1850441528393599634/FA79B99F5544D16D38DCC8A26F1CEB3E7D9FED17/", "ImageURL": "http://cloud-3.steamusercontent.com/ugc/1850441528393599634/FA79B99F5544D16D38DCC8A26F1CEB3E7D9FED17/",
"WidthScale": 0 "WidthScale": 0
}, },
"Description": "Cleans up the table for the next scenario.\n\nSee context menu for additional information.", "CustomUIAssets": [
{
"Type": 1,
"Name": "font_teutonic-arkham",
"URL": "http://cloud-3.steamusercontent.com/ugc/2027213118467703445/89328E273B4C5180BF491516CE998DE3C604E162/"
},
{
"Type": 0,
"Name": "option_on",
"URL": "http://cloud-3.steamusercontent.com/ugc/2024961953545431779/1D892EC9A38B06B8D34692642CDEEECF928DCE1C/"
},
{
"Type": 0,
"Name": "option_off",
"URL": "http://cloud-3.steamusercontent.com/ugc/2024961953545431709/07AD4D32B5C29A3B9F0917924CF7010A29DC3CE4/"
}
],
"Description": "Cleans up the table for the next scenario during campaign play.\n\nThis includes moving cards and tokens into the trashcans, resetting counters and removing bless/curse tokens from the chaos bag.",
"DragSelectable": true, "DragSelectable": true,
"GMNotes": "", "GMNotes": "",
"GUID": "26cf4b", "GUID": "26cf4b",
@ -33,7 +50,7 @@
"IgnoreFoW": false, "IgnoreFoW": false,
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": false, "Locked": false,
"LuaScriptState": "[true,true,true]", "LuaScriptState": "{\"options\":{\"importTrauma\":true,\"removeDrawnLines\":false,\"tidyPlayermats\":true}}",
"LuaScript_path": "Fan-MadeAccessories.aa8b38/CleanUpHelper.26cf4b.ttslua", "LuaScript_path": "Fan-MadeAccessories.aa8b38/CleanUpHelper.26cf4b.ttslua",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Token", "Name": "Custom_Token",
@ -51,10 +68,10 @@
"rotX": 0, "rotX": 0,
"rotY": 270, "rotY": 270,
"rotZ": 0, "rotZ": 0,
"scaleX": 1.2, "scaleX": 2,
"scaleY": 1, "scaleY": 1,
"scaleZ": 1.2 "scaleZ": 2
}, },
"Value": 0, "Value": 0,
"XmlUI": "" "XmlUI_path": "Fan-MadeAccessories.aa8b38/CleanUpHelper.26cf4b.xml"
} }

View File

@ -1,11 +1,12 @@
-- Clean Up Helper --[[
-- made by: Chr1Z Cleans up the table for the next scenario in a campaign:
-- description: 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 playAreaApi = require("core/PlayAreaApi") local playAreaApi = require("core/PlayAreaApi")
-- enable this for debugging -- enable this for debugging
local SHOW_RAYS = false local SHOW_RAYS = false
@ -29,24 +30,21 @@ local IGNORE_TAG = "CleanUpHelper_ignore"
-- colors and order for following tables -- colors and order for following tables
local COLORS = { "White"; "Orange"; "Green"; "Red"; "Agenda" } local COLORS = { "White"; "Orange"; "Green"; "Red"; "Agenda" }
-- counter GUIDS (4x damage, 4x sanity and 4x resource) -- counter GUIDS (4x damage and 4x horror)
local TOKEN_GUIDS = { local DAMAGE_HORROR_GUIDS = {
"eb08d6"; "e64eec"; "1f5a0a"; "591a45"; "eb08d6"; "e64eec"; "1f5a0a"; "591a45";
"468e88"; "0257d9"; "7b5729"; "beb964"; "468e88"; "0257d9"; "7b5729"; "beb964";
"4406f0"; "816d84"; "cd15ac"; "a4b60d"
} }
-- default values (4x damage, 4x horror, 4x resources) local RESET_VALUES = {}
local DEFAULT_VALUES = {
0; 0; 0; 0;
0; 0; 0; 0;
5; 5; 5; 5
}
local PLAYERMAT_GUIDS = { "8b081b"; "bd0ff4"; "383d8b"; "0840d5" } -- GUIDS of objects (in order of ownership relating to 'COLORS')
local TRACKER_GUIDS = { "e598c2"; "b4a5f7"; "af7ed7"; "e74881" } local PLAYERMAT_GUIDS = { "8b081b"; "bd0ff4"; "383d8b"; "0840d5" }
local CLUE_GUIDS = { "d86b7c"; "1769ed"; "032300"; "37be78" } local RESOURCE_GUIDS = { "4406f0"; "816d84"; "cd15ac"; "a4b60d" }
local TRASHCAN_GUIDS = { "147e80"; "f7b6c8"; "5f896a"; "4b8594"; "70b9f6" } local TRACKER_GUIDS = { "e598c2"; "b4a5f7"; "af7ed7"; "e74881" }
local CLUE_GUIDS = { "d86b7c"; "1769ed"; "032300"; "37be78" }
local CLUE_CLICKER_GUIDS = { "db85d6"; "3f22e5"; "891403"; "4111de" }
local TRASHCAN_GUIDS = { "147e80"; "f7b6c8"; "5f896a"; "4b8594"; "70b9f6" }
-- values for physics.cast (4 entries for player zones, 5th entry for agenda/act deck, 6th for campaign log) -- values for physics.cast (4 entries for player zones, 5th entry for agenda/act deck, 6th for campaign log)
local PHYSICS_POSITION = { local PHYSICS_POSITION = {
@ -69,9 +67,11 @@ local PHYSICS_SCALE = {
{ 05.0, 1, 05.0 } { 05.0, 1, 05.0 }
} }
local tidyPlayermats = true local optionsVisible = false
local importTrauma = true local options = {}
local resetResources = true options["importTrauma"] = true
options["tidyPlayermats"] = true
options["removeDrawnLines"] = false
local buttonParameters = {} local buttonParameters = {}
buttonParameters.function_owner = self buttonParameters.function_owner = self
@ -80,88 +80,80 @@ buttonParameters.function_owner = self
-- option loading and GUI setup -- option loading and GUI setup
--------------------------------------------------------- ---------------------------------------------------------
function onSave() return JSON.encode({ tidyPlayermats, importTrauma, resetResources }) end function onSave()
return JSON.encode({
options = options
})
end
function onLoad(saved_data) function onLoad(savedData)
local loaded_data = JSON.decode(saved_data) if savedData ~= nil then
if loaded_data ~= nil then local loadedData = JSON.decode(savedData)
tidyPlayermats = loaded_data[1] options = loadedData.options
importTrauma = loaded_data[2] -- update UI to match saved state
resetResources = loaded_data[3] for id, state in pairs(options) do
self.UI.setAttribute(id, "image", state and "option_on" or "option_off")
end
end end
-- context menu and buttons
self.addContextMenuItem("More Information", function()
printToAll("------------------------------", "White")
printToAll("Clean Up Helper by Chr1Z", "Orange")
printToAll("ignore tag: " .. IGNORE_TAG, "White")
printToAll("Player order in the campaign log for trauma import:\nWhite, Orange, Green, Red", "White")
end)
-- index 0: button as label -- index 0: button as label
buttonParameters.label = "Clean Up Helper" buttonParameters.label = "Clean Up Helper"
buttonParameters.click_function = "none" buttonParameters.click_function = "none"
buttonParameters.position = { x = 0, y = 0.1, z = -1.525 } buttonParameters.position = { x = 0, y = 0.1, z = -1.3 }
buttonParameters.height = 0 buttonParameters.height = 0
buttonParameters.width = 0 buttonParameters.width = 0
buttonParameters.font_size = 165 buttonParameters.font_size = 230
buttonParameters.font_color = "Black" buttonParameters.font_color = Color(0, 0, 0)
self.createButton(buttonParameters) self.createButton(buttonParameters)
-- index 1: option button for playermats -- index 1: option button
buttonParameters.label = "Tidy playermats: " .. (tidyPlayermats and "✓" or "✗") buttonParameters.label = "Settings"
buttonParameters.color = { 0, 0, 0, 0.95 } buttonParameters.click_function = "showOrHideOptions"
buttonParameters.click_function = "toggle_tidyPlayermats" buttonParameters.color = { 0, 0, 0, 0.96 }
buttonParameters.position.z = buttonParameters.position.z + 0.7 buttonParameters.position.z = -0.1
buttonParameters.height = 275 buttonParameters.height = 350
buttonParameters.width = 1550 buttonParameters.width = 1000
buttonParameters.font_size = 165 buttonParameters.font_size = 190
buttonParameters.font_color = "White" buttonParameters.font_color = "White"
self.createButton(buttonParameters) self.createButton(buttonParameters)
-- index 2: option button for trauma import -- index 2: start button
buttonParameters.label = "Import trauma: " .. (importTrauma and "✓" or "✗") buttonParameters.label = "Reset play areas"
buttonParameters.click_function = "toggle_importTrauma"
buttonParameters.position.z = buttonParameters.position.z + 0.7
self.createButton(buttonParameters)
-- index 3: option button for resources
buttonParameters.label = "Reset resources: " .. (resetResources and "✓" or "✗")
buttonParameters.click_function = "toggle_resetResources"
buttonParameters.position.z = buttonParameters.position.z + 0.7
self.createButton(buttonParameters)
-- index 4: start button
buttonParameters.label = "Start!"
buttonParameters.click_function = "cleanUp" buttonParameters.click_function = "cleanUp"
buttonParameters.position.z = buttonParameters.position.z + 0.7 buttonParameters.position.z = 1.1
buttonParameters.width = 775 buttonParameters.width = 1550
self.createButton(buttonParameters) self.createButton(buttonParameters)
-- create single table for ignoring -- create single table for ignoring
for _, v in ipairs(CLUE_GUIDS) do table.insert(IGNORE_GUIDS, v) end for _, v in ipairs(CLUE_GUIDS) do table.insert(IGNORE_GUIDS, v) end
for _, v in ipairs(CLUE_CLICKER_GUIDS) do table.insert(IGNORE_GUIDS, v) end
for _, v in ipairs(RESOURCE_GUIDS) do table.insert(IGNORE_GUIDS, v) end
for _, v in ipairs(TRASHCAN_GUIDS) do table.insert(IGNORE_GUIDS, v) end for _, v in ipairs(TRASHCAN_GUIDS) do table.insert(IGNORE_GUIDS, v) end
for _, v in ipairs(PLAYERMAT_GUIDS) do table.insert(IGNORE_GUIDS, v) end for _, v in ipairs(PLAYERMAT_GUIDS) do table.insert(IGNORE_GUIDS, v) end
for _, v in ipairs(TOKEN_GUIDS) do table.insert(IGNORE_GUIDS, v) end for _, v in ipairs(DAMAGE_HORROR_GUIDS) do table.insert(IGNORE_GUIDS, v) end
end end
--------------------------------------------------------- ---------------------------------------------------------
-- click functions for option buttons -- click functions for option buttons
--------------------------------------------------------- ---------------------------------------------------------
function toggle_tidyPlayermats() -- changes the UI state and the internal variable for the togglebuttons
tidyPlayermats = not tidyPlayermats function optionButtonClick(_, id)
self.editButton({ index = 1, label = "Tidy playermats: " .. (tidyPlayermats and "✓" or "✗") }) local currentState = options[id]
local newState = (currentState and "option_off" or "option_on")
options[id] = not currentState
self.UI.setAttribute(id, "image", newState)
end end
function toggle_importTrauma() -- shows or hides the option panel
importTrauma = not importTrauma function showOrHideOptions()
self.editButton({ index = 2, label = "Import trauma: " .. (importTrauma and "✓" or "✗") }) optionsVisible = not optionsVisible
end
function toggle_resetResources() if optionsVisible then
resetResources = not resetResources self.UI.show("options")
self.editButton({ index = 3, label = "Reset resources: " .. (resetResources and "✓" or "✗") }) else
self.UI.hide("options")
end
end end
--------------------------------------------------------- ---------------------------------------------------------
@ -174,65 +166,76 @@ function cleanUp()
printToAll("Resetting counters...", "White") printToAll("Resetting counters...", "White")
getTrauma() getTrauma()
resetCounters() updateCounters(DAMAGE_HORROR_GUIDS, RESET_VALUES, "Damage / Horror")
updateCounters(RESOURCE_GUIDS, 5, "Resources")
-- bless / curse manager prints removed amounts updateCounters(CLUE_CLICKER_GUIDS, 0, "Clue clickers")
resetSkillTrackers()
resetDoomCounter()
removeBlessCurse() removeBlessCurse()
printToAll("Removing vector lines...", "White")
removeLines() removeLines()
printToAll("Discarding player hands...", "White")
discardHands() discardHands()
printToAll("Tidying big playmat...", "White") printToAll("Tidying main play area...", "White")
startLuaCoroutine(self, "tidyPlaymatCoroutine") startLuaCoroutine(self, "tidyPlayareaCoroutine")
end end
--------------------------------------------------------- ---------------------------------------------------------
-- modular functions, called by other functions -- modular functions, called by other functions
--------------------------------------------------------- ---------------------------------------------------------
-- set counters to reset values function updateCounters(tableOfGUIDs, tableOfNewValues, info)
function resetCounters() if tonumber(tableOfNewValues) then
for i, guid in ipairs(TOKEN_GUIDS) do local value = tableOfNewValues
-- skip this step for resource tokens when option disabled (token number 9-12) tableOfNewValues = {}
if resetResources or (i < 9 or i > 12) then for i = 1, #tableOfGUIDs do
local TOKEN = getObjectFromGUID(guid) table.insert(tableOfNewValues, value)
if TOKEN ~= nil then
TOKEN.call("updateVal", RESET_VALUES[i])
else
printToAll("Token number " .. i .. " could not be found and was skipped.", "Yellow")
end
end end
end end
-- reset doom on agenda for i, guid in ipairs(tableOfGUIDs) do
local doomcounter = getObjectFromGUID("85c4c6") local TOKEN = getObjectFromGUID(guid)
if doomcounter ~= nil then
doomcounter.call("updateVal", 0)
end
if TOKEN ~= nil then
TOKEN.call("updateVal", tableOfNewValues[i])
else
printToAll(info .. ": No. " .. i .. " could not be found.", "Yellow")
end
end
end
-- set investigator skill trackers to "1, 1, 1, 1"
function resetSkillTrackers()
for i, guid in ipairs(TRACKER_GUIDS) do for i, guid in ipairs(TRACKER_GUIDS) do
local obj = getObjectFromGUID(guid) local obj = getObjectFromGUID(guid)
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("Stat tracker number " .. i .. " could not be found and was skipped.", "Yellow") printToAll("Skill tracker number " .. i .. " could not be found.", "Yellow")
end end
end end
end end
-- reset doom on agenda
function resetDoomCounter()
local doomcounter = getObjectFromGUID("85c4c6")
if doomcounter ~= nil then
doomcounter.call("updateVal")
else
printToAll("Doom counter could not be found.", "Yellow")
end
end
-- read values for trauma from campaign log if enabled -- read values for trauma from campaign log if enabled
function getTrauma() function getTrauma()
-- load default values RESET_VALUES = {
RESET_VALUES = {} 0; 0; 0; 0;
for k, v in pairs(DEFAULT_VALUES) do 0; 0; 0; 0
RESET_VALUES[k] = v }
end
-- stop here if trauma import is disabled -- stop here if trauma import is disabled
if not importTrauma then if not options["importTrauma"] then
printToAll("Default values for health and sanity loaded.", "Yellow") printToAll("Default values for health and sanity loaded.", "Yellow")
return return
end end
@ -259,42 +262,51 @@ function getTrauma()
end end
end end
-- get rid of bless/curse tokens via bless / curse manager -- get rid of bless/curse tokens via bless/curse manager
function removeBlessCurse() function removeBlessCurse()
local BlessCurseManager = getObjectFromGUID("5933fb") local BlessCurseManager = getObjectFromGUID("5933fb")
if BlessCurseManager ~= nil then if BlessCurseManager ~= nil then
BlessCurseManager.call("doRemove", "White") BlessCurseManager.call("doRemove", "White")
else
printToAll("Bless / Curse manager could not be found and thus bless/curse tokens were skipped.", "Yellow")
end end
end end
-- remove drawn lines -- remove drawn lines
function removeLines() function removeLines()
Global.setVectorLines({}) if options["removeDrawnLines"] then
printToAll("Removing vector lines...", "White")
Global.setVectorLines({})
end
end end
-- discard all hand objects -- discard all hand objects
function discardHands() function discardHands()
if not options["tidyPlayermats"] then return end
for i = 1, 4 do for i = 1, 4 do
local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[i]) local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[i])
local hand = Player[COLORS[i]].getHandObjects()
if trashcan == nil then return end if trashcan == nil then return end
for j = #hand, 1, -1 do trashcan.putObject(hand[j]) end local hand = Player[COLORS[i]].getHandObjects()
for j = #hand, 1, -1 do
trashcan.putObject(hand[j])
end
end end
end end
-- clean up for big playmat -- clean up for play area
function tidyPlaymatCoroutine() function tidyPlayareaCoroutine()
local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[5]) local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[5])
local PLAYMATZONE = getObjectFromGUID("a2f932") local PLAYMATZONE = getObjectFromGUID("a2f932")
if PLAYMATZONE == nil then if PLAYMATZONE == nil then
printToAll("Scripting zone for big playmat could not be found!", "Red") printToAll("Scripting zone for main play area could not be found!", "Red")
elseif trashcan == nil then elseif trashcan == nil then
printToAll("Trashcan for big playmat could not be found!", "Red") printToAll("Trashcan for main play area could not be found!", "Red")
else else
for _, obj in ipairs(PLAYMATZONE.getObjects()) do for _, obj in ipairs(PLAYMATZONE.getObjects()) do
-- ignore these elements -- ignore these elements
if indexOf(IGNORE_GUIDS, obj.getGUID()) == nil and obj.hasTag(IGNORE_TAG) == false then if not tableContains(IGNORE_GUIDS, obj.getGUID()) and obj.hasTag(IGNORE_TAG) == false then
coroutine.yield(0) coroutine.yield(0)
trashcan.putObject(obj) trashcan.putObject(obj)
end end
@ -311,8 +323,8 @@ end
-- clean up for the four playermats and the agenda/act playmat -- clean up for the four playermats and the agenda/act playmat
function tidyPlayerMatCoroutine() function tidyPlayerMatCoroutine()
for i = 1, 5 do for i = 1, 5 do
-- skip playermat (1-4) if option disabled -- only continue for playermat (1-4) if option enabled
if tidyPlayermats or i == 5 then if options["tidyPlayermats"] or i == 5 then
-- delay for animation purpose -- delay for animation purpose
for k = 1, 30 do coroutine.yield(0) end for k = 1, 30 do coroutine.yield(0) end
@ -328,7 +340,7 @@ function tidyPlayerMatCoroutine()
local desc_low = string.lower(obj.getDescription()) local desc_low = string.lower(obj.getDescription())
-- ignore these elements -- ignore these elements
if indexOf(IGNORE_GUIDS, obj.getGUID()) == nil and obj.hasTag(IGNORE_TAG) == false and if not tableContains(IGNORE_GUIDS, obj.getGUID()) and obj.hasTag(IGNORE_TAG) == false and
desc_low ~= "chaos bag" and desc_low ~= "action token" then desc_low ~= "chaos bag" and desc_low ~= "action token" then
coroutine.yield(0) coroutine.yield(0)
trashcan.putObject(obj) trashcan.putObject(obj)
@ -375,11 +387,12 @@ function findObjects(num)
}) })
end end
-- helper to search array -- search a table for a value, return true if found (else returns false)
function indexOf(array, value) function tableContains(table, value)
for i, v in ipairs(array) do for _, v in ipairs(table) do
if v == value then if v == value then
return i return true
end end
end end
return false
end end

View File

@ -0,0 +1,70 @@
<!-- Default formatting -->
<Defaults>
<Text color="black" alignment="MiddleLeft"/>
<Text class="h1" fontSize="115" font="font_teutonic-arkham"/>
<Text class="h2" fontSize="80" font="font_teutonic-arkham"/>
<Text class="p" fontSize="40" alignment="UpperLeft"/>
<Panel rotation="0 0 180"/>
<Panel class="window" width="1000" height="1000" color="black" outline="white" outlineSize="8 8"/>
<Row dontUseTableRowBackground="true"/>
<Row class="header" color="#707070"/>
<Row class="option" preferredHeight="130" color="#9e9e9e"/>
<!-- heights: 45 x lines + 40 -->
<Row class="description" color="#cfcfcf"/>
<Button class="optionToggle" rectAlignment="MiddleRight" offsetXY="-20 0" colors="#FFFFFF|#dfdfdf" height="108" width="225" ignoreLayout="True" fontSize="60"/>
</Defaults>
<!-- Option window -->
<Panel id="options" class="window" offsetXY="-460 0" scale="0.5 0.5" active="false" showAnimation="FadeIn" hideAnimation="FadeOut">
<TableLayout cellPadding="15 15 5 5">
<!-- Header -->
<Row class="header">
<Cell>
<Text class="h1">Clean up Helper - Options</Text>
</Cell>
</Row>
<!-- Option -->
<Row class="option">
<Cell>
<Text class="h2">Import trauma</Text>
<Button id="importTrauma" onClick="optionButtonClick(importTrauma)" class="optionToggle" image="option_on"/>
</Cell>
</Row>
<Row class="description" preferredHeight="220">
<Cell>
<Text class="p">Controls whether trauma values should be imported from the campaign log (if possible).&#xA;Enter players in the campaign log in this order:&#xA;White, Orange, Green, Red.</Text>
</Cell>
</Row>
<!-- Option -->
<Row class="option">
<Cell>
<Text class="h2">Tidy playermats</Text>
<Button id="tidyPlayermats" onClick="optionButtonClick(tidyPlayermats)" class="optionToggle" image="option_on"/>
</Cell>
</Row>
<Row class="description" preferredHeight="130">
<Cell>
<Text class="p">Controls whether the playermats should get tidied (removal of all cards and tokens).</Text>
</Cell>
</Row>
<!-- Option -->
<Row class="option">
<Cell>
<Text class="h2">Remove drawn lines</Text>
<Button id="removeDrawnLines" onClick="optionButtonClick(removeDrawnLines)" class="optionToggle" image="option_off"/>
</Cell>
</Row>
<Row class="description" preferredHeight="85">
<Cell>
<Text class="p">Controls whether all drawn lines should be removed.</Text>
</Cell>
</Row>
</TableLayout>
</Panel>