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,23 +30,20 @@ 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
}
-- GUIDS of objects (in order of ownership relating to 'COLORS')
local PLAYERMAT_GUIDS = { "8b081b"; "bd0ff4"; "383d8b"; "0840d5" } local PLAYERMAT_GUIDS = { "8b081b"; "bd0ff4"; "383d8b"; "0840d5" }
local RESOURCE_GUIDS = { "4406f0"; "816d84"; "cd15ac"; "a4b60d" }
local TRACKER_GUIDS = { "e598c2"; "b4a5f7"; "af7ed7"; "e74881" } local TRACKER_GUIDS = { "e598c2"; "b4a5f7"; "af7ed7"; "e74881" }
local CLUE_GUIDS = { "d86b7c"; "1769ed"; "032300"; "37be78" } local CLUE_GUIDS = { "d86b7c"; "1769ed"; "032300"; "37be78" }
local CLUE_CLICKER_GUIDS = { "db85d6"; "3f22e5"; "891403"; "4111de" }
local TRASHCAN_GUIDS = { "147e80"; "f7b6c8"; "5f896a"; "4b8594"; "70b9f6" } 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)
@ -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({
function onLoad(saved_data) options = options
local loaded_data = JSON.decode(saved_data) })
if loaded_data ~= nil then
tidyPlayermats = loaded_data[1]
importTrauma = loaded_data[2]
resetResources = loaded_data[3]
end end
-- context menu and buttons function onLoad(savedData)
self.addContextMenuItem("More Information", function() if savedData ~= nil then
printToAll("------------------------------", "White") local loadedData = JSON.decode(savedData)
printToAll("Clean Up Helper by Chr1Z", "Orange") options = loadedData.options
printToAll("ignore tag: " .. IGNORE_TAG, "White") -- update UI to match saved state
printToAll("Player order in the campaign log for trauma import:\nWhite, Orange, Green, Red", "White") for id, state in pairs(options) do
end) self.UI.setAttribute(id, "image", state and "option_on" or "option_off")
end
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
table.insert(tableOfNewValues, value)
end
end
for i, guid in ipairs(tableOfGUIDs) do
local TOKEN = getObjectFromGUID(guid) local TOKEN = getObjectFromGUID(guid)
if TOKEN ~= nil then if TOKEN ~= nil then
TOKEN.call("updateVal", RESET_VALUES[i]) TOKEN.call("updateVal", tableOfNewValues[i])
else else
printToAll("Token number " .. i .. " could not be found and was skipped.", "Yellow") 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
local obj = getObjectFromGUID(guid)
if obj ~= nil then
obj.call("updateStats", { 1, 1, 1, 1 })
else
printToAll("Skill tracker number " .. i .. " could not be found.", "Yellow")
end end
end end
end end
-- reset doom on agenda -- reset doom on agenda
function resetDoomCounter()
local doomcounter = getObjectFromGUID("85c4c6") local doomcounter = getObjectFromGUID("85c4c6")
if doomcounter ~= nil then
doomcounter.call("updateVal", 0)
end
for i, guid in ipairs(TRACKER_GUIDS) do if doomcounter ~= nil then
local obj = getObjectFromGUID(guid) doomcounter.call("updateVal")
if obj ~= nil then
obj.call("updateStats", { 1, 1, 1, 1 })
else else
printToAll("Stat tracker number " .. i .. " could not be found and was skipped.", "Yellow") printToAll("Doom counter could not be found.", "Yellow")
end
end end
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
@ -262,39 +265,48 @@ 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()
if options["removeDrawnLines"] then
printToAll("Removing vector lines...", "White")
Global.setVectorLines({}) 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>