Merge pull request #207 from argonui/legacy-tool-cleanup

"Hidden Zone" tool cleanup
This commit is contained in:
Chr1Z 2023-02-05 02:24:21 +01:00 committed by GitHub
commit 2f4e5be13a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 90 additions and 1445 deletions

View File

@ -112,13 +112,11 @@
"Blesstokens.afa06b",
"Cursetokens.bd0253",
"TokenRemover.0a5a29",
"TokenSpawner.36b4ee",
"TokenSpawnTool.36b4ee",
"OfficialStandaloneChallengeScenarios.0ef5c8",
"TarotDeck.77f1e5",
"TarotDeckScripted.a230f9",
"Fan-MadeAccessories.aa8b38",
"UIBuilder.ddd2eb",
"CommandManager.a0b1de",
"CoreNightoftheZealot.64a613",
"TheDunwichLegacy.2898f6",
"ThePathtoCarcosa.aca04c",

View File

@ -1546,8 +1546,8 @@
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 77.886,
"posY": 1.043,
"posX": 78,
"posY": 0.96,
"posZ": 27.031,
"rotX": 0,
"rotY": 0,

View File

@ -33,8 +33,8 @@
],
"Tooltip": true,
"Transform": {
"posX": 77.159,
"posY": 1.297,
"posX": 78,
"posY": 1.208,
"posZ": 6.315,
"rotX": 0,
"rotY": 270,

View File

@ -1,45 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 0,
"g": 0,
"r": 0
},
"Description": "",
"DragSelectable": true,
"GMNotes": "",
"GUID": "a0b1de",
"Grid": true,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScriptState": "",
"LuaScript_path": "CommandManager.a0b1de.ttslua",
"MeasureMovement": false,
"Name": "Checker_black",
"Nickname": "Command Manager",
"Snap": true,
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 77.06,
"posY": 1.296,
"posZ": 9.378,
"rotX": 0,
"rotY": 270,
"rotZ": 180,
"scaleX": 0.25,
"scaleY": 0.25,
"scaleZ": 0.25
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,287 +0,0 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by Whimsical.
--- DateTime: 2021-08-22 6:36 a.m.
---
---@class CommandTableEntry
---@field public object TTSObject
---@field public runOn ArkhamImport_Command_RunDirectives
local CommandTableEntry = {}
---@type table<string, CommandTableEntry>
local commands = {}
---@type table<string, boolean>
local found_commands = {}
---@type table<string, any>
local command_state
local function load_commands()
local command_objects = getObjectsWithTag("import_command")
for _, object in ipairs(command_objects) do
commands[object:getVar("command_name")] = {
object = object,
runOn = object:getTable("runOn")
}
end
end
---@param configuration ArkhamImportConfiguration
---@param message string
---@return ArkhamImport_CommandManager_InitializationResults
local function build_error(configuration, message)
return {
configuration = configuration,
is_successful = false,
error_message = message
}
end
---@param source table<any, any>
---@param updates table<any, any>
local function merge_tables(source, updates)
for key, _ in pairs(source) do
local update = updates[key]
if update~=nil then
source[key] = update
end
end
end
---@param instruction TTSObject
---@param initialization_state any
---@param arguments string[]
---@return ArkhamImport_CommandManager_InitializationResults|nil
local function run_instruction(instruction, initialization_state, arguments)
---@type ArkhamImport_Command_DescriptionInstructionResults
local result = instruction:call("do_instruction", {
configuration = initialization_state.configuration,
command_state = initialization_state.command_state,
arguments = arguments
})
if (not result) or type(result)~="table" then
return build_error(initialization_state.configuration, table.concat({"Command \"", instruction:getName(), "\" did not return a table from do_instruction call. Type \"", type(result), "\" was returned."}))
end
if not result.is_successful then
return build_error(result.configuration, result.error_message)
end
merge_tables(initialization_state, result)
end
---@param description string
---@param initialization_state table<string, any>
---@return ArkhamImport_CommandManager_InitializationResults|nil
local function initialize_instructions(description, initialization_state)
for _, instruction in ipairs(parse(description)) do
local command = commands[instruction.command]
if command==nil then
return build_error(initialization_state.configuration, table.concat({ "Could not find command \"", command, "\"."}))
end
found_commands[instruction.command] = true
if command.runOn.instructions then
local error = run_instruction(command.object, initialization_state, instruction.arguments)
if error then return error end
end
end
end
---@param parameters ArkhamImport_CommandManager_InitializationArguments
---@return table<string, any>
local function create_initialize_state(parameters)
return {
configuration = parameters.configuration,
command_state = {}
}
end
---@param parameters ArkhamImport_CommandManager_InitializationArguments
---@return ArkhamImport_CommandManager_InitializationResults
function initialize(parameters)
found_commands = {}
load_commands()
local initialization_state = create_initialize_state(parameters)
local error = initialize_instructions(parameters.description, initialization_state)
if error then return error end
command_state = initialization_state.command_state
return {
configuration = initialization_state.configuration,
is_successful = true
}
end
---@param parameters ArkhamImport_CommandManager_HandlerArguments
---@return table<string, any>
local function create_handler_state(parameters)
return {
card = parameters.card,
handled = false,
zone = parameters.zone,
command_state = command_state
},
{
configuration = parameters.configuration,
source_guid = parameters.source_guid
}
end
---@param card ArkhamImportCard
---@param zone = string[]
---@param handled boolean
---@param error_message string
---@return ArkhamImport_CommandManager_HandlerResults
local function create_handler_error(card, zone, handled, error_message)
return {
handled = handled,
card = card,
zone = zone,
is_successful = false,
error_message = error_message
}
end
---@param handler TTSObject
---@param handler_state table<string, any>
---@param handler_constants table<string, any>
---@return ArkhamImport_CommandManager_HandlerResults|nil
local function call_handler(handler, handler_state, handler_constants)
---@type ArkhamImport_CommandManager_HandlerResults
local results = handler:call("handle_card", {
configuration = handler_constants.configuration,
source_guid = handler_constants.source_guid,
card = handler_state.card,
zone = handler_state.zone,
command_state = handler_state.command_state,
})
if not results.is_successful then return create_handler_error(results.card, results.zone, results.handled, results.error_message) end
merge_tables(handler_state, results)
command_state = handler_state.command_state
end
---@param handler_state table<string, any>
---@param handler_constants table<string, any>
---@return ArkhamImport_CommandManager_HandlerResults|nil
local function run_handlers(handler_state, handler_constants)
for command_name, _ in pairs(found_commands) do
local command = commands[command_name]
if command.runOn.handlers then
local error = call_handler(command.object, handler_state, handler_constants)
if error then return error end
if (handler_state.handled) then return end
end
end
end
---@param parameters ArkhamImport_CommandManager_HandlerArguments
---@return ArkhamImport_CommandManager_HandlerResults
function handle(parameters)
local handler_state, handler_constants = create_handler_state(parameters)
local error = run_handlers(handler_state, handler_constants)
if error then return error end
return {
handled = handler_state.handled,
card = handler_state.card,
zone = handler_state.zone,
is_successful = true
}
end
---@param description string
---@return ArkhamImportCommandParserResult[]
function parse(description)
local input = description
if #input<=4 then return {} end
---@type string
local current, l1, l2, l3 = "", "", "", ""
local concat = table.concat
local function advance()
current, l1, l2, l3 = l1, l2, l3, input:sub(1,1)
input = input:sub(2)
end
local function advance_all()
current, l1, l2, l3 = input:sub(1,1), input:sub(2,2), input:sub(3,3), input:sub(4,4)
input = input:sub(5)
end
advance_all()
---@type ArkhamImportCommandParserResult[]
local results = {}
---@type string
local command
---@type string[]
local arguments = {}
---@type string
local separator
---@type string[]
local result = {}
while #current>0 do
if current=="<" and l1=="?" and l2 == "?" then
command = nil
arguments = {}
separator = l3
result = {}
advance_all()
elseif current == "?" and l1 == "?" and l2 == ">" then
if not command then
table.insert(results, {
command = concat(result),
arguments = {}
})
else
table.insert(arguments, concat(result))
table.insert(results, {
command = command,
arguments = arguments
})
end
separator = nil
current, l1, l2, l3 = l3, input:sub(1,1), input:sub(2,2), input:sub(3,3)
input = input:sub(4)
elseif current == separator then
if not command then
command = concat(result)
else
table.insert(arguments, concat(result))
end
result = {}
advance()
else
if separator~=nil then
table.insert(result, current)
end
advance()
end
end
return results
end

View File

@ -33,8 +33,8 @@
],
"Tooltip": true,
"Transform": {
"posX": 77.464,
"posY": 1.485,
"posX": 78,
"posY": 1.395,
"posZ": 4.352,
"rotX": 0,
"rotY": 270,

View File

@ -42,8 +42,8 @@
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 77.159,
"posY": 1.284,
"posX": 78,
"posY": 1.195,
"posZ": 7.589,
"rotX": 0,
"rotY": 270,

View File

@ -17,11 +17,8 @@
"Toggle-ableResourcetokens.272489",
"Pre-ErrataCampaignGuides.676d75",
"Pre-ErrataCards.8fa254",
"TokenArranger.4825a7",
"AttachmentFacedownHelper.3da8b6",
"GuardDog2.66c1cb",
"Flashlight3.ecd43e",
"DeckImporter-Commands.2e59f6"
"Flashlight3.ecd43e"
],
"ContainedObjects_path": "LegacyAssets.7165a9",
"CustomMesh": {

File diff suppressed because one or more lines are too long

View File

@ -1,34 +0,0 @@
function onload(saved_data)
generateText()
end
function generateText()
local text = 'Attachment/\nFacedown\nHelper'
self.createButton({
label = text,
click_function = 'nothing',
function_owner = self,
position = {0,0,-1.15},
width = 0,
height = 0,
font_size = 175,
font_color = {1,1,1}
})
text = 'State 1: Sefina Rousseau\n\nState 2: Diana Stanley\n\nState 3: Gloria Goldberg\n\nState 4: Crystallizer of Dreams\n\nState 5: Ancestral Knowledge\n\nState 6: Astronomical Atlas'
self.createButton({
label = text,
click_function = 'nothing',
function_owner = self,
position = {0,0,0.5},
width = 0,
height = 0,
font_size = 75,
font_color = {1,1,1}
})
end
function nothing()
end

View File

@ -1,59 +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": [
"IncludeCommand.f4b112",
"ProxyCardCommand.400e1a",
"MoveCommand.0b55d8",
"ZoneCommand.ec5b5f",
"ProxyInvestigatorCommand.80eac7",
"DeckImporterReferenceGuide.cb2ce4"
],
"ContainedObjects_path": "DeckImporter-Commands.2e59f6",
"Description": "",
"DragSelectable": true,
"GMNotes": "",
"GUID": "2e59f6",
"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": "Deck Importer - Commands",
"Snap": true,
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 29.214,
"posY": 4.036,
"posZ": -36.222,
"rotX": 0,
"rotY": 0,
"rotZ": 0,
"scaleX": 1,
"scaleY": 1,
"scaleZ": 1
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,45 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"Description": "",
"DragSelectable": true,
"GMNotes": "",
"GUID": "4825a7",
"Grid": true,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": false,
"LuaScriptState_path": "LegacyAssets.7165a9/TokenArranger.4825a7.luascriptstate",
"LuaScript_path": "LegacyAssets.7165a9/TokenArranger.4825a7.ttslua",
"MeasureMovement": false,
"Name": "Checker_white",
"Nickname": "Token Arranger",
"Snap": true,
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 28.631,
"posY": 4.219,
"posZ": -34.888,
"rotX": 0,
"rotY": 90,
"rotZ": 0,
"scaleX": 1,
"scaleY": 1,
"scaleZ": 1
},
"Value": 0,
"XmlUI_path": "LegacyAssets.7165a9/TokenArranger.4825a7.xml"
}

View File

@ -1 +0,0 @@
{"auto_update":"True","tokens":{"autofail":"-100","bless":"-105","cultist":"0","curse":"-106","elder_sign":"100","elder_thing":"0","frost":"-107","skull":"0","tablet":"0","unnamed":"0"},"tracking":[]}

View File

@ -1,249 +0,0 @@
---
--- Generated by Luanalysis
--- Created by Whimsical.
--- DateTime: 2021-12-19 5:00 p.m.
---
---@type table<string, string>
local token_ids = {
elder_sign = "Elder Sign",
skull = "Skull",
cultist = "Cultist",
tablet = "Tablet",
elder_thing = "Elder Thing",
autofail = "Auto-fail",
bless = "Bless",
curse = "Curse",
frost = "Frost",
unnamed = ""
}
---@type table<string, string>
local name_ids = {
["Elder Sign"] = "elder_sign",
["Skull"] = "skull",
["Cultist"] = "cultist",
["Tablet"] = "tablet",
["Elder Thing"] = "elder_thing",
["Auto-fail"] = "autofail",
["Bless"] = "bless",
["Curse"] = "curse",
["Frost"] = "frost",
[""] = "unnamed"
}
---@type Vector
local rotation = {0, 270.00, 0}
---@type table<string, number>
local offsets = {
x = -2,
z = -2
}
local left_right = "z"
local up_down = "x"
local vertical = "y"
---@type TTSObject[]
local tracking = {}
function onload(data)
data = JSON.decode(data)
if data then
local existing = data.tracking
if existing then
for _, guid in ipairs(existing) do
local object = getObjectFromGUID(guid)
if object then
table.insert(tracking, object)
end
end
end
if data.tokens then
Wait.frames(function ()
for token, value in pairs(data.tokens) do
revalue(nil, value, token)
end
end, 3)
end
Wait.frames(function ()
if data.auto_update then
self.UI:setAttribute("auto_update", "isOn", data.auto_update)
updateToggle(nil, data.auto_update, "auto_update")
end
end, 3)
end
self:addContextMenuItem("Clear", function ()
tracking = {}
end, false)
end
function onSave()
local targets = {}
for _, token in ipairs(tracking) do
table.insert(targets, token:getGUID())
end
local tokens = {}
for id, _ in pairs(token_ids) do
tokens[id] = self.UI:getValue(id)
end
return JSON.encode({
tracking = targets,
tokens = tokens,
auto_update = self.UI:getAttribute("auto_update", "isOn")
})
end
---@param player Player
---@param value string
---@param token string
function revalue(player, value, token)
if not tonumber(value) then value = 0 end
self.UI:setValue(token, value)
self.UI:setAttribute(token, "text", value)
if player then -- player is nil when we call this in onload
-- False since "on" looks greyed out
if self.UI:getAttribute("auto_update", "isOn"):lower()=="false" then
Wait.frames(function()
layout()
end, 3)
end
end
end
---@param player Player
---@param token string
function inc(player, token)
local value = tonumber(self.UI:getValue(token)) or 0
revalue(player, value+1, token)
end
---@param player Player
---@param token string
function dec(player, token)
local value = tonumber(self.UI:getValue(token)) or 0
revalue(player, value-1, token)
end
---@param player Player
---@param value string
---@param id string
function updateToggle(player, value, id)
local value = value:lower() == "true" and true or false
self.UI:setAttribute(id, "isOn", value)
if player then
broadcastToAll("Token Arranger: Auto-Update " .. (value and "Disabled" or "Enabled"))
end
end
---@return TTSObject
local function get_chaos_bag()
return getObjectsWithTag("chaosBag")[1]
end
---@type table<string, number>
local token_precedence = {
["Skull"] = -1,
["Cultist"] = -2,
["Tablet"] = -3,
["Elder Thing"] = -4,
["Elder Sign"] = 100,
["Auto-fail"] = -100,
["Bless"] = -1,
["Curse"] = -2,
["Frost"] = -3,
[""] = -1000,
}
local function token_value_comparator(left, right)
if left.value>right.value then return true
elseif right.value>left.value then return false
elseif left.precedence>right.precedence then return true
elseif right.precedence>left.precedence then return false
else return left.token:getGUID() > right.token:getGUID()
end
end
local function do_position()
local data = {}
for index, token in ipairs(tracking) do
local name = token:getName()
data[index] = {
token= token,
value = tonumber(name) or tonumber(self.UI:getValue(name_ids[name])),
precedence = token_precedence[name] or 0
}
end
table.sort(data, token_value_comparator)
local pos = self:getPosition()
local location = {}
pos[left_right] = pos[left_right] + offsets[left_right]
location[left_right] = pos[left_right]
location[up_down] = pos[up_down]
location[vertical] = pos[vertical]
local current_value = data[1].value
for _, item in ipairs(data) do
---@type TTSObject
local token = item.token
---@type number
local value = item.value
if value~=current_value then
location[left_right] = pos[left_right]
location[up_down] = location[up_down] + offsets[up_down]
current_value = value
end
token:setPosition(location)
token:setRotation(rotation)
location[left_right] = location[left_right] + offsets[left_right]
end
end
function layout()
for _, token in ipairs(tracking) do
token:destruct()
end
tracking = {}
local chaosBag = get_chaos_bag()
local size = #chaosBag:getObjects()
for _, data in ipairs(chaosBag:getObjects()) do
chaosBag:takeObject {
guid = data.guid,
smooth = false,
---@param tok TTSObject
callback_function = function (tok)
local clone = tok:clone()
Wait.frames(function() chaosBag:putObject(clone) end, 1)
table.insert(tracking, tok)
end
}
end
Wait.condition(function () do_position() end, function () return size==#tracking end)
end

View File

@ -1,53 +0,0 @@
<Text alignment="MiddleRight" width="100" height="30" color="#FFFFFF" outline="#000000" position="-140 -100 -5" text="Elder Sign" />
<InputField id="elder_sign" onEndEdit="revalue" width="120" height="30" color="#FFFFFF" position="-20 -100 -5" characterValidation="Integer">100</InputField>
<Button onClick="inc(elder_sign)" width="30" height="30" color="#FFFFFF" position="60 -100 -5" text="+" />
<Button onClick="dec(elder_sign)" width="30" height="30" color="#FFFFFF" position="95 -100 -5" text="-" />
<Text alignment="MiddleRight" width="100" height="30" color="#FFFFFF" outline="#000000" position="-140 -135 -5" text="Skull" />
<InputField id="skull" onEndEdit="revalue" width="120" height="30" color="#FFFFFF" position="-20 -135 -5" characterValidation="Integer">0</InputField>
<Button onClick="inc(skull)" width="30" height="30" color="#FFFFFF" position="60 -135 -5" text="+" />
<Button onClick="dec(skull)" width="30" height="30" color="#FFFFFF" position="95 -135 -5" text="-" />
<Text alignment="MiddleRight" width="100" height="30" color="#FFFFFF" outline="#000000" position="-140 -170 -5" text="Cultist" />
<InputField id="cultist" onEndEdit="revalue" width="120" height="30" color="#FFFFFF" position="-20 -170 -5" characterValidation="Integer">0</InputField>
<Button onClick="inc(cultist)" width="30" height="30" color="#FFFFFF" position="60 -170 -5" text="+" />
<Button onClick="dec(cultist)" width="30" height="30" color="#FFFFFF" position="95 -170 -5" text="-" />
<Text alignment="MiddleRight" width="100" height="30" color="#FFFFFF" outline="#000000" position="-140 -205 -5" text="Tablet" />
<InputField id="tablet" onEndEdit="revalue" width="120" height="30" color="#FFFFFF" position="-20 -205 -5" characterValidation="Integer">0</InputField>
<Button onClick="inc(tablet)" width="30" height="30" color="#FFFFFF" position="60 -205 -5" text="+" />
<Button onClick="dec(tablet)" width="30" height="30" color="#FFFFFF" position="95 -205 -5" text="-" />
<Text alignment="MiddleRight" width="100" height="30" color="#FFFFFF" outline="#000000" position="-140 -240 -5" text="Elder Thing" />
<InputField id="elder_thing" onEndEdit="revalue" width="120" height="30" color="#FFFFFF" position="-20 -240 -5" characterValidation="Integer">0</InputField>
<Button onClick="inc(elder_thing)" width="30" height="30" color="#FFFFFF" position="60 -240 -5" text="+" />
<Button onClick="dec(elder_thing)" width="30" height="30" color="#FFFFFF" position="95 -240 -5" text="-" />
<Text alignment="MiddleRight" width="100" height="30" color="#FFFFFF" outline="#000000" position="-140 -275 -5" text="Auto-fail" />
<InputField id="autofail" onEndEdit="revalue" width="120" height="30" color="#FFFFFF" position="-20 -275 -5" characterValidation="Integer">-100</InputField>
<Button onClick="inc(autofail)" width="30" height="30" color="#FFFFFF" position="60 -275 -5" text="+" />
<Button onClick="dec(autofail)" width="30" height="30" color="#FFFFFF" position="95 -275 -5" text="-" />
<Text alignment="MiddleRight" width="100" height="30" color="#FFFFFF" outline="#000000" position="-140 -310 -5" text="Bless" />
<InputField id="bless" onEndEdit="revalue" width="120" height="30" color="#FFFFFF" position="-20 -310 -5" characterValidation="Integer">-105</InputField>
<Button onClick="inc(bless)" width="30" height="30" color="#FFFFFF" position="60 -310 -5" text="+" />
<Button onClick="dec(bless)" width="30" height="30" color="#FFFFFF" position="95 -310 -5" text="-" />
<Text alignment="MiddleRight" width="100" height="30" color="#FFFFFF" outline="#000000" position="-140 -345 -5" text="Curse" />
<InputField id="curse" onEndEdit="revalue" width="120" height="30" color="#FFFFFF" position="-20 -345 -5" characterValidation="Integer">-106</InputField>
<Button onClick="inc(curse)" width="30" height="30" color="#FFFFFF" position="60 -345 -5" text="+" />
<Button onClick="dec(curse)" width="30" height="30" color="#FFFFFF" position="95 -345 -5" text="-" />
<Text alignment="MiddleRight" width="100" height="30" color="#FFFFFF" outline="#000000" position="-140 -380 -5" text="Frost" />
<InputField id="frost" onEndEdit="revalue" width="120" height="30" color="#FFFFFF" position="-20 -380 -5" characterValidation="Integer">-107</InputField>
<Button onClick="inc(frost)" width="30" height="30" color="#FFFFFF" position="60 -380 -5" text="+" />
<Button onClick="dec(frost)" width="30" height="30" color="#FFFFFF" position="95 -380 -5" text="-" />
<Text alignment="MiddleRight" width="100" height="30" color="#FFFFFF" outline="#000000" position="-140 -415 -5" text="Unnamed" />
<InputField id="unnamed" onEndEdit="revalue" width="120" height="30" color="#FFFFFF" position="-20 -415 -5" characterValidation="Integer">0</InputField>
<Button onClick="inc(unnamed)" width="30" height="30" color="#FFFFFF" position="60 -415 -5" text="+" />
<Button onClick="dec(unnamed)" width="30" height="30" color="#FFFFFF" position="95 -415 -5" text="-" />
<Button alignment="MiddleCenter" onClick="layout" width="280" height="30" color="#000000" textColor="#FFFFFF" position="-30 -450 -5" text="Position Tokens" />
<ToggleButton id="auto_update" onValueChanged="updateToggle" isOn="false" width="280" height="30" position="-30 -485 -5" text="Automatic Update" />

View File

@ -30,7 +30,7 @@
"Sticky": true,
"Tooltip": false,
"Transform": {
"posX": 77.836,
"posX": 78,
"posY": 1.244,
"posZ": 33.583,
"rotX": 0,

View File

@ -44,8 +44,8 @@
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 78.46,
"posY": 1.138,
"posX": 78,
"posY": 1.047,
"posZ": -1.001,
"rotX": 0,
"rotY": 0,

View File

@ -21,17 +21,17 @@
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScript": "require(\"util/TokenSpawner\")",
"LuaScript": "require(\"util/TokenSpawnTool\")",
"LuaScriptState": "",
"MeasureMovement": false,
"Name": "Checker_white",
"Nickname": "Token Spawner",
"Nickname": "Token Spawn Tool",
"Snap": true,
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 77.159,
"posY": 1.297,
"posX": 78,
"posY": 1.208,
"posZ": 6.952,
"rotX": 0,
"rotY": 270,

View File

@ -30,8 +30,8 @@
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 77.88,
"posY": 1.485,
"posX": 78,
"posY": 1.395,
"posZ": 1.875,
"rotX": 0,
"rotY": 0,

View File

@ -1,45 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 0,
"g": 0,
"r": 0
},
"Description": "",
"DragSelectable": true,
"GMNotes": "",
"GUID": "ddd2eb",
"Grid": true,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": true,
"LuaScriptState": "",
"LuaScript_path": "UIBuilder.ddd2eb.ttslua",
"MeasureMovement": false,
"Name": "Checker_black",
"Nickname": "UI Builder",
"Snap": true,
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 77.06,
"posY": 1.296,
"posZ": 8.942,
"rotX": 0,
"rotY": 270,
"rotZ": 180,
"scaleX": 0.25,
"scaleY": 0.25,
"scaleZ": 0.25
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,77 +0,0 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by Whimsical.
--- DateTime: 2021-08-24 9:55 a.m.
---
-- Please call this first. It makes things so much easier.
---@param target TTSObject
---@param callback_name string
---@return number
local function make_decktype_checkbox(target, callback_name)
-- Create Private/Published checkbox
target:createButton {
click_function = callback_name,
function_owner = target,
position = Vector(-0.33, 0.1, -0.255),
width = 2100,
height = 500,
tooltip = "Click to toggle Private/Published deck ID",
label = "Private",
font_size = 350,
scale = Vector(0.1, 0.1, 0.1),
color = Color(0.9, 0.7, 0.5),
hover_color = Color(0.4, 0.6, 0.8)
}
return target:getButtons()[1].index -- If we do this first, we know that our index is our new button
end
function noop() end
---@param target TTSObject
---@param debug_deck_id string|nil
local function make_text(target, debug_deck_id)
-- Create textbox
target:createInput {
function_owner = self,
position = Vector(0.33, 0.1, -0.255),
width = 2200,
height = 500,
scale = Vector(0.1, 0.1, 0.1),
font_size = 450,
tooltip = "*****PLEASE USE AN UNPUBLISHED DECK IF JUST FOR TTS TO AVOID FLOODING ARKHAMDB PUBLISHED DECK LISTS!*****\nInput deck ID from ArkhamDB URL of the deck\nExample: For the URL 'https://arkhamdb.com/decklist/view/101/knowledge-overwhelming-solo-deck-1.0', you should input '101'",
alignment = 3,
value = debug_deck_id or "",
color = Color(0.9, 0.7, 0.5),
validation = 2,
input_function = "noop"
}
end
---@param target TTSObject
---@param callback_name string
local function make_button(target, callback_name)
-- Create Button
target:createButton {
click_function = callback_name,
function_owner = target,
position = Vector(0.0, 0.05, -0.1),
width = 300,
height = 100,
tooltip = "Click to build your deck!",
scale = Vector(1, 1, 0.6),
color = Color.Black
}
end
---@param parameters ArkhamImportUIParameters
---@return number
function create_ui(parameters)
local target = getObjectFromGUID(parameters.target_guid)
local index = make_decktype_checkbox(target, parameters.checkbox_toggle_callback_name)
make_text(target, parameters.debug_deck_id)
make_button(target, parameters.build_deck_callback_name)
return index
end

View File

@ -1,98 +1,85 @@
-- Drawing Tool
-- created by: Chr1Z
-- original by: Whimsical
-- description: draws lines between selected objects
information = {
version = "1.1",
last_updated = "10.10.2022"
}
local lines = {}
-- save "lines" to be able to remove them after loading
function onSave() return JSON.encode(lines) end
function onSave()
return JSON.encode(lines)
end
-- load data and add context menu
function onload(saved_data)
lines = JSON.decode(saved_data) or {}
self.addContextMenuItem("More Information", function()
printToAll("------------------------------", "White")
printToAll("Drawing Tool v" .. information["version"] .. " by Chr1Z", "Orange")
printToAll("last updated: " .. information["last_updated"], "White")
printToAll("original concept by Whimsical", "White")
end)
function onLoad(savedData)
lines = JSON.decode(savedData) or {}
end
-- create timer when numpad 0 is pressed
function onScriptingButtonDown(index, player_color)
if index ~= 10 then return end
TimerID = Wait.time(function() draw_from(Player[player_color]) end, 1)
if index ~= 10 then return end
TimerID = Wait.time(function() draw_from(Player[player_color]) end, 1)
end
-- called for long press of numpad 0, draws lines from hovered object to selected objects
function draw_from(player)
local source = player.getHoverObject()
if not source then return end
local source = player.getHoverObject()
if not source then return end
for _, item in ipairs(player.getSelectedObjects()) do
if item.getGUID() ~= source.getGUID() then
if item.getGUID() > source.getGUID() then
draw_with_pair(item, source)
else
draw_with_pair(source, item)
end
end
for _, item in ipairs(player.getSelectedObjects()) do
if item.getGUID() ~= source.getGUID() then
if item.getGUID() > source.getGUID() then
draw_with_pair(item, source)
else
draw_with_pair(source, item)
end
end
end
process_lines()
process_lines()
end
-- general drawing of all lines between selected objects
function onScriptingButtonUp(index, player_color)
if index ~= 10 then return end
-- returns true only if there is a timer to cancel. If this is false then we've waited longer than a second.
if not Wait.stop(TimerID) then return end
if index ~= 10 then return end
-- returns true only if there is a timer to cancel. If this is false then we've waited longer than a second.
if not Wait.stop(TimerID) then return end
local items = Player[player_color].getSelectedObjects()
if #items < 2 then
broadcastToColor("You must have at least two items selected (currently: " .. #items .. ").", player_color, "Red")
return
local items = Player[player_color].getSelectedObjects()
if #items < 2 then
broadcastToColor("You must have at least two items selected (currently: " .. #items .. ").", player_color, "Red")
return
end
table.sort(items, function(a, b) return a.getGUID() > b.getGUID() end)
for f = 1, #items - 1 do
for s = f + 1, #items do
draw_with_pair(items[f], items[s])
end
end
table.sort(items, function(a, b) return a.getGUID() > b.getGUID() end)
for f = 1, #items - 1 do
for s = f + 1, #items do
draw_with_pair(items[f], items[s])
end
end
process_lines()
process_lines()
end
-- adds two objects to table of vector lines
function draw_with_pair(first, second)
local guid_first = first.getGUID()
local guid_second = second.getGUID()
local guid_first = first.getGUID()
local guid_second = second.getGUID()
if Global.getVectorLines() == nil then lines = {} end
if not lines[guid_first] then lines[guid_first] = {} end
if Global.getVectorLines() == nil then lines = {} end
if not lines[guid_first] then lines[guid_first] = {} end
if lines[guid_first][guid_second] then
lines[guid_first][guid_second] = nil
else
lines[guid_first][guid_second] = { points = { first.getPosition(), second.getPosition() }, color = "White" }
end
if lines[guid_first][guid_second] then
lines[guid_first][guid_second] = nil
else
lines[guid_first][guid_second] = { points = { first.getPosition(), second.getPosition() }, color = "White" }
end
end
-- updates the global vector lines based on "lines"
function process_lines()
local drawing = {}
local drawing = {}
for _, first in pairs(lines) do
for _, data in pairs(first) do
table.insert(drawing, data)
end
for _, first in pairs(lines) do
for _, data in pairs(first) do
table.insert(drawing, data)
end
end
Global.setVectorLines(drawing)
Global.setVectorLines(drawing)
end

View File

@ -1,31 +1,29 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by Whimsical.
--- DateTime: 2020-09-26 5:50 p.m.
---
---@param index number
---@param player_color string
-- cut 3 (6) cards from a deck if numpad 1 (2) is pressed
function onScriptingButtonDown(index, player_color)
if not (index>=1 and index<=3) then return end
if not (index >= 1 and index <= 2) then return end
local count = index * 3
---@type Player
local count = index * 3
local player = Player[player_color]
local object = player:getHoverObject()
local object = player.getHoverObject()
if not object then
broadcastToColor("Hover over a deck and try again.", player_color, "Orange")
return
end
if object.tag ~= "Deck" then
broadcastToColor("Hover over a deck and try again.", player_color, "Orange")
return
end
if count >= object.getQuantity() then
broadcastToColor("Deck is too small to cut " .. count .. " cards.", player_color, "Orange")
return
end
if (not object) then return end
if (object.tag~="Deck") then return end
if (count >= object:getQuantity()) then return end
for _ =1, count do
local target_position = object:positionToWorld(Vector(0, 0, -3.5))
object:takeObject {
local pos = object.positionToWorld(Vector(0, 0, -3.5))
for _ = 1, count do
object.takeObject {
index = 0,
position = target_position,
position = pos,
smooth = false
}
end

View File

@ -1,8 +1,5 @@
local tokenManager = require("core/token/TokenManager")
local TOKEN_INDEX = {}
TOKEN_INDEX[1] = false
TOKEN_INDEX[2] = false
TOKEN_INDEX[3] = "resourceCounter"
TOKEN_INDEX[4] = "damage"
TOKEN_INDEX[5] = "path"