SCED/objects/Fan-MadeAccessories.aa8b38/CleanUpHelper.26cf4b.ttslua
Buhallin db65f3c8e3
Add PlayArea API
Creates an API object for the PlayArea, and moves most references to the PlayArea to use the API instead.

Image swapper is excluded on this, as I'm not completely sure how TTS will handle having an object rebuild itself.
2022-12-12 18:56:04 -08:00

387 lines
12 KiB
Plaintext

-- Clean Up Helper
-- made by: Chr1Z
-- 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
-- - puts everything on playmats and hands into respective trashcans
-- - use the IGNORE_TAG to exclude objects from tidying (default: "CleanUpHelper_Ignore")
local playAreaApi = require("core/PlayAreaApi")
-- enable this for debugging
local SHOW_RAYS = false
-- these objects will be ignored
local IGNORE_GUIDS = {
-- big playmat, change image panel and investigator counter
"b7b45b"; "f182ee"; "721ba2";
-- bless/curse manager
"afa06b"; "bd0253"; "5933fb";
-- stuff on agenda/act playmat
"85c4c6"; "4a3aa4"; "fea079"; "b015d8"; "11e0cf"; "9f334f"; "70b9f6"; "0a5a29";
-- doom/location token bag
"47ffc3"; "170f10";
-- table
"4ee1f2"
}
-- objects with this tag will be ignored
local IGNORE_TAG = "CleanUpHelper_ignore"
-- colors and order for following tables
local COLORS = { "White"; "Orange"; "Green"; "Red"; "Agenda" }
-- counter GUIDS (4x damage, 4x sanity and 4x resource)
local TOKEN_GUIDS = {
"eb08d6"; "e64eec"; "1f5a0a"; "591a45";
"468e88"; "0257d9"; "7b5729"; "beb964";
"4406f0"; "816d84"; "cd15ac"; "a4b60d"
}
-- default values (4x damage, 4x horror, 4x resources)
local DEFAULT_VALUES = {
0; 0; 0; 0;
0; 0; 0; 0;
5; 5; 5; 5
}
local PLAYERMAT_GUIDS = { "8b081b"; "bd0ff4"; "383d8b"; "0840d5" }
local TRACKER_GUIDS = { "e598c2"; "b4a5f7"; "af7ed7"; "e74881" }
local CLUE_GUIDS = { "d86b7c"; "1769ed"; "032300"; "37be78" }
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)
local PHYSICS_POSITION = {
{ -54.5, 2, 21 };
{ -54.5, 2, -21 };
{ -25.0, 2, 26 };
{ -25.0, 2, -26 };
{ -02.0, 2, 10 };
{ -00.0, 2, -27 }
}
local PHYSICS_ROTATION = { 270, 270, 0, 180, 270, 0 }
local PHYSICS_SCALE = {
{ 36.6, 1, 14.5 };
{ 36.6, 1, 14.5 };
{ 28.0, 1, 14.5 };
{ 28.0, 1, 14.5 };
{ 55.0, 1, 13.5 };
{ 05.0, 1, 05.0 }
}
local tidyPlayermats = true
local importTrauma = true
local resetResources = true
local buttonParameters = {}
buttonParameters.function_owner = self
---------------------------------------------------------
-- option loading and GUI setup
---------------------------------------------------------
function onSave() return JSON.encode({ tidyPlayermats, importTrauma, resetResources }) end
function onLoad(saved_data)
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
-- 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
buttonParameters.label = "Clean Up Helper"
buttonParameters.click_function = "none"
buttonParameters.position = { x = 0, y = 0.1, z = -1.525 }
buttonParameters.height = 0
buttonParameters.width = 0
buttonParameters.font_size = 165
buttonParameters.font_color = "Black"
self.createButton(buttonParameters)
-- index 1: option button for playermats
buttonParameters.label = "Tidy playermats: " .. (tidyPlayermats and "✓" or "✗")
buttonParameters.color = { 0, 0, 0, 0.95 }
buttonParameters.click_function = "toggle_tidyPlayermats"
buttonParameters.position.z = buttonParameters.position.z + 0.7
buttonParameters.height = 275
buttonParameters.width = 1550
buttonParameters.font_size = 165
buttonParameters.font_color = "White"
self.createButton(buttonParameters)
-- index 2: option button for trauma import
buttonParameters.label = "Import trauma: " .. (importTrauma and "✓" or "✗")
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.position.z = buttonParameters.position.z + 0.7
buttonParameters.width = 775
self.createButton(buttonParameters)
-- create single table for ignoring
for _, v in ipairs(CLUE_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(TOKEN_GUIDS) do table.insert(IGNORE_GUIDS, v) end
end
---------------------------------------------------------
-- click functions for option buttons
---------------------------------------------------------
function toggle_tidyPlayermats()
tidyPlayermats = not tidyPlayermats
self.editButton({ index = 1, label = "Tidy playermats: " .. (tidyPlayermats and "✓" or "✗") })
end
function toggle_importTrauma()
importTrauma = not importTrauma
self.editButton({ index = 2, label = "Import trauma: " .. (importTrauma and "✓" or "✗") })
end
function toggle_resetResources()
resetResources = not resetResources
self.editButton({ index = 3, label = "Reset resources: " .. (resetResources and "✓" or "✗") })
end
---------------------------------------------------------
-- main function
---------------------------------------------------------
function cleanUp()
printToAll("------------------------------", "White")
printToAll("Clean up started!", "Orange")
printToAll("Resetting counters...", "White")
getTrauma()
resetCounters()
-- bless / curse manager prints removed amounts
removeBlessCurse()
printToAll("Removing vector lines...", "White")
removeLines()
printToAll("Discarding player hands...", "White")
discardHands()
printToAll("Tidying big playmat...", "White")
startLuaCoroutine(self, "tidyPlaymatCoroutine")
end
---------------------------------------------------------
-- modular functions, called by other functions
---------------------------------------------------------
-- set counters to reset values
function resetCounters()
for i, guid in ipairs(TOKEN_GUIDS) do
-- skip this step for resource tokens when option disabled (token number 9-12)
if resetResources or (i < 9 or i > 12) then
local TOKEN = getObjectFromGUID(guid)
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
-- reset doom on agenda
-- local doomcounter = getObjectFromGUID("85c4c6")
-- if doomcounter ~= nil then
-- doomcounter.call("setToZero")
-- end
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("Stat tracker number " .. i .. " could not be found and was skipped.", "Yellow")
end
end
end
-- read values for trauma from campaign log if enabled
function getTrauma()
-- load default values
RESET_VALUES = {}
for k, v in pairs(DEFAULT_VALUES) do
RESET_VALUES[k] = v
end
-- stop here if trauma import is disabled
if not importTrauma then
printToAll("Default values for health and sanity loaded.", "Yellow")
return
end
-- get campaign log
local campaignLog = findObjects(6)[1]
if campaignLog == nil then
printToAll("Campaign log not found in standard position!", "Yellow")
printToAll("Default values for health and sanity loaded.", "Yellow")
return
end
-- get data from campaign log if possible
local counterData = campaignLog.hit_object.getVar("ref_buttonData")
if counterData ~= nil then
printToAll("Trauma values found in campaign log!", "Green")
for i = 1, 10, 3 do
RESET_VALUES[1 + (i - 1) / 3] = counterData.counter[i].value
RESET_VALUES[5 + (i - 1) / 3] = counterData.counter[i + 1].value
end
else
printToAll("Trauma values could not be found in campaign log!", "Yellow")
printToAll("Default values for health and sanity loaded.", "Yellow")
end
end
-- get rid of bless/curse tokens via bless / curse manager
function removeBlessCurse()
local BlessCurseManager = getObjectFromGUID("5933fb")
if BlessCurseManager ~= nil then
BlessCurseManager.call("doRemove", "White")
end
end
-- remove drawn lines
function removeLines()
Global.setVectorLines({})
end
-- discard all hand objects
function discardHands()
for i = 1, 4 do
local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[i])
local hand = Player[COLORS[i]].getHandObjects()
if trashcan == nil then return end
for j = #hand, 1, -1 do trashcan.putObject(hand[j]) end
end
end
-- clean up for big playmat
function tidyPlaymatCoroutine()
local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[5])
local PLAYMATZONE = getObjectFromGUID("a2f932")
if PLAYMATZONE == nil then
printToAll("Scripting zone for big playmat could not be found!", "Red")
elseif trashcan == nil then
printToAll("Trashcan for big playmat could not be found!", "Red")
else
for _, obj in ipairs(PLAYMATZONE.getObjects()) do
-- ignore these elements
if indexOf(IGNORE_GUIDS, obj.getGUID()) == nil and obj.hasTag(IGNORE_TAG) == false then
coroutine.yield(0)
trashcan.putObject(obj)
end
end
end
playAreaApi.resetSpawnedCards()
printToAll("Tidying playermats and agenda mat...", "White")
startLuaCoroutine(self, "tidyPlayerMatCoroutine")
return 1
end
-- clean up for the four playermats and the agenda/act playmat
function tidyPlayerMatCoroutine()
for i = 1, 5 do
-- skip playermat (1-4) if option disabled
if tidyPlayermats or i == 5 then
-- delay for animation purpose
for k = 1, 30 do coroutine.yield(0) end
-- get respective trashcan
local trashcan = getObjectFromGUID(TRASHCAN_GUIDS[i])
if trashcan == nil then
printToAll("Trashcan for " .. COLORS[i] .. " playmat could not be found!", "Red")
return
end
for _, entry in ipairs(findObjects(i)) do
local obj = entry.hit_object
local desc_low = string.lower(obj.getDescription())
-- ignore these elements
if indexOf(IGNORE_GUIDS, obj.getGUID()) == nil and obj.hasTag(IGNORE_TAG) == false and
desc_low ~= "chaos bag" and desc_low ~= "action token" then
coroutine.yield(0)
trashcan.putObject(obj)
-- flip action tokens back to ready
elseif desc_low == "action token" and obj.is_face_down then
obj.flip()
end
end
-- reset "activeInvestigatorId"
if i < 5 then
local playermat = getObjectFromGUID(PLAYERMAT_GUIDS[i])
if playermat then
playermat.setVar("activeInvestigatorId", "00000")
end
end
end
end
local datahelper = getObjectFromGUID("708279")
if datahelper then
datahelper.setTable("SPAWNED_PLAYER_CARD_GUIDS", {})
end
printToAll("Clean up completed!", "Green")
return 1
end
---------------------------------------------------------
-- helper functions
---------------------------------------------------------
-- find objects depending on index (1 to 4 for playermats, 5 for agenda/act playmat, 6 for campaign log)
function findObjects(num)
return Physics.cast({
direction = { 0, 1, 0 },
max_distance = 1,
type = 3,
size = PHYSICS_SCALE[num],
origin = PHYSICS_POSITION[num],
orientation = { 0, PHYSICS_ROTATION[num], 0 },
debug = SHOW_RAYS
})
end
-- helper to search array
function indexOf(array, value)
for i, v in ipairs(array) do
if v == value then
return i
end
end
end