first commit

This commit is contained in:
Chr1Z93 2023-03-03 00:39:20 +01:00
parent ceef316adf
commit 832b8a24df
20 changed files with 315 additions and 941 deletions

View File

@ -63,7 +63,7 @@
"IgnoreFoW": false, "IgnoreFoW": false,
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": false, "Locked": false,
"LuaScript": "require(\"chaosbag/ChaosBag\")", "LuaScript": "",
"LuaScriptState": "", "LuaScriptState": "",
"MaterialIndex": -1, "MaterialIndex": -1,
"MeasureMovement": false, "MeasureMovement": false,

View File

@ -18,7 +18,7 @@
"Curse.16a9a7", "Curse.16a9a7",
"Bless.8e3aab", "Bless.8e3aab",
"ElderSign.0b1aca", "ElderSign.0b1aca",
"Auto-Fail.e31821", "Auto-fail.e31821",
"ElderThing.38609c", "ElderThing.38609c",
"Tablet.1a1506", "Tablet.1a1506",
"Cultist.7d6103", "Cultist.7d6103",

View File

@ -37,7 +37,7 @@
"LuaScriptState": "", "LuaScriptState": "",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Tile", "Name": "Custom_Tile",
"Nickname": "Auto-Fail", "Nickname": "Auto-fail",
"Snap": true, "Snap": true,
"Sticky": true, "Sticky": true,
"Tooltip": true, "Tooltip": true,

View File

@ -21,7 +21,7 @@
"ArkhamFantasy-PixelArtMini-Cards.e17c9e", "ArkhamFantasy-PixelArtMini-Cards.e17c9e",
"jaqenZannsNavigationOverlay.a8affa", "jaqenZannsNavigationOverlay.a8affa",
"DrawTokenButtonTooltipRenamer.cc77a8", "DrawTokenButtonTooltipRenamer.cc77a8",
"WhimsicalsGenericDifficultySelector.05efb4", "GenericDifficultySelector.8112ff",
"SearchAssistant.17aed0", "SearchAssistant.17aed0",
"HandHelper.450688", "HandHelper.450688",
"DisplacementTool.0f1374", "DisplacementTool.0f1374",

View File

@ -22,7 +22,7 @@
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/965354846165100486/3DC8FCEF364B30758B09EF96AF9458F2B8E64D56/", "ImageURL": "http://cloud-3.steamusercontent.com/ugc/965354846165100486/3DC8FCEF364B30758B09EF96AF9458F2B8E64D56/",
"WidthScale": 0 "WidthScale": 0
}, },
"Description": "click to set chaos token difficulty", "Description": "Define difficulties in this objects script.",
"DragSelectable": true, "DragSelectable": true,
"GMNotes": "", "GMNotes": "",
"GUID": "8112ff", "GUID": "8112ff",
@ -34,7 +34,7 @@
"LayoutGroupSortIndex": 0, "LayoutGroupSortIndex": 0,
"Locked": false, "Locked": false,
"LuaScriptState": "", "LuaScriptState": "",
"LuaScript_path": "Fan-MadeAccessories.aa8b38/WhimsicalsGenericDifficultySelector.05efb4/GenericDifficultySelector.8112ff.ttslua", "LuaScript_path": "Fan-MadeAccessories.aa8b38/GenericDifficultySelector.8112ff.ttslua",
"MeasureMovement": false, "MeasureMovement": false,
"Name": "Custom_Tile", "Name": "Custom_Tile",
"Nickname": "Generic Difficulty Selector", "Nickname": "Generic Difficulty Selector",
@ -54,4 +54,4 @@
}, },
"Value": 0, "Value": 0,
"XmlUI": "" "XmlUI": ""
} }

View File

@ -0,0 +1,38 @@
-- edit the "tokenData" table to change the preset difficulties
-- list of valid ids: 'p1', '0', 'm1', 'm2', 'm3', 'm4', 'm5', 'm6', 'm7', 'm8',
-- 'skull', 'cultist', 'tablet', 'elder', 'red', 'blue', 'bless', 'curse', 'frost'
local tokenData = {
Easy = { 'p1', 'p1', '0', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'skull', 'skull', 'cultist', 'red', 'blue' },
Standard = { 'p1', '0', '0', 'm1', 'm1', 'm1', 'm2', 'm2', 'm3', 'm4', 'skull', 'skull', 'cultist', 'red', 'blue' },
Hard = { '0', '0', '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm5', 'skull', 'skull', 'cultist', 'red', 'blue' },
Expert = { '0', 'm1', 'm1', 'm2', 'm2', 'm3', 'm3', 'm4', 'm4', 'm5', 'm6', 'm8', 'skull', 'skull', 'cultist', 'red', 'blue' }
}
-- create buttons on startup
function onLoad()
local z_offset = -0.15
for difficulty, _ in pairs(tokenData) do
local clickFunction = difficulty:lower() .. "Click"
self.setVar(clickFunction, function() clickFun(difficulty) end)
self.createButton({
label = difficulty,
function_owner = self,
click_function = clickFunction,
position = { 0, 0.1, z_offset },
rotation = { 0, 0, 0 },
scale = { 0.47, 1, 0.47 },
height = 200,
width = 1150,
font_size = 100,
color = { 0.87, 0.8, 0.70 },
font_color = { 0, 0, 0 }
})
z_offset = z_offset + 0.20
end
end
function clickFun(difficulty)
Global.call("setChaosBagState", tokenData[difficulty])
end

View File

@ -1,57 +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": [
"GenericDifficultySelector.8112ff",
"TokenImageProvider.162580",
"TokenList.297f5e",
"GenericDifficultySelectorInstructions13.c32992"
],
"ContainedObjects_path": "WhimsicalsGenericDifficultySelector.05efb4",
"Description": "",
"DragSelectable": true,
"GMNotes": "",
"GUID": "05efb4",
"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": "Whimsical's Generic Difficulty Selector",
"Snap": true,
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 29.073,
"posY": 3.901,
"posZ": -21.285,
"rotX": 0,
"rotY": 0,
"rotZ": 0,
"scaleX": 1,
"scaleY": 1,
"scaleZ": 1
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,169 +0,0 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by Whimsical.
--- DateTime: 2021-08-05 6:14 p.m.
---
local tags = {
bag = "chaosBag",
provider = "token_list_provider",
tokens = "token_image_provider"
}
---@class ChaosToken
---@field name string
---@field image string
local _ = {}
---@type table<string|number, ChaosToken>
local sources
---@type table<string, any[]>
local tokens
---@param source TTSObject
local LoadSource = function (source)
tokens = source:getTable("chaos_tokens")
end
---@param token ChaosToken
---@param position Vector
---@param chaosBag TTSObject
---@return number
local SpawnToken = function(token, position, chaosBag)
spawnObject {
type = "Custom_Tile",
position = position,
scale = { 0.81, 1.0, 0.81 },
rotation = { 0, 270, 0 },
---@param object TTSObject
callback_function = function(object, _, _)
object:setName(token.name)
chaosBag:putObject(object)
end
}:setCustomObject {
image = token.image,
type = 2,
thickness = 0.1
}
end
---@param chaosBag TTSObject
local emptyBag = function(chaosBag)
local object = chaosBag:getObjects()
local pos = self:getPosition()
pos.y = pos.y+1
for _, object in ipairs(object) do
chaosBag:takeObject {
guid = object.guid,
position = pos,
---@param item TTSObject
callback_function = function (item) item:destruct() end
}
end
end
---@param difficulty string
local clickFun= function (difficulty)
local chaosBag = getObjectsWithTag(tags.bag)[1]
emptyBag(chaosBag)
local loading = tokens[difficulty]
local pos = self:getPosition()
for _, token_id in ipairs(loading) do
if type(token_id)=="string" then token_id = token_id:lower() end
local token = sources[token_id]
if (token==nil) then
error("Could not find token \"" .. token_id .. "\".")
return
end
SpawnToken(token, pos, chaosBag)
end
end
---@param difficulty string
local MakeClickFun = function(difficulty)
return function ()
clickFun(difficulty)
end
end
---@param label string
---@param z_offset number|nil
local makeButton = function(label , z_offset)
z_offset = z_offset or -0.15
_G[label:lower() .. "Click"] = MakeClickFun(label)
self:createButton({
label = label,
function_owner = self,
click_function = label:lower() .. "Click",
position = {0, 0.1, z_offset},
rotation = {0, 0, 0},
scale = {0.47, 1, 0.47},
height = 200,
width = 1150,
font_size = 100,
color = {0.87, 0.8, 0.70},
font_color = {0, 0, 0}
})
return z_offset + 0.20
end
---@param source TTSObject
local CreateButtons= function(source)
self:clearButtons()
local z_offset
for difficulty,_ in pairs(tokens) do
z_offset = makeButton(difficulty, z_offset)
end
end
function LoadTokens()
---@type TTSObject[]
local image_sources = getObjectsWithTag(tags.tokens)
if (#image_sources<=0) then
error("Cannot find images_sources")
return
end
sources = image_sources[1]:getTable("sources")
if (tokens~=nil) then CreateButtons() return end
local source = getObjectsWithTag(tags.provider)
if (#source<=0) then return end
LoadSource(source[1])
CreateButtons()
end
function onload()
Timer.create {
identifier = self:getGUID(),
function_name = "LoadTokens"
}
end
---@param provider TTSObject
function onObjectSpawn(provider)
if (not provider:hasTag(tags.provider)) then return end
LoadSource(provider)
CreateButtons()
end

View File

@ -1,137 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"Description": "Tool for create custom chaos bag configurations.\n - The actual difficulty selector: click a difficulty to fill the chaos bag.\n- Token Image Provider: edit in scripting editor to add new token types. Cut and Paste to save.\n- Token List: edit in scripting editor to customize difficulties. Cut and Paste to save.\n\nReference of Token codes on following pages:",
"DragSelectable": true,
"GMNotes": "",
"GUID": "c32992",
"Grid": true,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": false,
"LuaScript": "",
"LuaScriptState": "",
"MeasureMovement": false,
"Name": "Notecard",
"Nickname": "Generic Difficulty Selector Instructions 1/3",
"Snap": true,
"States": {
"2": {
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"Description": "1 — -8: Numeric tokens (Don't place quotes around these).\r\n\"S\": Skull.\r\n\"C\": Cultist.\r\n\"T\": Tablet.\r\n\"E\": Elder Thing.\r\n\"Fr\": Frost.",
"DragSelectable": true,
"GMNotes": "",
"GUID": "eab766",
"Grid": true,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": false,
"LuaScript": "",
"LuaScriptState": "",
"MeasureMovement": false,
"Name": "Notecard",
"Nickname": "Generic Difficulty Selector Instructions 2/3",
"Snap": true,
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 3.29240441,
"posY": 1.33262193,
"posZ": 56.0586357,
"rotX": 359.9792,
"rotY": 89.99884,
"rotZ": 359.983215,
"scaleX": 1,
"scaleY": 1,
"scaleZ": 1
},
"Value": 0,
"XmlUI": ""
},
"3": {
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"Description": "\"*\": Elder Sign.\r\n\"F\": Auto-fail.\r\n\"+\": Bless.\r\n\"-\": Curse.",
"DragSelectable": true,
"GMNotes": "",
"GUID": "309295",
"Grid": true,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": false,
"LuaScript": "",
"LuaScriptState": "",
"MeasureMovement": false,
"Name": "Notecard",
"Nickname": "Generic Difficulty Selector Instructions 3/3",
"Snap": true,
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 3.29240441,
"posY": 1.33262193,
"posZ": 56.0586357,
"rotX": 359.9792,
"rotY": 89.9988556,
"rotZ": 359.983215,
"scaleX": 1,
"scaleY": 1,
"scaleZ": 1
},
"Value": 0,
"XmlUI": ""
}
},
"Sticky": true,
"Tooltip": true,
"Transform": {
"posX": 13.505,
"posY": 3.625,
"posZ": 30.273,
"rotX": 0,
"rotY": 90,
"rotZ": 0,
"scaleX": 1,
"scaleY": 1,
"scaleZ": 1
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,48 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 1,
"g": 1,
"r": 1
},
"Description": "",
"DragSelectable": true,
"GMNotes": "",
"GUID": "162580",
"Grid": true,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": false,
"LuaScriptState": "",
"LuaScript_path": "Fan-MadeAccessories.aa8b38/WhimsicalsGenericDifficultySelector.05efb4/TokenImageProvider.162580.ttslua",
"MeasureMovement": false,
"Name": "Checker_white",
"Nickname": "Token Image Provider",
"Snap": true,
"Sticky": true,
"Tags": [
"token_image_provider"
],
"Tooltip": true,
"Transform": {
"posX": 13.194,
"posY": 3.807,
"posZ": 28.835,
"rotX": 0,
"rotY": 270,
"rotZ": 180,
"scaleX": 1,
"scaleY": 1,
"scaleZ": 1
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,37 +0,0 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by Whimsical.
--- DateTime: 2021-08-05 6:51 p.m.
---
---@param name string
---@param image string
---@return ChaosToken
local MakeToken = function (name, image)
return {
name = name,
image = image
}
end
sources = {
[1] = MakeToken("+1", "https://i.imgur.com/uIx8jbY.png"),
[0] = MakeToken("0", "https://i.imgur.com/btEtVfd.png"),
[-1] = MakeToken("-1", "https://i.imgur.com/w3XbrCC.png"),
[-2] = MakeToken("-2", "https://i.imgur.com/bfTg2hb.png"),
[-3] = MakeToken("-3", "https://i.imgur.com/yfs8gHq.png"),
[-4] = MakeToken("-4", "https://i.imgur.com/qrgGQRD.png"),
[-5] = MakeToken("-5", "https://i.imgur.com/3Ym1IeG.png"),
[-6] = MakeToken("-6", "https://i.imgur.com/c9qdSzS.png"),
[-7] = MakeToken("-7", "https://i.imgur.com/4WRD42n.png"),
[-8] = MakeToken("-8", "https://i.imgur.com/9t3rPTQ.png"),
["s"] = MakeToken("Skull", "https://i.imgur.com/stbBxtx.png"),
["c"] = MakeToken("Cultist", "https://i.imgur.com/VzhJJaH.png"),
["t"] = MakeToken("Tablet", "https://i.imgur.com/1plY463.png"),
["e"] = MakeToken("Elder Thing", "https://i.imgur.com/ttnspKt.png"),
["*"] = MakeToken("Elder Sign", "https://i.imgur.com/nEmqjmj.png"),
["f"] = MakeToken("Auto-fail", "https://i.imgur.com/lns4fhz.png"),
["+"] = MakeToken("Bless", "http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/"),
["-"] = MakeToken("Curse", "http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/"),
["fr"] = MakeToken("Frost", "http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/"),
}

View File

@ -1,49 +0,0 @@
{
"AltLookAngle": {
"x": 0,
"y": 0,
"z": 0
},
"Autoraise": true,
"ColorDiffuse": {
"b": 0,
"g": 0,
"r": 0
},
"Description": "",
"DragSelectable": true,
"GMNotes": "",
"GUID": "297f5e",
"Grid": true,
"GridProjection": false,
"Hands": false,
"HideWhenFaceDown": false,
"IgnoreFoW": false,
"LayoutGroupSortIndex": 0,
"Locked": false,
"LuaScriptState": "",
"LuaScript_path": "Fan-MadeAccessories.aa8b38/WhimsicalsGenericDifficultySelector.05efb4/TokenList.297f5e.ttslua",
"MeasureMovement": false,
"Name": "Checker_black",
"Nickname": "Token List",
"Snap": true,
"Sticky": true,
"Tags": [
"mlc_memory_object",
"token_list_provider"
],
"Tooltip": true,
"Transform": {
"posX": 12.984,
"posY": 4.045,
"posZ": 29.828,
"rotX": 0,
"rotY": 270,
"rotZ": 206,
"scaleX": 1,
"scaleY": 1,
"scaleZ": 1
},
"Value": 0,
"XmlUI": ""
}

View File

@ -1,12 +0,0 @@
---
--- Generated by EmmyLua(https://github.com/EmmyLua)
--- Created by Whimsical.
--- DateTime: 2021-08-05 7:19 p.m.
---
chaos_tokens = {
Easy = {1, 1, 0, 0, -1, -1, -1, -2, -2, "S", "S", "C", "T", "F", "*"},
Standard = {1, 0, 0, -1, -1, -1, -2, -2, -3, -4, "S", "S", "C", "T", "F", "*"},
Hard = {0, 0, -1, -1, -2, -2, -3, -4, -4, -5, "Fr", "Fr", "S", "S", "C", "T", "F", "*"},
Expert = {0, -1, -2, -2, -3, -4, -4, -5, -7, "Fr", "Fr", "Fr", "S", "S", "C", "T", "F", "*"}
}

View File

@ -1,30 +1,10 @@
local TOKEN_URL = { local TOKEN_IDS = {
ElderSign = "https://i.imgur.com/nEmqjmj.png",
plusOne = "https://i.imgur.com/uIx8jbY.png",
Zero = "https://i.imgur.com/btEtVfd.png",
minusOne = "https://i.imgur.com/w3XbrCC.png",
minusTwo = "https://i.imgur.com/bfTg2hb.png",
minusThree = "https://i.imgur.com/yfs8gHq.png",
minusFour = "https://i.imgur.com/qrgGQRD.png",
minusFive = "https://i.imgur.com/3Ym1IeG.png",
minusSix = "https://i.imgur.com/c9qdSzS.png",
minusSeven = "https://i.imgur.com/4WRD42n.png",
minusEight = "https://i.imgur.com/9t3rPTQ.png",
Skull = "https://i.imgur.com/stbBxtx.png",
Cultist = "https://i.imgur.com/VzhJJaH.png",
Tablet = "https://i.imgur.com/1plY463.png",
ElderThing = "https://i.imgur.com/ttnspKt.png",
AutoFail = "https://i.imgur.com/lns4fhz.png",
Frost = "http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/"
}
local TOKEN_NAMES = {
-- first row -- first row
"plusOne", "Zero", "minusOne", "minusTwo", "minusThree", "minusFour", "p1", "0", "m1", "m2", "m3", "m4",
-- second row -- second row
"minusFive", "minusSix", "minusSeven", "minusEight", "Frost", "m5", "m6", "m7", "m8", "frost",
-- third row -- third row
"ElderSign", "Skull", "Cultist", "Tablet", "ElderThing", "AutoFail" "blue", "skull", "cultist", "tablet", "elder", "red"
} }
local BUTTON_TOOLTIP = { local BUTTON_TOOLTIP = {
@ -52,9 +32,6 @@ buttonParameters.color = { 0, 0, 0, 0 }
buttonParameters.width = 300 buttonParameters.width = 300
buttonParameters.height = 300 buttonParameters.height = 300
local UPDATING = false
local tokenArranger
local name local name
local tokens = {} local tokens = {}
@ -76,108 +53,30 @@ function onLoad()
self.createButton(buttonParameters) self.createButton(buttonParameters)
end end
self.addContextMenuItem("More Information", function()
printToAll("------------------------------", "White")
printToAll("Chaos Bag Manager by Chr1Z", "Orange")
end)
tokenArranger = getObjectFromGUID("022907")
end
-- get chaos bag from scripting zone and description
function getChaosBag()
local chaosbag = nil
local chaosbag_zone = getObjectFromGUID("83ef06")
-- error handling: scripting zone not found
if chaosbag_zone == nil then
printToAll("Zone for chaos bag detection couldn't be found.", "Red")
return nil
end
for _, v in ipairs(chaosbag_zone.getObjects()) do
if v.getDescription() == "Chaos Bag" then
chaosbag = getObjectFromGUID(v.getGUID())
break
end
end
-- error handling: chaos bag not found
if chaosbag == nil then
printToAll("Chaos bag couldn't be found.", "Red")
end
return chaosbag
end end
-- click function for buttons -- click function for buttons
function buttonClick(index, isRightClick) function buttonClick(index, isRightClick)
chaosbag = getChaosBag() local tokenId = TOKEN_IDS[index]
-- error handling: chaos bag not found
if chaosbag == nil then return end
name = BUTTON_TOOLTIP[index]
tokens = {}
for _, v in ipairs(chaosbag.getObjects()) do
if v.name == name then table.insert(tokens, v.guid) end
end
token = TOKEN_NAMES[index]
if isRightClick then if isRightClick then
-- error handling: no matching token found Global.call("removeChaosToken", tokenId)
if #tokens == 0 then else
printToAll("No " .. name .. " tokens in the chaos bag.", "Yellow") local tokens = {}
return local name = BUTTON_TOOLTIP[index]
local chaosbag = Global.call("findChaosBag")
for _, v in ipairs(chaosbag.getObjects()) do
if v.name == name then table.insert(tokens, v.guid) end
end end
-- remove token
chaosbag.takeObject({
guid = tokens[1],
position = self.getPosition(),
smooth = false,
callback_function = removeCallback
})
else
-- spawn token (only 8 frost tokens allowed) -- spawn token (only 8 frost tokens allowed)
if token == "Frost" and #tokens == 8 then if tokenId == "frost" and #tokens == 8 then
printToAll("The maximum of 8 Frost tokens is already in the bag.", "Yellow") printToAll("The maximum of 8 Frost tokens is already in the bag.", "Yellow")
return return
end end
local obj = spawnObject({ Global.call("spawnChaosToken", tokenId)
type = 'Custom_Tile', printToAll("Adding " .. name .. " token (in bag: " .. #tokens + 1 .. ")", "White")
position = chaosbag.getPosition() + Vector(0, 1, 0),
rotation = { x = 0, y = 260, z = 0 },
callback_function = spawnCallback
})
obj.setCustomObject({
type = 2,
image = TOKEN_URL[token],
thickness = 0.1
})
end
updateTokenArranger()
end
function removeCallback(obj)
printToAll("Removing " .. name .. " token (in bag: " .. #tokens - 1 .. ")", "White")
obj.destruct()
end
function spawnCallback(obj)
obj.scale { 0.81, 1, 0.81 }
obj.setName(name)
printToAll("Adding " .. name .. " token (in bag: " .. #tokens + 1 .. ")", "White")
end
function updateTokenArranger()
if tokenArranger and not UPDATING then
UPDATING = true
Wait.time(function()
UPDATING = false
tokenArranger.call("layout")
end, 1.5)
end end
end end

View File

@ -28,7 +28,7 @@ do
-- updates the laid out tokens -- updates the laid out tokens
TokenArrangerApi.layout = function() TokenArrangerApi.layout = function()
callIfExistent("layout") Wait.time(function() callIfExistent("layout") end, 0.1)
end end
return TokenArrangerApi return TokenArrangerApi

View File

@ -1,10 +1,5 @@
local tokenArrangerApi = require("accessories/TokenArrangerApi") local tokenArrangerApi = require("accessories/TokenArrangerApi")
local IMAGE_URL = {
Bless = "http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/",
Curse = "http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/"
}
-- common button parameters -- common button parameters
local buttonParamaters = {} local buttonParamaters = {}
buttonParamaters.function_owner = self buttonParamaters.function_owner = self
@ -71,8 +66,7 @@ end
function initializeState() function initializeState()
-- count tokens in the bag -- count tokens in the bag
local chaosbag = getChaosBag() local chaosbag = Global.call("findChaosBag")
if chaosbag == nil then return end
local tokens = {} local tokens = {}
for _, v in ipairs(chaosbag.getObjects()) do for _, v in ipairs(chaosbag.getObjects()) do
if v.name == "Bless" then if v.name == "Bless" then
@ -113,11 +107,7 @@ end
-- context menu function 1 -- context menu function 1
function doRemove(color) function doRemove(color)
local chaosbag = getChaosBag() local chaosbag = Global.call("findChaosBag")
if chaosbag == nil then
broadcastToAll("Chaos bag not found!", "Red")
return
end
-- remove tokens from chaos bag -- remove tokens from chaos bag
local count = { Bless = 0, Curse = 0 } local count = { Bless = 0, Curse = 0 }
@ -134,20 +124,6 @@ function doRemove(color)
broadcastToColor("Removed " .. count["Bless"] .. " Bless and " .. broadcastToColor("Removed " .. count["Bless"] .. " Bless and " ..
count["Curse"] .. " Curse tokens from the chaos bag.", color, "White") count["Curse"] .. " Curse tokens from the chaos bag.", color, "White")
-- removing tokens that were 'taken'
local function removeType(type)
local count = 0
for _, guid in ipairs(tokensTaken[type]) do
local token = getObjectFromGUID(guid)
if token ~= nil then
token.destruct()
count = count + 1
end
end
return count
end
broadcastToColor("Removed " .. removeType("Bless") .. " Bless and " .. broadcastToColor("Removed " .. removeType("Bless") .. " Bless and " ..
removeType("Curse") .. " Curse tokens from play.", color, "White") removeType("Curse") .. " Curse tokens from play.", color, "White")
@ -156,9 +132,6 @@ end
-- context menu function 2 -- context menu function 2
function doReset(color) function doReset(color)
-- delete previously pulled out tokens by the token arranger
tokenArrangerApi.deleteCopiedTokens()
playerColor = color playerColor = color
numInPlay = { Bless = 0, Curse = 0 } numInPlay = { Bless = 0, Curse = 0 }
tokensTaken = { Bless = {}, Curse = {} } tokensTaken = { Bless = {}, Curse = {} }
@ -166,6 +139,19 @@ function doReset(color)
tokenArrangerApi.layout() tokenArrangerApi.layout()
end end
-- removing tokens that were 'taken'
function removeType(type)
local count = 0
for _, guid in ipairs(tokensTaken[type]) do
local token = getObjectFromGUID(guid)
if token ~= nil then
token.destruct()
count = count + 1
end
end
return count
end
--------------------------------------------------------- ---------------------------------------------------------
-- click functions -- click functions
--------------------------------------------------------- ---------------------------------------------------------
@ -248,22 +234,6 @@ function callFunctions(token, isRightClick)
if success ~= 0 then tokenArrangerApi.layout() end if success ~= 0 then tokenArrangerApi.layout() end
end end
function getChaosBag()
local zone = getObjectFromGUID("83ef06")
if zone == nil then printToAll("Zone for chaosbag not found!", "Red") return end
local items = zone.getObjects()
local chaosbag = nil
for _, v in ipairs(items) do
if v.getDescription() == "Chaos Bag" then
chaosbag = getObjectFromGUID(v.getGUID())
break
end
end
if chaosbag == nil then printToColor("No chaos bag found", playerColor) end
return chaosbag
end
function getTokenCount(type) function getTokenCount(type)
if type == nil then type = mode end if type == nil then type = mode end
return "(" .. (numInPlay[type] - #tokensTaken[type]) .. "/" .. #tokensTaken[type] .. ")" return "(" .. (numInPlay[type] - #tokensTaken[type]) .. "/" .. #tokensTaken[type] .. ")"
@ -278,39 +248,13 @@ function addToken(type)
printToColor("10 tokens already in play, not adding any.", playerColor) printToColor("10 tokens already in play, not adding any.", playerColor)
return 0 return 0
end end
return spawnToken(type) numInPlay[type] = numInPlay[type] + 1
end printToAll("Adding " .. type .. " token " .. getTokenCount(type))
return Global.call("spawnChaosToken", type)
function spawnToken(type)
local chaosbag = getChaosBag()
if chaosbag == nil then
return 0
end
local pos = chaosbag.getPosition()
local obj = spawnObject({
type = 'Custom_Tile',
position = { pos.x, pos.y + 1, pos.z },
callback_function = function(obj)
obj.setName(type)
chaosbag.putObject(obj)
numInPlay[type] = numInPlay[type] + 1
printToAll("Adding " .. type .. " token " .. getTokenCount(type))
end
})
obj.setCustomObject({
type = 2,
image = IMAGE_URL[type],
thickness = 0.1,
})
obj.scale { 0.81, 1, 0.81 }
end end
function takeToken(type, remove) function takeToken(type, remove)
local chaosbag = getChaosBag() local chaosbag = Global.call("findChaosBag")
if chaosbag == nil then
broadcastToAll("Chaos bag not found!", "Red")
return 0
end
if not remove and not SEAL_CARD_MESSAGE then if not remove and not SEAL_CARD_MESSAGE then
broadcastToColor("For sealing tokens on cards try right-clicking on the card for seal options.", playerColor) broadcastToColor("For sealing tokens on cards try right-clicking on the card for seal options.", playerColor)
SEAL_CARD_MESSAGE = true SEAL_CARD_MESSAGE = true
@ -355,7 +299,7 @@ function returnToken(type)
printToColor("Couldn't find token " .. guid .. ", not returning to bag", playerColor) printToColor("Couldn't find token " .. guid .. ", not returning to bag", playerColor)
return 0 return 0
end end
local chaosbag = getChaosBag() local chaosbag = Global.call("findChaosBag")
if chaosbag == nil then if chaosbag == nil then
return 0 return 0
end end
@ -400,7 +344,7 @@ function addMenuOptions(playerColor, hoveredObject)
end end
function sealToken(type, playerColor, enemy) function sealToken(type, playerColor, enemy)
local chaosbag = getChaosBag() local chaosbag = Global.call("findChaosBag")
if chaosbag == nil then return end if chaosbag == nil then return end
local pos = enemy.getPosition() local pos = enemy.getPosition()
@ -425,7 +369,7 @@ function sealToken(type, playerColor, enemy)
end end
function releaseToken(type, playerColor, enemy) function releaseToken(type, playerColor, enemy)
local chaosbag = getChaosBag() local chaosbag = Global.call("findChaosBag")
if chaosbag == nil then return end if chaosbag == nil then return end
local tokens = sealedTokens[enemy.getGUID()] local tokens = sealedTokens[enemy.getGUID()]
if tokens == nil or #tokens == 0 then return end if tokens == nil or #tokens == 0 then return end

View File

@ -0,0 +1,14 @@
do
local BlessCurseManagerApi = {}
local GUID = "5933fb"
-- removes all taken tokens and resets the counts
BlessCurseManagerApi.removeTakenTokensAndReset = function()
local BlessCurseManager = getObjectFromGUID(GUID)
Wait.time(function() BlessCurseManager.call("removeType", "Bless") end, 0.05)
Wait.time(function() BlessCurseManager.call("removeType", "Curse") end, 0.10)
Wait.time(function() BlessCurseManager.call("doReset", "White") end, 0.15)
end
return BlessCurseManagerApi
end

View File

@ -1,9 +0,0 @@
-- automatically add correct names to tokens that enter the chaos bag
function filterObjectEnter(obj)
local props = obj.getCustomObject()
if props ~= nil and props.image ~= nil then
obj.setName(Global.call("getTokenName", { url = props.image }))
end
return true
end

View File

@ -36,6 +36,8 @@ local hideTitleSplashWaitFunctionId = nil
local playmatAPI = require("playermat/PlaymatApi") local playmatAPI = require("playermat/PlaymatApi")
local tokenManager = require("core/token/TokenManager") local tokenManager = require("core/token/TokenManager")
local playAreaAPI = require("core/PlayAreaApi") local playAreaAPI = require("core/PlayAreaApi")
local tokenArrangerApi = require("accessories/TokenArrangerApi")
local blessCurseManagerApi = require("chaosbag/BlessCurseManagerApi")
--------------------------------------------------------- ---------------------------------------------------------
-- data for tokens -- data for tokens
@ -49,87 +51,46 @@ TOKEN_DATA = {
clue = {image = "http://cloud-3.steamusercontent.com/ugc/1758068501357164917/1D06F1DC4D6888B6F57124BD2AFE20D0B0DA15A8/", scale = {0.15, 0.15, 0.15}} clue = {image = "http://cloud-3.steamusercontent.com/ugc/1758068501357164917/1D06F1DC4D6888B6F57124BD2AFE20D0B0DA15A8/", scale = {0.15, 0.15, 0.15}}
} }
IMAGE_TOKEN_MAP = { ID_URL_MAP = {
["https://i.imgur.com/nEmqjmj.png"] = "Elder Sign", ['p1'] = {name = "+1", url = 'https://i.imgur.com/uIx8jbY.png'},
["https://i.imgur.com/uIx8jbY.png"] = "+1", ['0'] = {name = "0", url = 'https://i.imgur.com/btEtVfd.png'},
["https://i.imgur.com/btEtVfd.png"] = "0", ['m1'] = {name = "-1", url = 'https://i.imgur.com/w3XbrCC.png'},
["https://i.imgur.com/w3XbrCC.png"] = "-1", ['m2'] = {name = "-2", url = 'https://i.imgur.com/bfTg2hb.png'},
["https://i.imgur.com/bfTg2hb.png"] = "-2", ['m3'] = {name = "-3", url = 'https://i.imgur.com/yfs8gHq.png'},
["https://i.imgur.com/yfs8gHq.png"] = "-3", ['m4'] = {name = "-4", url = 'https://i.imgur.com/qrgGQRD.png'},
["https://i.imgur.com/qrgGQRD.png"] = "-4", ['m5'] = {name = "-5", url = 'https://i.imgur.com/3Ym1IeG.png'},
["https://i.imgur.com/3Ym1IeG.png"] = "-5", ['m6'] = {name = "-6", url = 'https://i.imgur.com/c9qdSzS.png'},
["https://i.imgur.com/c9qdSzS.png"] = "-6", ['m7'] = {name = "-7", url = 'https://i.imgur.com/4WRD42n.png'},
["https://i.imgur.com/4WRD42n.png"] = "-7", ['m8'] = {name = "-8", url = 'https://i.imgur.com/9t3rPTQ.png'},
["https://i.imgur.com/9t3rPTQ.png"] = "-8", ['skull'] = {name = "Skull", url = 'https://i.imgur.com/stbBxtx.png'},
["https://i.imgur.com/stbBxtx.png"] = "Skull", ['cultist'] = {name = "Cultist", url = 'https://i.imgur.com/VzhJJaH.png'},
["https://i.imgur.com/VzhJJaH.png"] = "Cultist", ['tablet'] = {name = "Tablet", url = 'https://i.imgur.com/1plY463.png'},
["https://i.imgur.com/1plY463.png"] = "Tablet", ['elder'] = {name = "Elder Thing", url = 'https://i.imgur.com/ttnspKt.png'},
["https://i.imgur.com/ttnspKt.png"] = "Elder Thing", ['red'] = {name = "Auto-fail", url = 'https://i.imgur.com/lns4fhz.png'},
["https://i.imgur.com/lns4fhz.png"] = "Auto-fail", ['blue'] = {name = "Elder Sign", url = 'https://i.imgur.com/nEmqjmj.png'},
["http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/"] = "Bless", ['bless'] = {name = "Bless", url = 'http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/'},
["http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/"] = "Curse", ['curse'] = {name = "Curse", url = 'http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/'},
["http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/"] = "Frost" ['frost'] = {name = "Frost", url = 'http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/'}
} }
--------------------------------------------------------- ---------------------------------------------------------
-- data for chaos token stat tracker -- data for chaos token stat tracker
--------------------------------------------------------- ---------------------------------------------------------
local maxSquid = 0 local MAT_GUID_TO_COLOR = {
["Overall"] = "Overall",
MAT_GUID_TO_COLOUR = { ["8b081b"] = "White",
["8b081b"] = "White", ["bd0ff4"] = "Orange",
["bd0ff4"] = "Orange", ["383d8b"] = "Green",
["383d8b"] = "Green", ["0840d5"] = "Red"
["0840d5"] = "Red"
} }
local personalStats = { local tokenDrawingStats = {
["8b081b"] = {}, ["Overall"] = {},
["bd0ff4"] = {}, ["8b081b"] = {},
["383d8b"] = {}, ["bd0ff4"] = {},
["0840d5"] = {} ["383d8b"] = {},
} ["0840d5"] = {}
local overallStats = {
-- cultist
["https://i.imgur.com/VzhJJaH.png"] = 0,
-- skull
["https://i.imgur.com/stbBxtx.png"] = 0,
-- tablet
["https://i.imgur.com/1plY463.png"] = 0,
-- curse
["http://cloud-3.steamusercontent.com/ugc/1655601092778636039/2A25BD38E8C44701D80DD96BF0121DA21843672E/"] = 0,
-- tentacle
["https://i.imgur.com/lns4fhz.png"] = 0,
-- minus eight
["https://i.imgur.com/9t3rPTQ.png"] = 0,
-- minus seven
["https://i.imgur.com/4WRD42n.png"] = 0,
-- minus six
["https://i.imgur.com/c9qdSzS.png"] = 0,
-- minus five
["https://i.imgur.com/3Ym1IeG.png"] = 0,
-- minus four
["https://i.imgur.com/qrgGQRD.png"] = 0,
-- minus three
["https://i.imgur.com/yfs8gHq.png"] = 0,
-- minus two
["https://i.imgur.com/bfTg2hb.png"] = 0,
-- minus one
["https://i.imgur.com/w3XbrCC.png"] = 0,
-- zero
["https://i.imgur.com/btEtVfd.png"] = 0,
-- plus one
["https://i.imgur.com/uIx8jbY.png"] = 0,
-- elder thing
["https://i.imgur.com/ttnspKt.png"] = 0,
-- bless
["http://cloud-3.steamusercontent.com/ugc/1655601092778627699/339FB716CB25CA6025C338F13AFDFD9AC6FA8356/"] = 0,
-- elder sign
["https://i.imgur.com/nEmqjmj.png"] = 0,
-- frost
["http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/"] = 0,
} }
--------------------------------------------------------- ---------------------------------------------------------
@ -273,11 +234,22 @@ end
-- checks scripting zone for chaos bag -- checks scripting zone for chaos bag
function findChaosBag() function findChaosBag()
for _, item in ipairs(getObjectFromGUID("83ef06").getObjects()) do local chaosbag_zone = getObjectFromGUID("83ef06")
-- error handling: scripting zone not found
if chaosbag_zone == nil then
printToAll("Zone for chaos bag detection couldn't be found.", "Red")
return
end
for _, item in ipairs(chaosbag_zone.getObjects()) do
if item.getDescription() == "Chaos Bag" then if item.getDescription() == "Chaos Bag" then
return item return item
end end
end end
-- error handling: chaos bag not found
printToAll("Chaos bag couldn't be found.", "Red")
end end
function returnChaosTokens() function returnChaosTokens()
@ -291,22 +263,20 @@ end
-- are drawn or replaced a TTS bug can cause those tokens to vanish. Any functions which change the -- are drawn or replaced a TTS bug can cause those tokens to vanish. Any functions which change the
-- contents of the bag should check this method before doing so. -- contents of the bag should check this method before doing so.
-- This method will broadcast a message to all players if the bag is being searched. -- This method will broadcast a message to all players if the bag is being searched.
-- @return Boolean. True if the bag is manipulated, false if it should be blocked. ---@return Boolean. True if the bag is manipulated, false if it should be blocked.
function canTouchChaosTokens() function canTouchChaosTokens()
for color, searching in pairs(bagSearchers) do for color, searching in pairs(bagSearchers) do
if searching then if searching then
broadcastToAll("Someone is searching the chaos bag, can't touch the tokens", "Red") broadcastToAll("Someone is searching the chaos bag, can't touch the tokens.", "Red")
return false return false
end end
end end
return true return true
end end
function drawChaostoken(params) -- called by playermats (by the "Draw chaos token" button)
if not canTouchChaosTokens() then function drawChaosToken(params)
return if not canTouchChaosTokens() then return end
end
local mat = params[1] local mat = params[1]
local tokenOffset = params[2] local tokenOffset = params[2]
@ -321,6 +291,7 @@ function drawChaostoken(params)
end end
chaosTokensLastMat = mat chaosTokensLastMat = mat
-- if we have left clicked and have no tokens OR if we have right clicked -- if we have left clicked and have no tokens OR if we have right clicked
if isRightClick or #chaosTokens == 0 then if isRightClick or #chaosTokens == 0 then
if #chaosbag.getObjects() == 0 then return end if #chaosbag.getObjects() == 0 then return end
@ -329,11 +300,10 @@ function drawChaostoken(params)
-- add the token to the list, compute new position based on list length -- add the token to the list, compute new position based on list length
tokenOffset[1] = tokenOffset[1] + (0.17 * #chaosTokens) tokenOffset[1] = tokenOffset[1] + (0.17 * #chaosTokens)
local token = chaosbag.takeObject({ local token = chaosbag.takeObject({
index = 0,
position = mat.positionToWorld(tokenOffset), position = mat.positionToWorld(tokenOffset),
rotation = mat.getRotation(), rotation = mat.getRotation()
callback_function = function(obj) trackChaosToken(obj, mat.getGUID()) end
}) })
trackChaosToken(token.getName(), mat.getGUID())
chaosTokens[#chaosTokens + 1] = token chaosTokens[#chaosTokens + 1] = token
return return
else else
@ -356,64 +326,50 @@ end
-- chaos token stat tracker -- chaos token stat tracker
--------------------------------------------------------- ---------------------------------------------------------
function trackChaosToken(token, matGUID) function trackChaosToken(tokenName, matGUID)
local image = token.getCustomObject().image tokenDrawingStats["Overall"][tokenName] = (tokenDrawingStats["Overall"][tokenName] or 0) + 1
overallStats[image] = (overallStats[image] or 0) + 1 tokenDrawingStats[matGUID][tokenName] = (tokenDrawingStats[matGUID][tokenName] or 0) + 1
personalStats[matGUID][image] = (personalStats[matGUID][image] or 0) + 1
end end
-- Left-click: print stats, Right-click: reset stats
function handleStatTrackerClick(_, _, isRightClick) function handleStatTrackerClick(_, _, isRightClick)
if isRightClick then if isRightClick then
resetChaosTokenStats() for key, _ in pairs(tokenDrawingStats) do
tokenDrawingStats[key] = {}
end
else else
printChaosTokenStats() local squidKing = "Nobody"
end local maxSquid = 0
end local playerColor, playerName
for key, personalStats in pairs(tokenDrawingStats) do
if personalStats ~= {} then
if key == "Overall" then
playerColor = "White"
playerName = "Overall"
else
playerColor = MAT_GUID_TO_COLOR[key]
playerName = Player[playerColor].steam_name or playerColor
function resetChaosTokenStats() local playerSquidCount = personalStats["Auto-fail"] or 0
for key, _ in pairs(overallStats) do if playerSquidCount > maxSquid then
overallStats[key] = 0 squidKing = playerName
end maxSquid = playerSquidCount
for playerKey, _ in pairs(personalStats) do end
for key, value in pairs(overallStats) do end
personalStats[playerKey][key] = value
end printToAll("------------------------------")
end printToAll(playerName .. " Stats", playerColor)
end
for tokenName, value in pairs(personalStats) do
function printChaosTokenStats() if value then
local squidKing = "Nobody" printToAll(tokenName .. ': ' .. tostring(value))
printToAll("") end
printToAll("Overall Stats") end
printToAll("------------------------------") end
printNonZeroTokenPairs(overallStats)
printToAll("")
printToAll("Individual Stats")
printToAll("------------------------------")
for matGUID, _ in pairs(personalStats) do
local playerColour = MAT_GUID_TO_COLOUR[matGUID]
local playerSquidCount = personalStats[matGUID]["https://i.imgur.com/lns4fhz.png"] or 0
local playerName = playerColour
if Player[playerColour].seated then
playerName = Player[playerColour].steam_name
end
printToAll(playerName .. " Stats", playerColour)
printNonZeroTokenPairs(personalStats[matGUID])
if playerSquidCount > maxSquid then
squidKing = playerName
maxSquid = playerSquidCount
end
end
printToAll(squidKing .. " is an auto-fail magnet.", {255, 0, 0})
end
function printNonZeroTokenPairs(theTable)
for key, value in pairs(theTable) do
if value ~= 0 then
printToAll(IMAGE_TOKEN_MAP[key] .. ': ' .. tostring(value))
end end
printToAll("------------------------------")
printToAll(squidKing .. " is an auto-fail magnet.", {255, 0, 0})
end end
end end
@ -474,63 +430,44 @@ end
-- called for adding chaos tokens -- called for adding chaos tokens
---@param object object Usually "self" ---@param object object Usually "self"
---@param key string Name of the scenario ---@param key string Name of the scenario
---@param mode string diffculty (e.g. "hard" or "expert") ---@param mode string difficulty (e.g. "hard" or "expert")
function fillContainer(args) function fillContainer(args)
chaosbag = findChaosBag() local data = getDataValue('modeData', args.key)
if data == nil then return end
if chaosbag ~= nil then local value = data[args.mode]
local data = getDataValue('modeData', args.key) if value == nil or value.token == nil then return end
if data == nil then return end
local value = data[args.mode] local tokenList = {}
if value == nil or value.token == nil then return end
local pos = chaosbag.getPosition() for _, tokenId in ipairs(value.token) do
if args.object ~= nil then table.insert(tokenList, tokenId)
pos = args.object.getPosition() end
if value.append ~= nil then
for _, tokenId in ipairs(value.append) do
table.insert(tokenList, tokenId)
end end
end
-- empty the chaos bag -- randomly choose tokens for specific Carcosa scenarios in standalone
for _, item in ipairs(chaosbag.getObjects()) do if value.random then
destroyObject(chaosbag.takeObject({})) local n = #value.random
end if n > 0 then
for _, tokenId in ipairs(value.random[math.random(1, n)]) do
for _, token in ipairs(value.token) do table.insert(tokenList, tokenId)
local obj = spawnChaosToken(token, pos)
if obj ~= nil then
chaosbag.putObject(obj)
end end
end end
end
if value.append ~= nil then setChaosBagState(tokenList)
for _, token in ipairs(value.append) do
local obj = spawnChaosToken(token, pos)
if obj ~= nil then
chaosbag.putObject(obj)
end
end
end
-- randomly choose tokens for specific Carcosa scenarios in standalone if value.message then
if value.random then broadcastToAll(value.message)
local n = #value.random end
if n > 0 then
for _, token in ipairs(value.random[math.random(1, n)]) do
local obj = spawnChaosToken(token, pos)
if obj ~= nil then
chaosbag.putObject(obj)
end
end
end
end
if value.message then if value.warning then
broadcastToAll(value.message) broadcastToAll(value.warning, { 1, 0.5, 0.5 })
end
if value.warning then
broadcastToAll(value.warning, { 1, 0.5, 0.5 })
end
end end
end end
@ -555,52 +492,112 @@ function getDataValue(storage, key)
end end
end end
function spawnChaosToken(id, pos) -- respawns the chaos bag with a new state of tokens
local url = getChaosTokenImageURL(id) ---@param tokenList Table List of chaos token ids
if url ~= '' then function setChaosBagState(tokenList)
local obj = spawnObject({ if not canTouchChaosTokens() then return end
local chaosbag = findChaosBag()
local chaosbagData = chaosbag.getData()
local reserveData = getObjectFromGUID("106418").getData()
local tokenCache = {}
local containedObjects = {}
-- create a temporary copy of the data for each chaos token
for _, objData in ipairs(reserveData.ContainedObjects) do
tokenCache[objData.Nickname] = objData
end
-- iterate over tokenlist and insert specified tokens into new table
for _, tokenId in ipairs(tokenList) do
local tokenName = ID_URL_MAP[tokenId].name
table.insert(containedObjects, tokenCache[tokenName])
end
-- overwrite chaos bag content and respawn it
chaosbagData.ContainedObjects = containedObjects
chaosbag.destruct()
spawnObjectData({data = chaosbagData})
-- remove tokens that are still in play
for _, token in pairs(chaosTokens) do
if token ~= nil then token.destruct() end
end
chaosTokens = {}
chaosTokensLastMat = nil
-- reset bless / curse manager
blessCurseManagerApi.removeTakenTokensAndReset()
printToAll("Chaos bag set to chosen difficulty.", "Green")
end
-- spawns the specified chaos token and puts it into the chaos bag
---@param id String ID of the chaos token
function spawnChaosToken(id)
if not canTouchChaosTokens() then return end
id = id:lower()
local chaosbag = findChaosBag()
local url = ID_URL_MAP[id].url or ""
if url ~= "" then
return spawnObject({
type = 'Custom_Tile', type = 'Custom_Tile',
position = {pos.x, pos.y + 3, pos.z}, position = { 0.49, 3, 0 },
rotation = {0, 260, 0} scale = { 0.81, 1.0, 0.81 },
}) rotation = {0, 270, 0},
obj.setCustomObject({ callback_function = function(obj)
obj.setName(ID_URL_MAP[id].name)
chaosbag.putObject(obj)
tokenArrangerApi.layout()
end
}).setCustomObject({
type = 2, type = 2,
image = url, image = url,
thickness = 0.1 thickness = 0.1
}) })
obj.scale {0.81, 1, 0.81}
obj.setName(getTokenName({ url=url }))
return obj
end end
end end
-- chaos bag needs this for renaming chaos tokens -- removes the specified chaos token from the chaos bag
function getTokenName(params) ---@param id String ID of the chaos token
local name = IMAGE_TOKEN_MAP[params.url] function removeChaosToken(id)
if name == nil then name = "" end if not canTouchChaosTokens() then return end
return name
local tokens = {}
local chaosbag = findChaosBag()
local name = ID_URL_MAP[id].name
for _, v in ipairs(chaosbag.getObjects()) do
if v.name == name then table.insert(tokens, v.guid) end
end
-- error handling: no matching token found
if #tokens == 0 then
printToAll("No " .. name .. " tokens in the chaos bag.", "Yellow")
return
end
chaosbag.takeObject({
guid = tokens[1],
smooth = false,
callback_function = function(obj)
obj.destruct()
tokenArrangerApi.layout()
end
})
printToAll("Removing " .. name .. " token (in bag: " .. #tokens - 1 .. ")", "White")
end end
-- returns the image url for a chaos token (identified by the "id") -- empty the chaos bag
function getChaosTokenImageURL(id) function emptyChaosBag()
if id == 'p1' then return 'https://i.imgur.com/uIx8jbY.png' end if not canTouchChaosTokens() then return end
if id == '0' then return 'https://i.imgur.com/btEtVfd.png' end
if id == 'm1' then return 'https://i.imgur.com/w3XbrCC.png' end local chaosbag = findChaosBag()
if id == 'm2' then return 'https://i.imgur.com/bfTg2hb.png' end for _, object in ipairs(chaosbag.getObjects()) do
if id == 'm3' then return 'https://i.imgur.com/yfs8gHq.png' end chaosbag.takeObject({callback_function = function(item) item.destruct() end})
if id == 'm4' then return 'https://i.imgur.com/qrgGQRD.png' end end
if id == 'm5' then return 'https://i.imgur.com/3Ym1IeG.png' end
if id == 'm6' then return 'https://i.imgur.com/c9qdSzS.png' end
if id == 'm7' then return 'https://i.imgur.com/4WRD42n.png' end
if id == 'm8' then return 'https://i.imgur.com/9t3rPTQ.png' end
if id == 'skull' then return 'https://i.imgur.com/stbBxtx.png' end
if id == 'cultist' then return 'https://i.imgur.com/VzhJJaH.png' end
if id == 'tablet' then return 'https://i.imgur.com/1plY463.png' end
if id == 'elder' then return 'https://i.imgur.com/ttnspKt.png' end
if id == 'red' then return 'https://i.imgur.com/lns4fhz.png' end
if id == 'blue' then return 'https://i.imgur.com/nEmqjmj.png' end
if id == 'frost' then return 'http://cloud-3.steamusercontent.com/ugc/1858293462583104677/195F93C063A8881B805CE2FD4767A9718B27B6AE/' end
return ''
end end
--------------------------------------------------------- ---------------------------------------------------------

View File

@ -95,7 +95,7 @@ function onLoad(save_state)
}) })
self.createButton({ self.createButton({
click_function = "drawChaostokenButton", click_function = "drawChaosTokenButton",
function_owner = self, function_owner = self,
position = {1.85, 0, -0.74}, position = {1.85, 0, -0.74},
rotation = {0, -45, 0}, rotation = {0, -45, 0},
@ -688,8 +688,8 @@ end
-- calls to 'Global' / functions for calls from outside -- calls to 'Global' / functions for calls from outside
--------------------------------------------------------- ---------------------------------------------------------
function drawChaostokenButton(_, _, isRightClick) function drawChaosTokenButton(_, _, isRightClick)
Global.call("drawChaostoken", {self, DRAWN_CHAOS_TOKEN_OFFSET, isRightClick}) Global.call("drawChaosToken", {self, DRAWN_CHAOS_TOKEN_OFFSET, isRightClick})
end end
function drawEncountercard(_, _, isRightClick) function drawEncountercard(_, _, isRightClick)