├── .emmyrc.json
├── .gitattributes
├── .gitignore
├── Clever Notecard
├── notecard.lua
└── notecard.xml
├── Commander Gen 2
├── DEPRECATED
│ ├── Boss
│ │ ├── boss.lua
│ │ └── boss.xml
│ └── Token
│ │ ├── token.lua
│ │ └── token.xml
├── Initiative Stuff
│ ├── initiative preset
│ │ ├── epic.lua
│ │ └── lair.lua
│ ├── initiative-mat.lua
│ ├── initiative-mat.xml
│ └── initiative-token.lua
├── Monster Token
│ ├── monster.lua
│ ├── ui.lua
│ └── ui.xml
├── NPC Commander.v2.lua
└── README.md
├── DEPRECATED
├── NPC Commander v0.lua
├── README.md
├── notecard.lua
├── rolling-block.lua
├── token-boss.lua
├── token-boss.xml
├── token-tracker.lua
├── token.lua
└── token.xml
├── HUD
├── Assets
│ ├── Widget-flipped-open.png
│ ├── Widget-flipped-overlay.png
│ ├── Widget-flipper.png
│ ├── Widget-open.png
│ ├── Widget-overlay.png
│ ├── Widget.png
│ ├── ally-open.png
│ ├── ally.png
│ ├── enemy-open.png
│ ├── enemy.png
│ ├── neutral-open.png
│ ├── neutral.png
│ ├── player-open.png
│ ├── player.png
│ ├── player_request.png
│ ├── reminder-closed.png
│ ├── reminder-glow.png
│ └── reminder-open.png
├── HUD.lua
├── HUD.xml
├── Projector-Global.lua
├── Projector-Global.xml
├── average-hud.lua
├── average-hud.xml
├── breaker.lua
├── breaker.xml
├── epic-reminder.lua
├── epic-reminder.xml
├── initiative-hud.lua
├── initiative-hud.xml
├── reminder-hud.lua
└── reminder-hud.xml
├── LICENSE
├── Projector.lua
├── README.md
├── Utility tools
├── Color Switcher Tool.lua
├── README.md
├── empty-container.lua
├── mansion-mover.lua
└── memo-viewer.lua
├── VERSIONS
├── average-button.lua
├── average-notecard.lua
├── bag-peeker.lua
├── bundle-map.lua
├── card creator
├── card creator-2.0.lua
├── card creator.lua
└── card creator.xml
├── command-manager.lua
├── debug-button.lua
├── dice-mat.lua
├── dice-rolling-tool.lua
├── exploding_dice
├── .exploding-strip.lua
├── dice-bundler.lua
├── exploding-dice.lua
└── exploding-note.lua
├── hide-me.lua
├── image-changer.lua
├── interactable.lua
├── item-positioner.lua
├── item-stack.lua
├── macro-maker.lua
├── map-positioner.lua
├── notecard 2.0.lua
├── pin-positioner.lua
├── pin.lua
├── pin.xml
├── player_manager
├── conditions
│ ├── blinded.png
│ ├── charmed.png
│ ├── concentration.png
│ ├── deafened.png
│ ├── frightened.png
│ ├── grappled.png
│ ├── incapacitated.png
│ ├── invisible.png
│ ├── on fire.png
│ ├── paralyzed.png
│ ├── petrified.png
│ ├── poisoned.png
│ ├── restrained.png
│ └── stunned.png
├── move-token-snippet.lua
├── move-token-snippet.min.lua
├── player-manager-area.lua
├── player-manager-area.min.lua
├── player-manager.lua
├── player-manager.xml
├── readme.md
├── shapes
│ ├── circle.png
│ ├── cone.png
│ └── cube.png
├── state-player-manager.lua
└── state-player-manager.min.lua
├── potion maker
├── potion maker.lua
└── potion maker.xml
├── reset-characters.lua
├── script-updater.lua
├── table-updater.lua
├── table-updater.xml
└── tarot-cards.lua
/.emmyrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "diagnostics": {
3 | "disable": ["undefined-global"]
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /.vscode/
--------------------------------------------------------------------------------
/Clever Notecard/notecard.lua:
--------------------------------------------------------------------------------
1 | --[[StartXML
2 |
3 |
4 |
5 |
6 |
7 | Title
8 | Description
9 | StopXML--xml]]
10 |
11 |
12 | function loadXML()
13 | local script = self.getLuaScript()
14 | local xml = script:sub(script:find("StartXML")+8, script:find("StopXML")-1)
15 | self.UI.setXml(xml)
16 | Wait.frames(function() setData() end, 20)
17 | end
18 |
19 | local commander = "878b50"
20 |
21 | function onload()
22 | loadXML()
23 |
24 | local data = {
25 | click_function = "parse",
26 | function_owner = self,
27 | label = "Parse",
28 | position = {1.92, 0.1, 1.33},
29 | scale = {0.3, 0.3, 0.3},
30 | width = 1200,
31 | height = 500,
32 | font_size = 400,
33 | color = {0.1341, 0.1341, 0.1341, 1},
34 | font_color = {1, 1, 1, 1},
35 | tooltip = "Parse"
36 | }
37 |
38 | self.addContextMenuItem("Set Commander", function(player)
39 | if Player[player].admin then
40 | local guid = self.getName()
41 | local obj = getObjectFromGUID(guid)
42 | if not obj then
43 | broadcastToColor("You must write the NPC Commander ID as the name of the notecard.", "Black", Color.White)
44 | else
45 | self.memo = guid
46 | end
47 | end
48 | end, false)
49 | self.createButton(data)
50 | end
51 |
52 | function onHover()
53 | setData()
54 | end
55 |
56 | function setData()
57 | self.UI.setAttribute("title", "text", self.getName())
58 | self.UI.setAttribute("description", "text", self.getDescription())
59 | end
60 |
61 | function parse()
62 | if self.getDescription() ~= "" and self.getName() ~= "" then
63 | local vars = JSON.decode(self.getDescription())
64 | local npc_commander = getObjectFromGUID(self.memo or commander)
65 |
66 | if vars.name then
67 | npc_commander.call("setName", {input = vars.name})
68 | end
69 |
70 | if vars.ini then
71 | npc_commander.call("setINI", {input = vars.ini})
72 | end
73 |
74 | if vars.hp then
75 | npc_commander.call("setHP", {input = vars.hp})
76 | end
77 |
78 | if vars.ac then
79 | npc_commander.call("setAC", {input = vars.ac})
80 | end
81 |
82 | if vars.mov then
83 | npc_commander.call("setMovement", {input = vars.mov})
84 | end
85 |
86 | if vars.size then
87 | npc_commander.call("setSize", {input = vars.size})
88 | end
89 |
90 | if vars.image then
91 | npc_commander.setDescription(vars.image)
92 | npc_commander.call("toggleIsBoss", {input = true})
93 | else
94 | npc_commander.call("toggleIsBoss", {input = false})
95 | end
96 |
97 | if vars.side then
98 | npc_commander.call("setSide", {input = vars.side})
99 | else
100 | npc_commander.call("setSide", {input = "enemy"})
101 | end
102 |
103 | if vars.extra then
104 | npc_commander.call("setExtraParams", vars.extra)
105 | else
106 | npc_commander.call("setExtraParams", nil)
107 | end
108 |
109 | if self.getGMNotes() ~= "" then
110 | -- this means i have multiple that i want to make
111 | local number = tonumber(self.getGMNotes())
112 | npc_commander.call("setNumberToCreate", {input = number})
113 | else
114 | npc_commander.call("setNumberToCreate", {input = 1})
115 | end
116 | end
117 | end
118 |
119 | function mysplit(inputstr, sep)
120 | if sep == nil then
121 | sep = "%s"
122 | end
123 | local t = {}
124 | i = 1
125 | for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
126 | t[i] = str
127 | i = i + 1
128 | end
129 | return t
130 | end
131 |
--------------------------------------------------------------------------------
/Clever Notecard/notecard.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Title
7 | Description
--------------------------------------------------------------------------------
/Commander Gen 2/DEPRECATED/Boss/boss.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/Commander Gen 2/DEPRECATED/Token/token.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
67 |
68 |
69 |
70 |
--------------------------------------------------------------------------------
/Commander Gen 2/Initiative Stuff/initiative preset/epic.lua:
--------------------------------------------------------------------------------
1 | --Runs when the scripted button inside the button is clicked
2 | function buttonPress()
3 | if lockout == false then
4 | local gm = self.getGMNotes()
5 |
6 | if gm ~= nil then
7 | local bag = getObjectFromGUID(gm)
8 | local pos = self.getPosition()
9 | pos.y = pos.y + 3
10 | local takeParams = {
11 | position = pos,
12 | rotation = {0, 0, 0},
13 | callback_function = function(spawned)
14 | Wait.time(
15 | function()
16 | spawned.call(
17 | "_init",
18 | {
19 | input = {
20 | name = "Epic Die",
21 | modifier = 50,
22 | pawn = "",
23 | side = "epic",
24 | static = true
25 | }
26 | }
27 | )
28 | end,
29 | 1
30 | )
31 | end
32 | }
33 | bag.takeObject(takeParams)
34 | end
35 |
36 | self.AssetBundle.playTriggerEffect(0) --triggers animation/sound
37 | lockout = true --locks out the button
38 | startLockoutTimer() --Starts up a timer to remove lockout
39 | end
40 | end
41 |
42 | --Runs on load, creates button and makes sure the lockout is off
43 | function onload()
44 | self.createButton(
45 | {
46 | label = "Big Red Button\n\nBy: MrStump",
47 | click_function = "buttonPress",
48 | function_owner = self,
49 | position = {0, 0.25, 0},
50 | height = 1400,
51 | width = 1400
52 | }
53 | )
54 | lockout = false
55 | end
56 |
57 | --Starts a timer that, when it ends, will unlock the button
58 | function startLockoutTimer()
59 | Timer.create({identifier = self.getGUID(), function_name = "unlockLockout", delay = 0.5})
60 | end
61 |
62 | --Unlocks button
63 | function unlockLockout()
64 | lockout = false
65 | end
66 |
67 | --Ends the timer if the object is destroyed before the timer ends, to prevent an error
68 | function onDestroy()
69 | Timer.destroy(self.getGUID())
70 | end
71 |
--------------------------------------------------------------------------------
/Commander Gen 2/Initiative Stuff/initiative preset/lair.lua:
--------------------------------------------------------------------------------
1 | --Runs when the scripted button inside the button is clicked
2 | function buttonPress()
3 | if lockout == false then
4 | local gm = self.getGMNotes()
5 |
6 | if gm ~= nil then
7 | local bag = getObjectFromGUID(gm)
8 | local pos = self.getPosition()
9 | pos.y = pos.y + 3
10 | local takeParams = {
11 | position = pos,
12 | rotation = {0, 0, 0},
13 | callback_function = function(spawned)
14 | Wait.time(
15 | function()
16 | spawned.call(
17 | "_init",
18 | {
19 | input = {
20 | name = "Lair",
21 | modifier = 20,
22 | pawn = "",
23 | side = "lair",
24 | static = true
25 | }
26 | }
27 | )
28 | end,
29 | 1
30 | )
31 | end
32 | }
33 | bag.takeObject(takeParams)
34 | end
35 |
36 | self.AssetBundle.playTriggerEffect(0) --triggers animation/sound
37 | lockout = true --locks out the button
38 | startLockoutTimer() --Starts up a timer to remove lockout
39 | end
40 | end
41 |
42 | --Runs on load, creates button and makes sure the lockout is off
43 | function onload()
44 | self.createButton(
45 | {
46 | label = "Big Red Button\n\nBy: MrStump",
47 | click_function = "buttonPress",
48 | function_owner = self,
49 | position = {0, 0.25, 0},
50 | height = 1400,
51 | width = 1400
52 | }
53 | )
54 | lockout = false
55 | end
56 |
57 | --Starts a timer that, when it ends, will unlock the button
58 | function startLockoutTimer()
59 | Timer.create({identifier = self.getGUID(), function_name = "unlockLockout", delay = 0.5})
60 | end
61 |
62 | --Unlocks button
63 | function unlockLockout()
64 | lockout = false
65 | end
66 |
67 | --Ends the timer if the object is destroyed before the timer ends, to prevent an error
68 | function onDestroy()
69 | Timer.destroy(self.getGUID())
70 | end
71 |
--------------------------------------------------------------------------------
/Commander Gen 2/Initiative Stuff/initiative-mat.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Commander Gen 2/Initiative Stuff/initiative-token.lua:
--------------------------------------------------------------------------------
1 | local myToken = nil
2 | local myData = nil
3 | local mySide = nil
4 | local initialized = false
5 | local restored = false
6 |
7 | local myName = ""
8 | local myRoll = -1
9 |
10 | local _states = {
11 | ["player"] = {color = {0, 0, 0.545098}},
12 | ["enemy"] = {color = {0.517647, 0, 0.098039}},
13 | ["ally"] = {color = {0.039216, 0.368627, 0.211765}},
14 | ["neutral"] = {color = {0.764706, 0.560784, 0}},
15 | ["lair"] = {color = {0.823529, 0.819608, 0.52549}},
16 | ["epic"] = {color = {0.701961, 0.54902, 1}}
17 | }
18 |
19 | function click_textbox(obj, color, input, stillEditing)
20 | if stillEditing == false then
21 | updateSave(input)
22 | end
23 | end
24 |
25 | function find_token(obj, color)
26 | if not myToken then
27 | return
28 | end
29 | --Player[color].pingTable(myToken.getPosition())
30 | myToken.call("toggleVisualize", {input = true, color = color})
31 | end
32 |
33 | local textbox = {
34 | input_function = "click_textbox",
35 | function_owner = self,
36 | label = "Name",
37 | position = {-1.2, 0.1, 0},
38 | scale = {1.4, 0.5, 1.4},
39 | width = 2300,
40 | height = 700,
41 | font_size = 300,
42 | alignment = 3,
43 | custom = {
44 | color = 0,
45 | 0,
46 | 0.545098
47 | }
48 | }
49 |
50 | function onLoad(save_state)
51 | local color = {0, 0, 0.545098}
52 | local value = ""
53 | myData = JSON.decode(save_state)
54 | if myData ~= nil then
55 | value = myData['v']
56 | myToken = getObjectFromGUID(myData.t)
57 | if myData.c ~= nil then
58 | color = myData.c
59 | end
60 |
61 | local lines = getLines(value)
62 | myName = lines[1]
63 | myRoll = lines[2]
64 | end
65 | textbox.custom.color = color
66 | -- textbox.label = value
67 |
68 | self.createInput(
69 | {
70 | input_function = "click_textbox",
71 | function_owner = textbox.function_owner,
72 | label = textbox.label,
73 | position = textbox.position,
74 | scale = textbox.scale,
75 | width = textbox.width,
76 | height = textbox.height,
77 | font_size = textbox.font_size,
78 | alignment = textbox.alignment,
79 | value = value
80 | }
81 | )
82 |
83 | self.editInput({index = 0, value = value})
84 |
85 | self.createButton(
86 | {
87 | click_function = "find_token",
88 | function_owner = self,
89 | label = " ",
90 | position = {3.3, 0.2, 0},
91 | scale = {0.6, 0.6, 0.6},
92 | width = 680,
93 | height = 680,
94 | font_size = 0,
95 | color = {0.25, 0.25, 0.25, 1},
96 | tooltip = " ",
97 | alignment = 3
98 | }
99 | )
100 |
101 | self.setColorTint(color)
102 |
103 | return JSON.encode(myData)
104 | end
105 |
106 | -- function onSave()
107 | -- print(myName)
108 | -- self.getInputs()[1].value = myName
109 | -- return
110 | -- end
111 |
112 | function onObjectDestroy(destroyedObj)
113 | if myToken then
114 | local gid = destroyedObj.getGUID()
115 | local mgid = myToken.getGUID()
116 | if destroyedObj == myToken then
117 | self.destruct()
118 | end
119 | end
120 | end
121 |
122 | function _init(params)
123 | --initiative.call("_init",
124 | -- {input = {name = name, i = i, pawn = getObjectByID(id).obj.pawn.getGUID(), side = _side}})
125 | --log(params, "Initiative parameters:")
126 | myName = params.input.name
127 | local modifier = params.input.modifier
128 | local pawn = params.input.pawn
129 | local side = params.input.side
130 |
131 | local roll = math.random(1, 20)
132 | local final = roll + modifier
133 | if params.input.static then
134 | final = modifier
135 | end
136 |
137 | if final <= 0 then
138 | final = 1
139 | end
140 | myRoll = final
141 |
142 | self.editInput({index = 0, value = myName .. "\n" .. final})
143 | self.setDescription(myName .. "\n" .. final .. "\n" .. roll .. " + " .. modifier .. "\n" .. pawn)
144 |
145 | if pawn ~= nil then
146 | setToken({input = pawn})
147 | end
148 | setSide({side = side})
149 |
150 | updateSave(myName .. "\n" .. final)
151 | end
152 |
153 | function setToken(params)
154 | myToken = getObjectFromGUID(params.input)
155 | end
156 |
157 | function updateSave(value)
158 | local color = self.getColorTint()
159 | local guid = nil
160 | if myToken then
161 | guid = myToken.getGUID()
162 | end
163 | myData = {
164 | v = value,
165 | t = guid,
166 | c = {color.r, color.g, color.b}
167 | }
168 | -- log(myData)
169 | local save_data = JSON.encode(myData)
170 | self.script_state = save_data
171 | return save_data
172 | end
173 |
174 | function checkUpdates()
175 | if myToken then
176 | local name = myToken.getInputs()[1].value
177 | if name ~= myName then
178 | myName = name
179 | self.editInput({index = 0, value = myName .. "\n" .. myRoll})
180 | updateSave(myName .. "\n" .. myRoll)
181 | end
182 | end
183 | end
184 |
185 | function onSave()
186 | return updateSave(self.getInputs()[1].value)
187 | end
188 |
189 | function setSide(params)
190 | self.setColorTint(_states[params.side].color)
191 | self.setName(params.side .. "_token")
192 | self.tooltip = false
193 | end
194 |
195 | function getLines(text)
196 | local returner = {}
197 | for s in text:gmatch("[^\r\n]+") do
198 | table.insert(returner, s)
199 | end
200 | return returner
201 | end
--------------------------------------------------------------------------------
/Commander Gen 2/Monster Token/ui.lua:
--------------------------------------------------------------------------------
1 | --[[StartXML
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
65 |
66 |
67 |
68 | StopXML--xml]]
--------------------------------------------------------------------------------
/Commander Gen 2/Monster Token/ui.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/Commander Gen 2/README.md:
--------------------------------------------------------------------------------
1 | This is the main tool that you will use for the most part. If you want to understand most of the things that are used in the project then this is where you should start.
2 |
--------------------------------------------------------------------------------
/DEPRECATED/README.md:
--------------------------------------------------------------------------------
1 | ### Deprecated stuff folder
2 | Even though all this stuff has not been used for a very long time as they have been replaced by a much better version of themselves, this is kept here for the sake of keeping working code in the github itself.
--------------------------------------------------------------------------------
/DEPRECATED/notecard.lua:
--------------------------------------------------------------------------------
1 | --local commander = "9d42ad"
2 | local commander = "878b50"
3 |
4 | function onLoad()
5 | local data = {
6 | click_function = "parse",
7 | function_owner = self,
8 | label = "Parse",
9 | position = {-0.39, 2.4, -0.43},
10 | rotation = {0, 180, 0},
11 | scale = {0.1, 1, 0.18},
12 | width = 1100,
13 | height = 400,
14 | font_size = 400,
15 | color = {0.1341, 0.1341, 0.1341, 1},
16 | font_color = {1, 1, 1, 1}
17 | }
18 | self.createButton(data)
19 | end
20 |
21 | --/|2|r50-68|12|6|2d6+4
22 |
23 | function parse()
24 | if self.getDescription() ~= "" and self.getName() ~= "" then
25 | local stuff = mysplit(mysplit(self.getDescription(), "\n")[1], "|")
26 | local npc_commander = getObjectFromGUID(commander)
27 | npc_commander.call("setName", {input = stuff[1]})
28 | npc_commander.call("setINI", {input = stuff[2]})
29 | npc_commander.call("setHP", {input = stuff[3]})
30 | npc_commander.call("setAC", {input = stuff[4]})
31 | npc_commander.call("setATK", {input = stuff[5]})
32 | npc_commander.call("setDMG", {input = stuff[6]})
33 |
34 | if stuff[7] then
35 | npc_commander.call("setMovement", {input = stuff[7]})
36 | end
37 |
38 | if stuff[8] then
39 | npc_commander.call("setSize", {input = stuff[8]})
40 | end
41 |
42 | local second_line = mysplit(self.getDescription(), "\n")[2]
43 | if second_line ~= nil and second_line ~= "" then
44 | -- this means it is a boss
45 | npc_commander.setDescription(second_line)
46 | npc_commander.call("toggleIsBoss", {input = true})
47 | else
48 | npc_commander.call("toggleIsBoss", {input = false})
49 | end
50 |
51 | if self.getGMNotes() ~= "" then
52 | -- this means i have multiple that i want to make
53 | local number = tonumber(self.getGMNotes())
54 | npc_commander.call("setNumberToCreate", {input = number})
55 | end
56 | end
57 | end
58 |
59 | function mysplit(inputstr, sep)
60 | if sep == nil then
61 | sep = "%s"
62 | end
63 | local t = {}
64 | i = 1
65 | for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
66 | t[i] = str
67 | i = i + 1
68 | end
69 | return t
70 | end
71 |
--------------------------------------------------------------------------------
/DEPRECATED/rolling-block.lua:
--------------------------------------------------------------------------------
1 | local _sz = "876993"
2 | local reference = nil
3 |
4 | self.createInput({
5 | input_function = "name",
6 | function_owner = self,
7 | label = "Name",
8 | alignment = 3,
9 | position = {x=0, y=0.5, z=-0.3},
10 | rotation = {0, 0, 0},
11 | width = 1600,
12 | height = 400,
13 | font_size = 200,
14 | validation = 1,
15 | scale = {0.3, 0.5, 0.4},
16 | })
17 |
18 | self.createInput({
19 | input_function = "value",
20 | function_owner = self,
21 | label = "V",
22 | alignment = 3,
23 | position = {x=-0.4, y=0.5, z=0.15},
24 | rotation = {0, 0, 0},
25 | width = 300,
26 | height = 300,
27 | font_size = 260,
28 | validation = 2,
29 | scale = {0.3, 0.3, 0.6},
30 | })
31 |
32 | self.createInput({
33 | input_function = "modifier",
34 | function_owner = self,
35 | label = "M",
36 | alignment = 3,
37 | position = {x=-0.2, y=0.5, z=0.15},
38 | rotation = {0, 0, 0},
39 | width = 300,
40 | height = 300,
41 | font_size = 260,
42 | validation = 2,
43 | scale = {0.3, 0.3, 0.6},
44 | })
45 |
46 | self.createInput({
47 | input_function = "name",
48 | function_owner = self,
49 | label = "R",
50 | alignment = 3,
51 | position = {x=0.1, y=0.5, z=0.15},
52 | rotation = {0, 0, 0},
53 | width = 580,
54 | height = 300,
55 | font_size = 260,
56 | validation = 1,
57 | scale = {0.3, 0.3, 0.6},
58 | })
59 |
60 | self.createButton({
61 | click_function = "roll_die",
62 | function_owner = self,
63 | label = "R",
64 | position = {0.4, 0.5, 0.15},
65 | scale = {0.3, 0.3, 0.6},
66 | width = 380,
67 | height = 300,
68 | font_size = 260,
69 | tooltip = "R",
70 | alignment = 3
71 | })
72 |
73 | function modifier(obj, color, input, stillEditing)
74 | if not stillEditing then
75 | local die = findDie()
76 | if die then
77 | die.setDescription(input)
78 | else
79 | broadcastToColor("delete me pls", "Black", {1,1,1})
80 | end
81 | updateResult()
82 | end
83 | end
84 |
85 | function findDie()
86 | if not reference then
87 | local name = getTop()
88 | local zone = getObjectFromGUID(_sz)
89 | local dices = zone.getObjects()
90 | for i=0, #dices do
91 | local die = dices[i]
92 | if die then
93 | if die.getName() == name then
94 | reference = die
95 | return reference
96 | end
97 | end
98 | end
99 | end
100 | return reference
101 | end
102 |
103 | function value(obj, color, input, stillEditing)
104 | if not stillEditing then
105 | updateResult()
106 | end
107 | end
108 |
109 | function updateModifier(params)
110 | self.editInput({index=2, value=params.input})
111 | updateResult()
112 | end
113 |
114 | function updateResult()
115 | self.editInput({index=3, value="= "..getValue() + getModifier()})
116 | end
117 |
118 | function getTop()
119 | return self.getInputs()[1].value
120 | end
121 | function getValue()
122 | return tonumber(self.getInputs()[2].value)
123 | end
124 | function getModifier()
125 | return tonumber(self.getInputs()[3].value)
126 | end
127 | function getResult()
128 | return tonumber(self.getInputs()[4].value)
129 | end
130 |
131 | function name()
132 | end
133 |
134 | function roll_die()
135 | local obj = findDie()
136 | obj.roll()
137 | local rollWatch = function() return obj.resting end
138 | local rollEnd = function()
139 | self.editInput({index=1, value = obj.getRotationValue()})
140 | updateResult()
141 | end
142 | Wait.condition(rollEnd, rollWatch)
143 | end
144 |
145 |
146 |
147 |
--------------------------------------------------------------------------------
/DEPRECATED/token-boss.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/DEPRECATED/token-tracker.lua:
--------------------------------------------------------------------------------
1 | -- textbox = {
2 | -- --[[
3 | -- pos = the position (pasted from the helper tool)
4 | -- rows = how many lines of text you want for this box
5 | -- width = how wide the text box is
6 | -- font_size = size of text. This and "rows" effect overall height
7 | -- label = what is shown when there is no text. "" = nothing
8 | -- value = text entered into box. "" = nothing
9 | -- alignment = Number to indicate how you want text aligned
10 | -- (1=Automatic, 2=Left, 3=Center, 4=Right, 5=Justified)
11 | -- ]]
12 | local _color = {1, 1, 1, 0.3}
13 | local _tracker_name = "npc_tracker"
14 |
15 | function onLoad()
16 | -- name
17 | self.createInput(
18 | {
19 | input_function = "none",
20 | function_owner = self,
21 | label = "Name",
22 | position = {0.6, 0.1, -0.6},
23 | scale = {0.6, 0.6, 0.7},
24 | width = 3000,
25 | height = 470,
26 | font_size = 400,
27 | color = {1, 1, 1, 0},
28 | font_color = {1, 1, 1, 100},
29 | alignment = 3,
30 | value = ""
31 | }
32 | )
33 |
34 | -- hp
35 | self.createInput(
36 | {
37 | input_function = "hp",
38 | function_owner = self,
39 | label = "HP",
40 | position = {-1.63, 0.1, 0.7},
41 | scale = {0.8, 0.5, 0.9},
42 | width = 500,
43 | height = 440,
44 | font_size = 400,
45 | color = _color,
46 | font_color = {0, 0, 0, 100},
47 | alignment = 3,
48 | value = ""
49 | }
50 | )
51 |
52 | -- ac
53 | self.createInput(
54 | {
55 | input_function = "ac",
56 | function_owner = self,
57 | label = "AC",
58 | position = {-0.43, 0.1, 0.7},
59 | scale = {0.8, 0.5, 0.9},
60 | width = 500,
61 | height = 440,
62 | font_size = 400,
63 | color = _color,
64 | font_color = {0, 0, 0, 100},
65 | alignment = 3,
66 | value = ""
67 | }
68 | )
69 |
70 | -- atk
71 | self.createInput(
72 | {
73 | input_function = "atk",
74 | function_owner = self,
75 | label = "ATK",
76 | position = {0.77, 0.1, 0.7},
77 | scale = {0.8, 0.5, 0.9},
78 | width = 500,
79 | height = 440,
80 | font_size = 150,
81 | color = _color,
82 | font_color = {0, 0, 0, 100},
83 | alignment = 3,
84 | value = ""
85 | }
86 | )
87 |
88 | self.createInput(
89 | {
90 | input_function = "dmg",
91 | function_owner = self,
92 | label = "DMG",
93 | position = {1.97, 0.1, 0.7},
94 | scale = {0.8, 0.5, 0.9},
95 | width = 500,
96 | height = 440,
97 | font_size = 150,
98 | color = _color,
99 | font_color = {0, 0, 0, 100},
100 | alignment = 3,
101 | value = ""
102 | }
103 | )
104 |
105 | self.createButton(
106 | {
107 | click_function = "none",
108 | function_owner = self,
109 | label = " ",
110 | position = {-1.9, 0.1, -0.62},
111 | scale = {0.5, 0.5, 0.5},
112 | width = 600,
113 | height = 600,
114 | font_size = 400
115 | }
116 | )
117 | end
118 |
119 | function none()
120 | end
121 |
122 | function hp(self, color, text, stillEditing)
123 | if not stillEditing then
124 | local size = convertSize(text)
125 | self.editInput({index = 1, font_size = size})
126 | end
127 | end
128 |
129 | function ac(self, color, text, stillEditing)
130 | if not stillEditing then
131 | local size = convertSize(text)
132 | self.editInput({index = 2, font_size = size})
133 | end
134 | end
135 |
136 | function atk(self, color, text, stillEditing)
137 | if not stillEditing then
138 | local size = convertSize(text)
139 | self.editInput({index = 3, font_size = size})
140 | end
141 | end
142 |
143 | function dmg(self, color, text, stillEditing)
144 | if not stillEditing then
145 | local size = convertSize(text)
146 | self.editInput({index = 4, font_size = size})
147 | end
148 | end
149 |
150 | function convertSize(input)
151 | if string.len(input) <= 2 then
152 | return 400
153 | elseif string.len(input) == 3 then
154 | return 300
155 | else
156 | return 150
157 | end
158 | end
159 |
160 | function setName(params)
161 | self.editInput({index = 0, value = params.input})
162 | end
163 |
164 | function setHP(params)
165 | self.editInput({index = 1, value = params.input})
166 | local size = convertSize(params.input)
167 | self.editInput({index = 1, font_size = size})
168 | end
169 | function setAC(params)
170 | self.editInput({index = 2, value = params.input})
171 | local size = convertSize(params.input)
172 | self.editInput({index = 2, font_size = size})
173 | end
174 | function setATK(params)
175 | self.editInput({index = 3, value = params.input})
176 | local size = convertSize(params.input)
177 | self.editInput({index = 3, font_size = size})
178 | end
179 | function setDMG(params)
180 | self.editInput({index = 4, value = params.input})
181 | local size = convertSize(params.input)
182 | self.editInput({index = 4, font_size = size})
183 | end
184 |
185 | function setColor(params)
186 | self.editButton({index = 0, color = params.input})
187 | end
188 |
189 | function order(params)
190 | local blockPosition = {x = 42.83, y = 1.5, z = -2.77}
191 | local zone = getObjectFromGUID(params.input)
192 | local objs = zone.getObjects()
193 | local x_diffence = 2.16
194 | local z_difference = 4.87
195 | local row = 1
196 | for i = 0, #objs do
197 | local obj = objs[i]
198 | if obj then
199 | if obj.getName() == _tracker_name then
200 | obj.setPositionSmooth(blockPosition, false, true)
201 | obj.setRotationSmooth({0, 90, 0}, false, true)
202 | if row == 1 then
203 | blockPosition.x = blockPosition.x + x_diffence
204 | row = row + 1
205 | elseif row == 2 then
206 | row = 1
207 | blockPosition.x = 42.83
208 | blockPosition.z = blockPosition.z + z_difference
209 | end
210 | end
211 | end
212 | end
213 | end
214 |
215 | --function mysplit(inputstr, sep)
216 | -- if sep == nil then
217 | -- sep = "%s"
218 | -- end
219 | -- local t={} ; i=1
220 | -- for str in string.gmatch(inputstr, "([^"..sep.."]+)") do
221 | -- t[i] = str
222 | -- i = i + 1
223 | -- end
224 | -- return t
225 | --end
226 | --
227 | --function getHP(text)
228 | -- local spl = mysplit(text, "\n")[1]
229 | -- return mysplit(spl, " ")[2]
230 | --end
231 | --
232 | --function getAC(text)
233 | -- local spl = mysplit(text, "\n")[2]
234 | -- return mysplit(spl, " ")[2]
235 | --end
236 | --function getATK(text)
237 | -- local spl = mysplit(text, "\n")[3]
238 | -- return mysplit(spl, " ")[2]
239 | --end
240 | --function getDMG(text)
241 | -- local spl = mysplit(text, "\n")[4]
242 | -- return mysplit(spl, " ")[2]
243 | --end
244 |
--------------------------------------------------------------------------------
/DEPRECATED/token.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/HUD/Assets/Widget-flipped-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/Widget-flipped-open.png
--------------------------------------------------------------------------------
/HUD/Assets/Widget-flipped-overlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/Widget-flipped-overlay.png
--------------------------------------------------------------------------------
/HUD/Assets/Widget-flipper.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/Widget-flipper.png
--------------------------------------------------------------------------------
/HUD/Assets/Widget-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/Widget-open.png
--------------------------------------------------------------------------------
/HUD/Assets/Widget-overlay.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/Widget-overlay.png
--------------------------------------------------------------------------------
/HUD/Assets/Widget.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/Widget.png
--------------------------------------------------------------------------------
/HUD/Assets/ally-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/ally-open.png
--------------------------------------------------------------------------------
/HUD/Assets/ally.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/ally.png
--------------------------------------------------------------------------------
/HUD/Assets/enemy-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/enemy-open.png
--------------------------------------------------------------------------------
/HUD/Assets/enemy.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/enemy.png
--------------------------------------------------------------------------------
/HUD/Assets/neutral-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/neutral-open.png
--------------------------------------------------------------------------------
/HUD/Assets/neutral.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/neutral.png
--------------------------------------------------------------------------------
/HUD/Assets/player-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/player-open.png
--------------------------------------------------------------------------------
/HUD/Assets/player.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/player.png
--------------------------------------------------------------------------------
/HUD/Assets/player_request.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/player_request.png
--------------------------------------------------------------------------------
/HUD/Assets/reminder-closed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/reminder-closed.png
--------------------------------------------------------------------------------
/HUD/Assets/reminder-glow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/reminder-glow.png
--------------------------------------------------------------------------------
/HUD/Assets/reminder-open.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/HUD/Assets/reminder-open.png
--------------------------------------------------------------------------------
/HUD/Projector-Global.lua:
--------------------------------------------------------------------------------
1 | --#region projector
2 | function toggleProjectorGUI(player, value, btn_id)
3 | local color = player.color:lower()
4 | self.UI.setAttribute("projector-panel-" .. color, "active", "false")
5 | end
6 | --#endregion
7 |
--------------------------------------------------------------------------------
/HUD/Projector-Global.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
23 |
31 |
32 |
42 |
50 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
--------------------------------------------------------------------------------
/HUD/average-hud.lua:
--------------------------------------------------------------------------------
1 | --#region average hud
2 | local _average_notecard = nil
3 | local averages = {}
4 |
5 | function showHuds(params)
6 | -- i'll receive params which is all the colors that i have to show the huds of
7 | _average_notecard = params.notecard
8 | for i = 1, #params.players do
9 | self.UI.setAttribute(params.players[i]:lower() .. "_average_box", "active", "true")
10 | averages = {}
11 | end
12 | end
13 |
14 | function submitAverage(player, request)
15 | if not averages[player.color] or averages[player.color] == "" then
16 | broadcastToColor("You need to insert a number in the box!", player.color, Color.Red)
17 | return
18 | end
19 | -- i'll receive the info for the notecard to read
20 | self.UI.setAttribute(player.color:lower() .. "_average_box", "active", "false")
21 | self.UI.setAttribute(player.color:lower() .. "_average", "text", "")
22 | local notecard = getObjectFromGUID(_average_notecard)
23 | if notecard then
24 | local crit = nil
25 | if request ~= "-1" then
26 | crit = request == "crit" and 20 or 1
27 | end
28 | log(crit)
29 | notecard.call(
30 | "setData",
31 | {
32 | color = player.color,
33 | avg = averages[player.color],
34 | crit = crit
35 | }
36 | )
37 | end
38 | end
39 |
40 | function updateAverage(player, value, obj)
41 | averages[player.color] = value
42 | end
43 | --#endregion
44 |
--------------------------------------------------------------------------------
/HUD/average-hud.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
--------------------------------------------------------------------------------
/HUD/breaker.lua:
--------------------------------------------------------------------------------
1 | -- #region breaker
2 | function UI_SideToggle()
3 | local offset = self.UI.getAttribute("TopButton", "offsetXY")
4 | local closed = offset == "75 5"
5 |
6 | if closed then
7 | -- to open
8 | -- button stuff
9 | self.UI.setAttribute("TopButton", "offsetXY", "75 -295")
10 | self.UI.setAttribute("TopButton", "text", "▲")
11 | self.UI.setAttribute("TopButton", "textColor", "#f0f0f0") -- dno why i gotta do this, but alas, shitty program
12 |
13 | -- panel stuff
14 | self.UI.setAttribute("TopPanel", "active", "true")
15 | else
16 | -- to close
17 | -- button stuff
18 | self.UI.setAttribute("TopButton", "offsetXY", "75 5")
19 | self.UI.setAttribute("TopButton", "text", "▼")
20 | self.UI.setAttribute("TopButton", "textColor", "#f0f0f0") -- dno why i gotta do this, but alas, shitty program
21 |
22 | -- panel stuff
23 | self.UI.setAttribute("TopPanel", "active", "hide")
24 | end
25 | end
26 |
27 | local _MassField = ""
28 | function UI_MassCalculate(player, request, id)
29 | local half = string.find(id, "Half") ~= nil
30 |
31 | local text = tonumber(_MassField)
32 | if half then
33 | text = math.floor(text / 2)
34 | end
35 |
36 | local objs = Player[player.color].getSelectedObjects()
37 | for i = 1, #objs do
38 | local gm = objs[i].getGMNotes()
39 | if gm == "monster_token" or gm == "boss_token" then
40 | local val = (id == "MassDamage" or id == "MassDamageHalf") and text * -1 or text
41 |
42 | local t = string.gsub(id, "Mass", "")
43 | t = string.gsub(t, "Half", "")
44 | objs[i].call(
45 | "GlobalCalculate",
46 | {
47 | input = val,
48 | t = t
49 | }
50 | )
51 | end
52 | end
53 | end
54 |
55 | function UI_UpdateMassHp(player, value)
56 | _MassField = value
57 | end
58 |
59 | local _MassModifier = ""
60 | function UI_MassRoll(player, request, id)
61 | local mode = ""
62 | if id == "MassRollAdv" then
63 | mode = "adv"
64 | elseif id == "MassRollDis" then
65 | mode = "dis"
66 | else
67 | mode = nil
68 | end
69 |
70 | local text = tonumber(_MassModifier)
71 | if not text then
72 | text = 0
73 | end
74 |
75 | local objs = Player[player.color].getSelectedObjects()
76 | for i = 1, #objs do
77 | local gm = objs[i].getGMNotes()
78 | if gm == "monster_token" or gm == "boss_token" then
79 | Wait.time(
80 | function()
81 | objs[i].call("GlobalRoll", {input = text, mode = mode})
82 | end,
83 | math.random(0.2, 0.8)
84 | )
85 | end
86 | end
87 | end
88 |
89 | local _MassReminder = ""
90 |
91 | function MassReminder(player, time)
92 | local count = 0
93 | local objs = Player[player.color].getSelectedObjects()
94 | for i = 1, #objs do
95 | local gm = objs[i].getGMNotes()
96 | if gm == "monster_token" or gm == "boss_token" then
97 | local monster = objs[i]
98 | monster.call("setReminder", {time = time, message = _MassReminder})
99 | count = count + 1
100 | monster.highlightOn(Color.White, 1.5)
101 | end
102 | end
103 | -- print to color with color #7FDBFF
104 | printToColor("Set to " .. count .. " the reminder: " .. _MassReminder, "Black", Color.Blue)
105 | end
106 |
107 | function UI_MassEndReminder(player, request, id)
108 | MassReminder(player, "_end")
109 | end
110 |
111 | function UI_MassStartReminder(player, request, id)
112 | MassReminder(player, "_start")
113 | end
114 |
115 | function UI_UpdateMassMod(player, value)
116 | _MassModifier = value
117 | end
118 |
119 | function UI_UpdateMassReminder(player, value)
120 | _MassReminder = value
121 | end
122 | -- #endregion
123 |
--------------------------------------------------------------------------------
/HUD/breaker.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/HUD/epic-reminder.lua:
--------------------------------------------------------------------------------
1 | --#region epic-reminder
2 | local _epicBoons = 0
3 | local _initialized = false
4 |
5 | function initEpicBoons()
6 | _epicBoons = 0
7 | ShowAllReminders()
8 |
9 | _initialized = true
10 | end
11 |
12 | function resetEpicBoons()
13 | local colors = {"White", "Teal", "Brown", "Blue", "Red", "Purple", "Orange", "Pink", "Yellow", "Green"}
14 | for _, color in ipairs(colors) do
15 | self.UI.setAttribute(color .. "_Epic_Reminder", "active", false)
16 | self.UI.setAttribute(color .. "_Epic_Boon_1", "active", false)
17 | self.UI.setAttribute(color .. "_Epic_Boon_2", "active", false)
18 | self.UI.setAttribute(color .. "_Epic_Boon_3", "active", false)
19 | self.UI.setAttribute(color .. "_Epic_Boon_4", "active", false)
20 | self.UI.setAttribute(color .. "_Epic_Boon_5", "active", false)
21 | self.UI.setAttribute(color .. "_Epic_Boon_6", "active", false)
22 | end
23 | self.UI.setAttribute("Epic_Glow", "active", false)
24 |
25 | _initialized = false
26 | end
27 |
28 | function UIEpicReminderOpen(player)
29 | EpicReminderBreaker(true, player.color)
30 | end
31 |
32 | function UIEpicReminderClose(player)
33 | EpicReminderBreaker(false, player.color)
34 | end
35 |
36 | function ShowAllReminders()
37 | local colors = {"White", "Teal", "Brown", "Blue", "Red", "Purple", "Orange", "Pink", "Yellow", "Green"}
38 | for _, color in ipairs(colors) do
39 | self.UI.setAttribute(color .. "_Epic_Reminder", "active", true)
40 | EpicReminderBreaker(false, color)
41 | end
42 | self.UI.setAttribute("Epic_Glow", "active", true)
43 | end
44 |
45 | function EpicReminderBreaker(open, color)
46 | if open then
47 | self.UI.setAttribute(color .. "_Closed_Reminder", "active", false)
48 | self.UI.setAttribute(color .. "_Opened_Reminder", "active", true)
49 | else
50 | self.UI.setAttribute(color .. "_Closed_Reminder", "active", true)
51 | self.UI.setAttribute(color .. "_Opened_Reminder", "active", false)
52 | end
53 | end
54 |
55 | function EpicReminderHighlight(color)
56 | for i = 1, 6, 1 do
57 | if i % 2 == 1 then
58 | Wait.time(
59 | function()
60 | self.UI.setAttribute("Epic_Glow", "color", "#B349FD")
61 | end,
62 | 0.1 * i
63 | )
64 | else
65 | Wait.time(
66 | function()
67 | self.UI.setAttribute("Epic_Glow", "color", "#A52CFA")
68 | end,
69 | 0.1 * i
70 | )
71 | end
72 | end
73 | end
74 |
75 | function AddBoon(params)
76 | if not _initialized then
77 | initEpicBoons()
78 | end
79 |
80 | local boon = params.boon
81 | local tooltip = params.tooltip
82 |
83 | _epicBoons = _epicBoons + 1
84 | if tooltip ~= nil and tooltip ~= "" then
85 | boon = boon .. " ⓘ"
86 | end
87 | local colors = {"White", "Teal", "Brown", "Blue", "Red", "Purple", "Orange", "Pink", "Yellow", "Green"}
88 | for _, color in ipairs(colors) do
89 | local height = 80 * _epicBoons
90 | if height > 320 then
91 | height = 320
92 | end
93 | self.UI.setAttribute(color .. "_Epic_Boons", "height", height)
94 | self.UI.setAttribute(color .. "_Epic_Boon_" .. _epicBoons, "active", true)
95 |
96 | if tooltip ~= nil then
97 | self.UI.setAttribute(color .. "_Epic_Boon_" .. _epicBoons, "tooltip", tooltip)
98 | end
99 | self.UI.setAttribute(color .. "_Epic_Boon_" .. _epicBoons, "text", boon)
100 |
101 | EpicReminderBreaker(true, color)
102 | EpicReminderHighlight(color)
103 | end
104 | end
105 |
106 | --#endregion
107 |
--------------------------------------------------------------------------------
/HUD/reminder-hud.lua:
--------------------------------------------------------------------------------
1 | -- #region reminder-hud
2 | function UI_ReminderSave()
3 | local pattern = "%(([^)]+)%)"
4 | local textToMatch = self.UI.getAttribute("reminder_details", "text")
5 |
6 | local guid = string.match(textToMatch, pattern)
7 |
8 | if guid then
9 | local reminder_start = self.UI.getAttribute("reminder_input_start", "value")
10 | local reminder_end = self.UI.getAttribute("reminder_input_end", "value")
11 |
12 |
13 | -- Why the _start and _end? because that's how it's written in monster.lua
14 | local pawn = getObjectFromGUID(guid)
15 | if reminder_start ~= "" then
16 | pawn.call("setReminder", {time = "_start", message = reminder_start})
17 | end
18 |
19 | if reminder_end ~= "" then
20 | pawn.call("setReminder", {time = "_end", message = reminder_end})
21 | end
22 |
23 | else
24 | broadcastToColor("Invalid GUID", "Black", "White")
25 | end
26 | self.UI.hide("reminder_dialogue")
27 | end
28 |
29 | function UI_ReminderClose()
30 | self.UI.hide("reminder_dialogue")
31 | end
32 |
33 | -- #endregion
34 |
--------------------------------------------------------------------------------
/HUD/reminder-hud.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Show Reminders
6 | Ajax (aaaaaa)
7 |
8 |
9 |
10 | Turn Start
11 |
12 |
13 |
14 | Turn End
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 Emanuele Sbabo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Tabletop Simulator Table
2 |
3 | This library is **not meant** for distribution, I use this place to share my code and to reference it when I do need it. If you found this place through a link given by me or by a friend, hi I guess. If you found this by googling, be aware that these scripts even though are optimized as much as I'm able to they are also very specific to my table (which is not released in the workshop, still working on that)
4 |
5 | I hope that whoever found this place will find the code within useful in some ways, sorry for no comments around but this is all stuff made for private usage.
6 | If you need help you can contact me @Zavian#8253 on discord (you can also find me in the official tabletop simulator discord if you don't want to add random friends for simple questions, you can join it here https://discord.gg/tabletopsimulator. I am **NOT** a Berserk developer and even though I'd like to don't ping anybody but me if you really need to ping someone), just be aware that I'm GMT+1 and if you are from another side of the planet it'll be hard for me to answer at all times. Peace 🐌
7 |
8 | # What's all this stuff? How do I go around this repository?
9 |
10 | Well, as a basis the nomenclature of the files makes pretty obvious, so through some logic and stuff like that, you'll be able to figure out most things. Even though this is on github the actual context of most of these things isn't really anywhere, for now.
11 |
12 | If a file has a .xml version it means that it's both UI and Lua based.
13 |
14 | If a file is in the **DEPRECATED** folder then there is probably a better version of it or it has simply become useless by the implementation of different code.
15 |
16 | # Who am I?
17 |
18 | I'm a developer that has taken under his responsibility to recreate a series of tools to ease DnD into Tabletop Simulator. Don't think of me of anything as I am far from expert on the tool, however the scrips present in this page can be used in all sorts of manners, just be aware that there is close to no documentation, you can still concact me if you need to understand anything from the project.
19 |
20 | # What is the purpose of all these scripts?
21 |
22 | The things that I'm trying to achieve via these scripts is to reach a decent level of both automation and management of a DnD table, mostly for combat related activities. Many tools are inspired by other external programs such as Roll20, Foundry, FantasyGrounds, etc.
23 | The end goal is to have a table that is both **stable** (still working on it) and easy to understand with all the features you may be in need for managing a DnD game.
24 |
25 | # Credits where credits are due
26 |
27 | It goes without saying that a lot of the things that can be found here are things that are gathered from the community, both from the official tabletop simulator discord (in which plenty of people have helped me) and other github repositories that I have found throught the years. Additionally a lot of the work could've not been done if it wasn't for the various top developers that can be found in the workshop. Among these there is:
28 | * [Mr. Stump](https://steamcommunity.com/id/MrStump/myworkshopfiles/?appid=286160)
29 | * [St0m 🐱](https://steamcommunity.com/id/st0m/myworkshopfiles/?appid=286160)
30 | * [CHRY](https://steamcommunity.com/id/chries/myworkshopfiles/?appid=286160)
31 | * [Kijan](https://steamcommunity.com/id/kijands/myworkshopfiles/?appid=286160)
32 |
33 | And countless more. If it wasn't for these wonderful people I would've probably not started making anything as daunting as this projects. 💖
34 | If you feel unrepresented please do go ahead and contact me.
35 |
--------------------------------------------------------------------------------
/Utility tools/README.md:
--------------------------------------------------------------------------------
1 | This is a folder dedicated to many tools that don't really have a function in a table but rather are made to serve one purpose.
--------------------------------------------------------------------------------
/Utility tools/empty-container.lua:
--------------------------------------------------------------------------------
1 | function onLoad()
2 | local button = {
3 | click_function = "emptyContainer",
4 | function_owner = self,
5 | label = "Click",
6 | position = {0, 0.6, 0},
7 | scale = {0.5, 0.5, 0.5},
8 | width = 2000,
9 | height = 400,
10 | font_size = 400
11 | }
12 | end
13 |
14 | function emptyContainer()
15 | local gm = self.getGMNotes()
16 |
17 | local obj = getObjectFromGUID(gm)
18 | print(obj)
19 | if not obj then
20 | print("Could not find object with GUID: " .. gm)
21 | return
22 | end
23 |
24 | local objects = obj.getObjects()
25 | print("Found " .. #objects .. " objects in container")
26 |
27 | --for _, v in ipairs(objects) do
28 | -- v.destruct()
29 | --end
30 | end
31 |
--------------------------------------------------------------------------------
/Utility tools/mansion-mover.lua:
--------------------------------------------------------------------------------
1 | local _floors = {
2 | [1] = {
3 | id = "c18d92",
4 | initial_pos = {x = 0.02, y = 1.18, z = -0.09}
5 | },
6 | [2] = {
7 | id = "7d3103",
8 | initial_pos = {x = 0.02, y = 1.48, z = -0.09}
9 | },
10 | [3] = {
11 | id = "94c856",
12 | initial_pos = {x = 0.02, y = 1.78, z = -0.09}
13 | }
14 | }
15 |
16 | function onLoad()
17 | dim_floor(_floors[2])
18 |
19 | self.createButton(
20 | {
21 | click_function = "show_all_floors",
22 | function_owner = self,
23 | label = "Show All Floors",
24 | position = {6, 0.6, 7},
25 | scale = {0.5, 0.5, 0.5},
26 | color = {0, 0.4117, 0.7058},
27 | width = 3000,
28 | height = 800,
29 | font_size = 400
30 | }
31 | )
32 | self.createButton({
33 | click_function = 'toggle_first_floor',
34 | function_owner = self,
35 | label = '1st Floor',
36 | position = {6.6, 0.6, 6.2},
37 | scale = {0.3, 0.3, 0.3},
38 | color = {0.2784, 0.7255, 0.2784},
39 | width = 3000,
40 | height = 800,
41 | font_size = 400,
42 | tooltip = 'Visible'
43 | })
44 |
45 | self.createButton({
46 | click_function = 'toggle_second_floor',
47 | function_owner = self,
48 | label = '2nd Floor',
49 | position = {6.6, 0.6, 5.7},
50 | scale = {0.3, 0.3, 0.3},
51 | color = {0.2784, 0.7255, 0.2784},
52 | width = 3000,
53 | height = 800,
54 | font_size = 400,
55 | tooltip = 'Visible'
56 | })
57 |
58 | self.createButton({
59 | click_function = 'toggle_third_floor',
60 | function_owner = self,
61 | label = '3rd Floor',
62 | position = {6.6, 0.6, 5.2},
63 | scale = {0.3, 0.3, 0.3},
64 | color = {0.2784, 0.7255, 0.2784},
65 | width = 3000,
66 | height = 800,
67 | font_size = 400,
68 | tooltip = 'Visible'
69 | })
70 | end
71 |
72 |
73 | local can_set = true
74 | local showing_all = false
75 |
76 | function move_floor(floor, offset)
77 | local obj = getObjectFromGUID(floor.id)
78 | local pos = obj.getPosition()
79 | local newPos = {
80 | x = pos.x + offset,
81 | y = _floors[1].initial_pos.y,
82 | z = pos.z
83 | }
84 | if obj then
85 | obj.setPositionSmooth(newPos, false, false)
86 | end
87 | end
88 |
89 | function reset_floor(floor)
90 | local obj = getObjectFromGUID(floor.id)
91 | local pos = floor.initial_pos
92 | if obj then
93 | obj.setPositionSmooth(pos, false, false)
94 | end
95 | end
96 |
97 | function mat_floor(floor)
98 | local obj = getObjectFromGUID(floor.id)
99 | if obj then
100 | obj.setColorTint({r = 1, g = 1, b = 1, a = 1})
101 | end
102 | end
103 |
104 | function dim_floor(floor)
105 | local obj = getObjectFromGUID(floor.id)
106 | if obj then
107 | obj.setColorTint({r = 0.5568, g = 0.5568, b = 0.5568, a = 1})
108 | end
109 | end
110 |
111 | function isVisible(floor_number)
112 | return self.getButtons()[floor_number+1].tooltip == 'Visible'
113 | end
114 |
115 | function toggle_floor(floor_number)
116 | local floor = _floors[floor_number]
117 | if isVisible(floor_number) then
118 | getObjectFromGUID(floor.id).setInvisibleTo({
119 | "White",
120 | "Brown",
121 | "Red",
122 | "Orange",
123 | "Yellow",
124 | "Green",
125 | "Teal",
126 | "Blue",
127 | "Purple",
128 | "Pink",
129 | "Grey",
130 | "Black"
131 | })
132 | self.editButton({index = floor_number, tooltip = "Invisible", color = {r = 1, g = 0.2549, b = 0.2117}})
133 | else
134 | getObjectFromGUID(floor.id).setInvisibleTo({})
135 | self.editButton({index = floor_number, tooltip = "Visible", color = {0.2784, 0.7255, 0.2784}})
136 | end
137 | end
138 |
139 | function toggle_first_floor()
140 | toggle_floor(1)
141 | end
142 |
143 | function toggle_second_floor()
144 | toggle_floor(2)
145 | end
146 |
147 | function toggle_third_floor()
148 | toggle_floor(3)
149 | if isVisible(2) and not showing_all then
150 | mat_floor(_floors[2])
151 | end
152 |
153 | if isVisible(3) and not showing_all then
154 | dim_floor(_floors[2])
155 | end
156 | end
157 |
158 |
159 | function show_all_floors()
160 | local offset = 17
161 | if not showing_all then
162 | if can_set then
163 | _floors[1].initial_pos = getObjectFromGUID(_floors[1].id).getPosition()
164 | _floors[2].initial_pos = getObjectFromGUID(_floors[2].id).getPosition()
165 | _floors[3].initial_pos = getObjectFromGUID(_floors[3].id).getPosition()
166 | can_set = false
167 | Wait.time(function() can_set = true end, 10)
168 | end
169 |
170 | move_floor(_floors[2], offset)
171 | move_floor(_floors[3], offset * -1)
172 |
173 | mat_floor(_floors[2])
174 |
175 | for i = 1, 3 do
176 | self.editButton({index = i, width = 0, height = 0, label = ""})
177 | getObjectFromGUID(_floors[i].id).setName(
178 | i == 1 and "1st Floor"
179 | or i == 2 and "2nd Floor"
180 | or "3rd Floor"
181 | )
182 | end
183 | else
184 | reset_floor(_floors[2])
185 | reset_floor(_floors[3])
186 |
187 | dim_floor(_floors[2])
188 |
189 | for i = 1, 3 do
190 | self.editButton({index = i, width = 3000, height = 800,
191 | label =
192 | i == 1 and "1st Floor"
193 | or i == 2 and "2nd Floor"
194 | or "3rd Floor"
195 | }
196 | )
197 | getObjectFromGUID(_floors[i].id).setName("")
198 | end
199 | end
200 |
201 | showing_all = not showing_all
202 | end
--------------------------------------------------------------------------------
/Utility tools/memo-viewer.lua:
--------------------------------------------------------------------------------
1 | function onLoad()
2 | self.createButton({
3 | click_function = 'showMemo',
4 | function_owner = self,
5 | label = 'MEMO',
6 | position = {0, 0, 0},
7 | rotation = {180, 180, 0},
8 | scale = {0.3, 0.3, 0.3},
9 | width = 1200,
10 | height = 800,
11 | font_size = 400,
12 | color = {1,0.863,0},
13 | tooltip = 'Show Memo'
14 | })
15 | end
16 |
17 | local _SAVED_GUID = null
18 |
19 | function onCollisionEnter(collision_info)
20 | -- collision_info table:
21 | -- collision_object Object
22 | -- contact_points Table {Vector, ...}
23 | -- relative_velocity Vector
24 | if(not collision_info.collision_object.interactable) then return end
25 | if(collision_info.collision_object == self) then return end
26 | _SAVED_GUID = collision_info.collision_object.getGUID()
27 | print("GUID Found: ".._SAVED_GUID)
28 | collision_info.collision_object.highlightOn(Color.Green, 1)
29 | end
30 |
31 | function showMemo(obj, player_color)
32 | if player_color ~= "Black" then return end
33 | if _SAVED_GUID == null then broadcastToColor("Must select an object first!", player_color, Color.red); return; end
34 | -- print(getObjectFromGUID(_SAVED_GUID).)
35 |
36 | local chosen_object = getObjectFromGUID(_SAVED_GUID)
37 |
38 | Player["Black"].showMemoDialog("Memo of " .. _SAVED_GUID, chosen_object.memo,
39 | function(input, player_color)
40 | -- print(input)
41 | if input ~= chosen_object.memo then
42 | -- chosen_object.setDescription(input)
43 | Player["Black"].showConfirmDialog("Memo and text don't match, confirm change?",
44 | function()
45 | broadcastToColor("Memo saved!", player_color, Color.green)
46 | chosen_object.memo = input
47 | end
48 | )
49 | end
50 | end
51 | )
52 | end
--------------------------------------------------------------------------------
/VERSIONS:
--------------------------------------------------------------------------------
1 | table_updater 1.2
2 | npc_commander 2.2.3
3 | monster 4.0
4 | initiative_mat 2.3.2
5 | initiative_token 1.1.4
6 | player_manager 3.0
7 | note 2.1.1
--------------------------------------------------------------------------------
/average-button.lua:
--------------------------------------------------------------------------------
1 | local expanded = false
2 | local _Black = Color.Black
3 |
4 | function buttonPress()
5 | if lockout == false then
6 | --Call on any other function here. For example:
7 | --Global.call("Function Name", {table of parameters if needed})
8 | --You could also add your own scrting here. For example:
9 | --print("The button was pressed. Hoozah.")
10 | self.AssetBundle.playTriggerEffect(0) --triggers animation/sound
11 | lockout = true --locks out the button
12 | startLockoutTimer() --Starts up a timer to remove lockout
13 |
14 | local notes = self.getGMNotes()
15 | local vars = JSON.decode(notes)
16 | -- send to open all things from seated players
17 | -- and send it back to a notepad
18 | if not notes then
19 | printError()
20 | return
21 | end
22 | local notecard = getObjectFromGUID(vars["note"])
23 | if not notecard then
24 | printError()
25 | return
26 | else
27 | notecard.setDescription("")
28 | end
29 | if not expanded then
30 | Global.call("showHuds", {notecard = vars["note"], players = createSeatedTable()})
31 | notecard.call("reset")
32 | else
33 | Global.call("showHuds", {notecard = vars["note"], players = createSelectedTable()})
34 | notecard.call("reset", {colors = createSelectedTable()})
35 | end
36 | end
37 | end
38 |
39 | function printError()
40 | printToColor("Error in the average, gotta setup the note in the GM Note", "Black", Color.White)
41 | end
42 |
43 | function onload()
44 | self.createButton(
45 | {
46 | label = "Big Red Button\n\nBy: MrStump",
47 | click_function = "buttonPress",
48 | function_owner = self,
49 | position = {0, 0.25, 0},
50 | height = 1400,
51 | width = 1400
52 | }
53 | )
54 |
55 | local colors = getAllColors()
56 |
57 | local x = 1.9
58 | local z = -1.4
59 | for i = 1, #colors do
60 | x = x + 1.5
61 | if i == 5 or i == 9 then
62 | z = z + 1.6
63 | x = 3.4
64 | end
65 | local button = {
66 | label = colors[i],
67 | click_function = "Button_" .. colors[i],
68 | function_owner = self,
69 | position = {x, 0.2, z},
70 | font_size = 215,
71 | color = _Black,
72 | font_color = Color.White,
73 | width = 700,
74 | height = 700,
75 | scale = {0, 0, 0}
76 | }
77 | self.createButton(button)
78 | end
79 | self.createButton(
80 | {
81 | -- button for expanding extra buttons
82 | click_function = "toggleExtra",
83 | function_owner = self,
84 | label = "▶",
85 | position = {2.1, 0.2, 0},
86 | scale = {0.5, 0.5, 0.5},
87 | width = 950,
88 | height = 950,
89 | font_size = 900,
90 | color = _Black,
91 | font_color = Color.White
92 | }
93 | )
94 | lockout = false
95 | end
96 |
97 | function createSeatedTable()
98 | local returner = {}
99 | local colors = getAllColors()
100 | for i = 1, #colors do
101 | local seat = Seated(colors[i])
102 | if seat then
103 | table.insert(returner, seat)
104 | end
105 | end
106 | return returner
107 | end
108 |
109 | function createSelectedTable()
110 | returner = {}
111 | local buttons = self.getButtons()
112 | for i = 1, #getAllColors() do
113 | if buttons[i].font_color == Color.Red then
114 | log("Found color " .. buttons[i].label)
115 | table.insert(returner, buttons[i].label)
116 | end
117 | end
118 | return returner
119 | end
120 |
121 | function toggleExtra()
122 | local buttons = #self.getButtons()
123 | local button = self.getButtons()[buttons]
124 | if button.label == "▶" then
125 | self.editButton({index = buttons - 1, label = "◀"})
126 | enlargeExtras(true)
127 | else
128 | self.editButton({index = buttons - 1, label = "▶"})
129 | enlargeExtras(false)
130 | end
131 | end
132 |
133 | function enlargeExtras(doIt)
134 | local scale = doIt and {1, 1, 1} or {0, 0, 0}
135 | local colors = getAllColors()
136 | for i = 1, #colors do
137 | self.editButton({index = i, scale = scale})
138 | if not Seated(colors[i]) then
139 | self.editButton({index = i, font_color = _Black})
140 | else
141 | self.editButton({index = i, font_color = Color.White})
142 | end
143 | end
144 | expanded = doIt
145 | end
146 |
147 | function getAllColors()
148 | return {
149 | "White",
150 | "Teal",
151 | "Brown",
152 | "Blue",
153 | "Red",
154 | "Purple",
155 | "Orange",
156 | "Pink",
157 | "Yellow",
158 | "Green"
159 | }
160 | end
161 |
162 | function Seated(color)
163 | if Player[color].seated then
164 | return color
165 | else
166 | return nil
167 | end
168 | end
169 |
170 | function getColorIndex(color)
171 | local colors = getAllColors()
172 | for i = 1, #colors do
173 | if color == colors[i] then
174 | return i
175 | end
176 | end
177 | return -1
178 | end
179 |
180 | function toggleButton(color)
181 | local buttons = self.getButtons()
182 | for i = 1, #buttons do
183 | local label = buttons[i].label
184 | if label == color then
185 | local fc = buttons[i].font_color
186 | if fc.b ~= _Black.b then
187 | if fc ~= Color.White then
188 | self.editButton({index = i - 1, font_color = Color.White})
189 | else
190 | self.editButton({index = i - 1, font_color = Color.Red})
191 | end
192 | end
193 | end
194 | end
195 | end
196 |
197 | function Button_White()
198 | toggleButton("White")
199 | end
200 |
201 | function Button_Teal()
202 | toggleButton("Teal")
203 | end
204 |
205 | function Button_Brown()
206 | toggleButton("Brown")
207 | end
208 |
209 | function Button_Blue()
210 | toggleButton("Blue")
211 | end
212 |
213 | function Button_Red()
214 | toggleButton("Red")
215 | end
216 |
217 | function Button_Purple()
218 | toggleButton("Purple")
219 | end
220 |
221 | function Button_Orange()
222 | toggleButton("Orange")
223 | end
224 |
225 | function Button_Pink()
226 | toggleButton("Pink")
227 | end
228 |
229 | function Button_Yellow()
230 | toggleButton("Yellow")
231 | end
232 |
233 | function Button_Green()
234 | toggleButton("Green")
235 | end
236 |
237 | --Starts a timer that, when it ends, will unlock the button
238 | function startLockoutTimer()
239 | Timer.create({identifier = self.getGUID(), function_name = "unlockLockout", delay = 0.5})
240 | end
241 |
242 | --Unlocks button
243 | function unlockLockout()
244 | lockout = false
245 | end
246 |
247 | --Ends the timer if the object is destroyed before the timer ends, to prevent an error
248 | function onDestroy()
249 | Timer.destroy(self.getGUID())
250 | end
251 |
--------------------------------------------------------------------------------
/average-notecard.lua:
--------------------------------------------------------------------------------
1 | local _buttons = {}
2 | local _startIndex = 0
3 |
4 | local _setup = false
5 |
6 | local _critColor = {r = 0.0667, g = 0.3019, b = 0.0667, a = 1}
7 | local _failColor = {r = 0.3019, g = 0.0667, b = 0.0667, a = 1}
8 |
9 | function onLoad()
10 | self.createButton(
11 | {
12 | click_function = "setup",
13 | function_owner = self,
14 | label = "Setup",
15 | position = {0, 2.6, 0.42},
16 | rotation = {180, 0, 180},
17 | scale = {0.15, 0.2, 0.2},
18 | width = 1010,
19 | height = 330,
20 | font_size = 200,
21 | color = Color.Black,
22 | font_color = Color.White
23 | }
24 | )
25 | self.createButton(
26 | {
27 | click_function = "average",
28 | function_owner = self,
29 | label = "AVG",
30 | position = {0, 2.6, -0.58},
31 | rotation = {180, 0, 180},
32 | scale = {0.15, 0.2, 0.2},
33 | width = 1010,
34 | height = 330,
35 | font_size = 200,
36 | color = Color.Red,
37 | font_color = Color.White
38 | }
39 | )
40 | _startIndex = 2
41 |
42 | --Wait.Time(
43 | -- function()
44 | -- setup()
45 | -- randomizeDebug()
46 | -- end,
47 | -- 2
48 | --)
49 | end
50 |
51 | function randomizeDebug()
52 | local colors = getAllColors()
53 | for i = 1, #colors do
54 | Wait.Time(
55 | function()
56 | local avg = math.random(1, 22)
57 | local crit = nil
58 | if avg == 1 then
59 | crit = 1
60 | elseif avg >= 20 then
61 | crit = 20
62 | end
63 | setData({avg = avg, color = colors[i], crit = crit})
64 | end,
65 | 0.5
66 | )
67 | end
68 | end
69 |
70 | function setData(params)
71 | if not _setup then
72 | setup()
73 | end
74 | local buttonIndex = findButtonByColor(params.color) - 1
75 | self.editButton({index = buttonIndex, label = params.avg})
76 | if params.crit ~= nil then
77 | local desc = self.getDescription()
78 | if params.crit == 20 then
79 | self.editButton({index = buttonIndex, color = _critColor})
80 | self.setDescription(desc == "" and params.avg or desc .. " " .. params.avg)
81 | else
82 | self.editButton({index = buttonIndex, color = _failColor})
83 | self.setDescription(desc == "" and "1" or desc .. " 1")
84 | end
85 | else
86 | self.editButton({index = buttonIndex, color = Color.Black})
87 | end
88 | end
89 |
90 | function findButtonByColor(color)
91 | local buttons = self.getButtons()
92 | for i = 1, #buttons do
93 | local button = buttons[i]
94 | if button.tooltip == color then
95 | return i
96 | end
97 | end
98 | end
99 |
100 | function reset(params)
101 | setup()
102 | if params then
103 | Wait.Time(
104 | function()
105 | local buttons = self.getButtons()
106 | for i = 1, #buttons do
107 | if notInList(params.colors, buttons[i].tooltip) and i - 1 >= _startIndex then
108 | self.editButton({index = i - 1, font_color = Color.Black})
109 | end
110 | end
111 | end,
112 | 0.5
113 | )
114 | end
115 | end
116 |
117 | function notInList(list, color)
118 | for i = 1, #list do
119 | if list[i] == color then
120 | return false
121 | end
122 | end
123 | return true
124 | end
125 |
126 | function setup()
127 | if #_buttons > 0 then
128 | resetButtons()
129 | end
130 |
131 | local colors = getAllColors()
132 |
133 | local x = 0.39
134 | local z = -0.36
135 | for i = 1, #colors do
136 | if Seated(colors[i]) then
137 | local button = {
138 | label = colors[i],
139 | click_function = "none",
140 | function_owner = self,
141 | position = {x, 2.6, z},
142 | font_size = 215,
143 | color = Color.Black,
144 | font_color = Color[colors[i]],
145 | tooltip = colors[i],
146 | width = 700,
147 | height = 700,
148 | scale = {0.13, 0.15, 0.15},
149 | rotation = {180, 0, 180}
150 | }
151 | self.createButton(button)
152 | table.insert(_buttons, button)
153 | x = x - 0.19
154 | if i == 5 or i == 10 then
155 | z = z + 0.23
156 | x = 0.39
157 | end
158 | end
159 | end
160 | _setup = true
161 | end
162 |
163 | function resetButtons()
164 | for i = 1, #self.getButtons() do
165 | if i - 1 >= _startIndex then
166 | self.removeButton(i - 1)
167 | _buttons = {}
168 | _setup = false
169 | end
170 | end
171 | end
172 |
173 | function none()
174 | end
175 |
176 | function average()
177 | local numbers = 0
178 | local tot = 0
179 | -- get all buttons
180 | local buttons = self.getButtons()
181 | for i = _startIndex + 1, #buttons do
182 | if buttons[i].font_color ~= Color.Black then
183 | --log(buttons[i].tooltip .. " " .. buttons[i].label)
184 | local num = tonumber(buttons[i].label)
185 | if (num) then
186 | tot = tot + num
187 | numbers = numbers + 1
188 | end
189 | end
190 | end
191 |
192 | if self.getDescription() ~= "" then
193 | local extras = split(self.getDescription(), " ")
194 | for i = 1, #extras do
195 | tot = tot + tonumber(extras[i])
196 | numbers = numbers + 1
197 | end
198 | end
199 | self.setName("[00000000]" .. tot / numbers .. "[-]")
200 | self.editButton({index = 1, label = math.floor(tot / numbers)})
201 | end
202 |
203 | function Seated(color)
204 | if Player[color].seated then
205 | return color
206 | else
207 | return nil
208 | end
209 | end
210 |
211 | function getAllColors()
212 | return {
213 | "White",
214 | "Teal",
215 | "Brown",
216 | "Blue",
217 | "Red",
218 | "Purple",
219 | "Orange",
220 | "Pink",
221 | "Yellow",
222 | "Green"
223 | }
224 | end
225 |
226 | function split(inputstr, sep)
227 | if sep == nil then
228 | sep = "%s"
229 | end
230 | local t = {}
231 | i = 1
232 | for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
233 | t[i] = str
234 | i = i + 1
235 | end
236 | return t
237 | end
238 |
--------------------------------------------------------------------------------
/bag-peeker.lua:
--------------------------------------------------------------------------------
1 | local firstItem = ""
2 |
3 | function onLoad()
4 | self.createButton(
5 | {
6 | click_function = "none",
7 | function_owner = self,
8 | label = firstItem,
9 | position = {0, 0.6, 2.9},
10 | scale = {0.7, 0.7, 0.7},
11 | width = 7200,
12 | height = 800,
13 | font_size = 600
14 | }
15 | )
16 | getFirstItem()
17 | end
18 |
19 | function none()
20 | end
21 |
22 | function onObjectEnterContainer(bag, obj)
23 | if bag == self then
24 | getFirstItem()
25 | end
26 | end
27 |
28 | function onObjectLeaveContainer(bag, obj)
29 | if bag == self then
30 | getFirstItem()
31 | end
32 | end
33 |
34 | function getFirstItem()
35 | local objs = self.getObjects()
36 | if objs then
37 | if objs[1] then
38 | firstItem = objs[#objs].name
39 | else
40 | firstItem = ""
41 | end
42 | self.editButton({index = 0, label = firstItem})
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/card creator/card creator-2.0.lua:
--------------------------------------------------------------------------------
1 | local bag = self.getDescription()
2 |
3 | local objs = {}
4 |
5 | local processing = false
6 | local index = 1
7 |
8 | function mysplit(inputstr, sep)
9 | if sep == nil then
10 | sep = "%s"
11 | end
12 | local t = {}
13 | i = 1
14 | for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
15 | t[i] = str
16 | i = i + 1
17 | end
18 | return t
19 | end
20 |
21 | --Runs when the scripted button inside the button is clicked
22 | function buttonPress()
23 | if lockout == false then
24 | --Call on any other function here. For example:
25 | --Global.call("Function Name", {table of parameters if needed})
26 | --You could also add your own scrting here. For example:
27 | --print("The button was pressed. Hoozah.")
28 |
29 | text = self.UI.getAttribute("text", "value")
30 | local lines = mysplit(text, "\n")
31 |
32 | local readingBack = false
33 | local card = ""
34 |
35 | for i = 1, #lines do
36 | local line = lines[i]
37 | local isSmall = #mysplit(line, "|") > 1
38 |
39 | local card = line
40 | if isSmall then
41 | card = mysplit(line, "|")[1]
42 | end
43 |
44 | local elements = mysplit(card, " ")
45 | local result = ""
46 | if #elements == 1 then -- in the case that i only put the link
47 | result = elements[1] .. "|" .. elements[1]
48 | take_card(result)
49 | elseif #elements == 2 then -- in the case that i two links
50 | result = elements[1] .. "|" .. elements[2]
51 | take_card(result)
52 | elseif #elements == 3 then -- in the case that i have also the color
53 | local isHex = elements[1]:sub(1, 1) == "#"
54 | result = elements[2] .. "|" .. elements[3]
55 | take_card(result, true, isHex)
56 | end
57 | end
58 |
59 | local waiter = function()
60 | if #objs == 0 then
61 | return false
62 | end
63 | for i = 1, #objs do
64 | local res = objs[i].o.resting
65 | if res == false then
66 | return false
67 | end
68 | end
69 | return true
70 | end
71 |
72 | local waited = function()
73 | setCards()
74 | end
75 |
76 | Wait.condition(waited, waiter)
77 |
78 | self.AssetBundle.playTriggerEffect(0) --triggers animation/sound
79 | lockout = true --locks out the button
80 | startLockoutTimer() --Starts up a timer to remove lockout
81 | end
82 | end
83 |
84 | function take_card(c, hasColor, isHex)
85 | local returner = {}
86 |
87 | local splitted = mysplit(c, "|")
88 |
89 | if hasColor then
90 | if not isHex then
91 | local colo = splitted[3]:gsub("-", "")
92 | returner.color = colorTranslate(colo)
93 | else
94 | local colo = hexToRgb(splitted[3])
95 | returner.color = colo
96 | end
97 | else
98 | returner.color {r = 0, g = 0, b = 0}
99 | end
100 |
101 | returner.card = {splitted[1], splitted[2]}
102 | takeParams = {
103 | position = {119.49, 2.80, 13.54},
104 | rotation = {0, 0, 0},
105 | callback_function = function(obj)
106 | returner.o = obj
107 | table.insert(objs, returner)
108 | end
109 | }
110 | --printTable(objs)
111 |
112 | getObjectFromGUID(bag).takeObject(takeParams)
113 | end
114 |
115 | function setCards(small)
116 | for i = 1, #objs do
117 | objs[i].o.setCustomObject(
118 | {
119 | image = objs[i].card[1],
120 | image_secondary = objs[i].card[2]
121 | }
122 | )
123 | if objs[i].color ~= nil then
124 | objs[i].o.setColorTint(objs[i].color)
125 | end
126 |
127 | if small ~= nil then
128 | if small then
129 | objs[i].o.setScale({1.76, 1.00, 1.76})
130 | end
131 | elseif makeSmall() then
132 | objs[i].o.setScale({1.76, 1.00, 1.76})
133 | end
134 |
135 | objs[i].o.reload()
136 | end
137 |
138 | objs = {}
139 | end
140 |
141 | function colorTranslate(color)
142 | --[[
143 | arr["Green"] = "u";
144 | arr["Navy"] = "r";
145 | arr["BlueViolet"] = "e";
146 | arr["#c46709"] = "l";
147 | --]]
148 | local r = ""
149 | if color == "u" then
150 | r = "Green"
151 | elseif color == "r" then
152 | r = "Blue"
153 | elseif color == "e" then
154 | r = "Purple"
155 | elseif color == "l" then
156 | r = {r = 0.768627, g = 0.403922, b = 0.035294}
157 | else
158 | r = {r = 0, g = 0, b = 0}
159 | end
160 |
161 | return r
162 | end
163 |
164 | --Runs on load, creates button and makes sure the lockout is off
165 | function onload()
166 | self.createButton(
167 | {
168 | label = "Big Red Button\n\nBy: MrStump",
169 | click_function = "buttonPress",
170 | function_owner = self,
171 | position = {0, 0.25, 0},
172 | height = 1400,
173 | width = 1400
174 | }
175 | )
176 | self.createButton(
177 | {
178 | click_function = "changeSmall",
179 | function_owner = self,
180 | label = " ",
181 | position = {-1.5, 0.45, 1.5},
182 | width = 400,
183 | height = 400,
184 | color = {0.856, 0.1, 0.094, 1},
185 | tooltip = "big"
186 | }
187 | )
188 | lockout = false
189 |
190 | local desc = self.getDescription()
191 | if desc ~= "" then
192 | bag = desc
193 | end
194 | self.UI.setAttribute("text", "onValueChanged", self.getGUID() .. "/UIUpdateValue(value)")
195 | end
196 |
197 | function changeSmall()
198 | local btn = self.getButtons()[2]
199 | local isBig = btn.tooltip == "big"
200 | local color = {
201 | red = {0.856, 0.1, 0.094, 1},
202 | green = {0.4418, 0.8101, 0.4248, 1}
203 | }
204 | if isBig then
205 | self.editButton({index = 1, color = color.green})
206 | self.editButton({index = 1, tooltip = "small"})
207 | else
208 | self.editButton({index = 1, color = color.red})
209 | self.editButton({index = 1, tooltip = "big"})
210 | end
211 | end
212 |
213 | function makeSmall()
214 | local btn = self.getButtons()[2]
215 | return btn.tooltip == "small"
216 | end
217 |
218 | function UIUpdateValue(player, text, id)
219 | self.UI.setAttribute("text", "value", text)
220 | end
221 |
222 | --Starts a timer that, when it ends, will unlock the button
223 | function startLockoutTimer()
224 | Timer.create({identifier = self.getGUID(), function_name = "unlockLockout", delay = 0.5})
225 | end
226 |
227 | --Unlocks button
228 | function unlockLockout()
229 | lockout = false
230 | end
231 |
232 | --Ends the timer if the object is destroyed before the timer ends, to prevent an error
233 | function onDestroy()
234 | Timer.destroy(self.getGUID())
235 | end
236 |
237 | function hexToRgb(hex)
238 | hex = hex:gsub("#", "")
239 | if #hex < 8 then
240 | hex = hex .. "ff"
241 | end
242 | return color(
243 | tonumber("0x" .. hex:sub(1, 2), 16) / 255,
244 | tonumber("0x" .. hex:sub(3, 4), 16) / 255,
245 | tonumber("0x" .. hex:sub(5, 6), 16) / 255,
246 | tonumber("0x" .. hex:sub(7, 8), 16) / 255
247 | )
248 | end
249 |
--------------------------------------------------------------------------------
/card creator/card creator.lua:
--------------------------------------------------------------------------------
1 | local bag = self.getDescription()
2 |
3 | local objs = {}
4 |
5 | local processing = false
6 | local index = 1
7 |
8 | function mysplit(inputstr, sep)
9 | if sep == nil then
10 | sep = "%s"
11 | end
12 | local t = {}
13 | i = 1
14 | for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
15 | t[i] = str
16 | i = i + 1
17 | end
18 | return t
19 | end
20 |
21 | --Runs when the scripted button inside the button is clicked
22 | function buttonPress()
23 | if lockout == false then
24 | --Call on any other function here. For example:
25 | --Global.call("Function Name", {table of parameters if needed})
26 | --You could also add your own scrting here. For example:
27 | --print("The button was pressed. Hoozah.")
28 |
29 | text = self.UI.getAttribute("text", "value")
30 | local lines = mysplit(text, "\n")
31 |
32 | local readingBack = false
33 | local card = ""
34 |
35 | for i = 1, #lines do
36 | local str = lines[i]
37 | local firstChar = string.sub(lines[i], 1, 1)
38 | if firstChar == "h" then
39 | --if not readingBack then
40 | -- card = str
41 | -- readingBack = true
42 | --else
43 | -- card = card .. "|" .. str
44 | -- readingBack = false
45 | -- take_card(card)
46 | --end
47 | -- there's no color detailed
48 | local sp = mysplit(str, " ")
49 | take_card(sp[1] .. "|" .. sp[2])
50 | elseif firstChar == "-" then
51 | --color
52 | local sp = mysplit(str, " ")
53 | take_card(sp[2] .. "|" .. sp[3] .. "|" .. sp[1], true)
54 | elseif firstChar == "#" then
55 | local sp = mysplit(str, " ")
56 | take_card(sp[2] .. "|" .. sp[3] .. "|" .. sp[1], true, true)
57 | end
58 | end
59 |
60 | local waiter = function()
61 | if #objs == 0 then
62 | return false
63 | end
64 | for i = 1, #objs do
65 | local res = objs[i].o.resting
66 | if res == false then
67 | return false
68 | end
69 | end
70 | return true
71 | end
72 |
73 | local waited = function()
74 | setCards()
75 | end
76 |
77 | Wait.condition(waited, waiter)
78 |
79 | self.AssetBundle.playTriggerEffect(0) --triggers animation/sound
80 | lockout = true --locks out the button
81 | startLockoutTimer() --Starts up a timer to remove lockout
82 | end
83 | end
84 |
85 | function take_card(c, hasColor, isHex)
86 | local returner = {}
87 |
88 | local splitted = mysplit(c, "|")
89 |
90 | if hasColor then
91 | if not isHex then
92 | local colo = splitted[3]:gsub("-", "")
93 | returner.color = colorTranslate(colo)
94 | else
95 | local colo = hexToRgb(splitted[3])
96 | returner.color = colo
97 | end
98 | else
99 | returner.color {r = 0, g = 0, b = 0}
100 | end
101 | returner.card = {splitted[1], splitted[2]}
102 | takeParams = {
103 | position = {119.49, 2.80, 13.54},
104 | rotation = {0, 0, 0},
105 | callback_function = function(obj)
106 | returner.o = obj
107 | table.insert(objs, returner)
108 | end
109 | }
110 | --printTable(objs)
111 |
112 | getObjectFromGUID(bag).takeObject(takeParams)
113 | end
114 |
115 | function setCards()
116 | for i = 1, #objs do
117 | objs[i].o.setCustomObject(
118 | {
119 | image = objs[i].card[1],
120 | image_secondary = objs[i].card[2]
121 | }
122 | )
123 | if objs[i].color ~= nil then
124 | objs[i].o.setColorTint(objs[i].color)
125 | end
126 |
127 | if makeSmall() then
128 | objs[i].o.setScale({1.76, 1.00, 1.76})
129 | end
130 |
131 | objs[i].o.reload()
132 | end
133 |
134 | objs = {}
135 | end
136 |
137 | function colorTranslate(color)
138 | --[[
139 | arr["Green"] = "u";
140 | arr["Navy"] = "r";
141 | arr["BlueViolet"] = "e";
142 | arr["#c46709"] = "l";
143 | --]]
144 | local r = ""
145 | if color == "u" then
146 | r = "Green"
147 | elseif color == "r" then
148 | r = "Blue"
149 | elseif color == "e" then
150 | r = "Purple"
151 | elseif color == "l" then
152 | r = {r = 0.768627, g = 0.403922, b = 0.035294}
153 | else
154 | r = {r = 0, g = 0, b = 0}
155 | end
156 |
157 | return r
158 | end
159 |
160 | --Runs on load, creates button and makes sure the lockout is off
161 | function onload()
162 | self.createButton(
163 | {
164 | label = "Big Red Button\n\nBy: MrStump",
165 | click_function = "buttonPress",
166 | function_owner = self,
167 | position = {0, 0.25, 0},
168 | height = 1400,
169 | width = 1400
170 | }
171 | )
172 | self.createButton(
173 | {
174 | click_function = "changeSmall",
175 | function_owner = self,
176 | label = " ",
177 | position = {-1.5, 0.45, 1.5},
178 | width = 400,
179 | height = 400,
180 | color = {0.856, 0.1, 0.094, 1},
181 | tooltip = "big"
182 | }
183 | )
184 | lockout = false
185 |
186 | local desc = self.getDescription()
187 | if desc ~= "" then
188 | bag = desc
189 | end
190 | self.UI.setAttribute("text", "onValueChanged", self.getGUID() .. "/UIUpdateValue(value)")
191 | end
192 |
193 | function changeSmall()
194 | local btn = self.getButtons()[2]
195 | local isBig = btn.tooltip == "big"
196 | local color = {
197 | red = {0.856, 0.1, 0.094, 1},
198 | green = {0.4418, 0.8101, 0.4248, 1}
199 | }
200 | if isBig then
201 | self.editButton({index = 1, color = color.green})
202 | self.editButton({index = 1, tooltip = "small"})
203 | else
204 | self.editButton({index = 1, color = color.red})
205 | self.editButton({index = 1, tooltip = "big"})
206 | end
207 | end
208 |
209 | function makeSmall()
210 | local btn = self.getButtons()[2]
211 | return btn.tooltip == "small"
212 | end
213 |
214 | function UIUpdateValue(player, text, id)
215 | self.UI.setAttribute("text", "value", text)
216 | end
217 |
218 | --Starts a timer that, when it ends, will unlock the button
219 | function startLockoutTimer()
220 | Timer.create({identifier = self.getGUID(), function_name = "unlockLockout", delay = 0.5})
221 | end
222 |
223 | --Unlocks button
224 | function unlockLockout()
225 | lockout = false
226 | end
227 |
228 | --Ends the timer if the object is destroyed before the timer ends, to prevent an error
229 | function onDestroy()
230 | Timer.destroy(self.getGUID())
231 | end
232 |
233 | function hexToRgb(hex)
234 | hex = hex:gsub("#", "")
235 | if #hex < 8 then
236 | hex = hex .. "ff"
237 | end
238 | return color(
239 | tonumber("0x" .. hex:sub(1, 2), 16) / 255,
240 | tonumber("0x" .. hex:sub(3, 4), 16) / 255,
241 | tonumber("0x" .. hex:sub(5, 6), 16) / 255,
242 | tonumber("0x" .. hex:sub(7, 8), 16) / 255
243 | )
244 | end
245 |
--------------------------------------------------------------------------------
/card creator/card creator.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/command-manager.lua:
--------------------------------------------------------------------------------
1 | local _messages
2 |
3 | function onLoad()
4 | updateMessages()
5 | end
6 |
7 | function updateMessages()
8 | _messages = {}
9 | for _, containedObject in ipairs(self.getObjects()) do
10 | local command = containedObject.name
11 | local desc = containedObject.description
12 |
13 | table.insert(_messages, {command = command, desc = desc})
14 |
15 | end
16 | end
17 |
18 | function isContained(command)
19 | for i = 1, #_messages do
20 | if _messages[i].command == command then
21 | return _messages[i]
22 | end
23 | end
24 |
25 | return false
26 | end
27 |
28 | function onChat(message, player)
29 | local contained = isContained(message)
30 |
31 | if contained then
32 | createDialog(contained)
33 | end
34 | end
35 |
36 | function createDialog(message)
37 | Player["Black"].showMemoDialog(message.command, message.desc)
38 | end
39 |
40 | function onObjectEnterContainer(container, enter_object)
41 | if container == self then
42 | updateMessages()
43 | end
44 | end
45 |
46 | function onObjectLeaveContainer(container, leave_object)
47 | if container == self then
48 | updateMessages()
49 | end
50 | end
--------------------------------------------------------------------------------
/debug-button.lua:
--------------------------------------------------------------------------------
1 | local _stuffs = {
2 | {obj = "28f96e", bag = "e1e28a"},
3 | {obj = "1d7e9d", bag = "627199"},
4 | {obj = "b81df8", bag = "de97c2"}
5 | }
6 |
7 | local _snap = nil
8 | local _color = nil
9 |
10 | function onLoad()
11 | self.setRotation({0.00, 0.00, 0.00})
12 | self.createButton(
13 | {
14 | click_function = "store_stuff",
15 | function_owner = self,
16 | label = "Store Stuff",
17 | position = {0, 0.5, 0},
18 | rotation = {0, 180, 0},
19 | scale = {0.4, 0.7, 0.4},
20 | width = 1600,
21 | height = 450,
22 | font_size = 320
23 | }
24 | )
25 |
26 | local notes = self.getGMNotes()
27 | local vars = JSON.decode(notes)
28 |
29 | if vars.stuff then
30 | _stuffs = vars.stuff
31 | end
32 |
33 | if vars.snap ~= nil then
34 | _snap = vars.snap
35 | end
36 |
37 | if vars.color ~= nil then
38 | _color = hexToRgb(vars.color)
39 | end
40 |
41 | store_stuff()
42 | end
43 |
44 | function store_stuff()
45 | for i = 1, #_stuffs do
46 | local o = getObjectFromGUID(_stuffs[i].obj)
47 | local put =
48 | o.clone(
49 | {
50 | position = {
51 | x = o.getPosition().x,
52 | y = o.getPosition().y + 3,
53 | z = o.getPosition().z
54 | }
55 | }
56 | )
57 | put.setLock(true)
58 |
59 | local b = getObjectFromGUID(_stuffs[i].bag)
60 |
61 | if _color ~= nil then
62 | b.setColorTint(_color)
63 | end
64 |
65 | if _snap ~= nil then
66 | put.use_grid = _snap
67 | put.use_snap_points = _snap
68 | end
69 |
70 | Wait.time(
71 | function()
72 | b.reset()
73 | local waiter = function()
74 | return put.resting
75 | end
76 | local waited = function()
77 | local pos = b.getPosition()
78 | pos.y = pos.y + 2
79 | put.setLock(false)
80 |
81 | put.setPositionSmooth(pos, false, true)
82 | end
83 | Wait.condition(waited, waiter)
84 | end,
85 | 1.2
86 | )
87 | end
88 | end
89 |
90 | function hexToRgb(hex)
91 | hex = hex:gsub("#", "")
92 | if #hex < 8 then
93 | hex = hex .. "ff"
94 | end
95 | return color(
96 | tonumber("0x" .. hex:sub(1, 2), 16) / 255,
97 | tonumber("0x" .. hex:sub(3, 4), 16) / 255,
98 | tonumber("0x" .. hex:sub(5, 6), 16) / 255,
99 | tonumber("0x" .. hex:sub(7, 8), 16) / 255
100 | )
101 | end
102 |
--------------------------------------------------------------------------------
/dice-mat.lua:
--------------------------------------------------------------------------------
1 | local _sz = "876993"
2 | local _blockBag = "012999"
3 |
4 | local _blockPosition = {x=-1.21, y=2.30, z=8.34}
5 | local _blockName = "block"
6 | local _color = "Black"
7 |
8 | local dices = {}
9 |
10 | function getSides(dice)
11 | local values = dice.getRotationValues(dice)
12 | value = values[#values].value
13 | return value
14 | end
15 |
16 | self.createButton({
17 | click_function = "roll_all",
18 | function_owner = self,
19 | label = "Roll All",
20 | position = {0.8, 0.33, 1.15},
21 | rotation = {0, 90, 0},
22 | scale = {0.3, 0.6, 0.5},
23 | width = 600,
24 | height = 200,
25 | font_size = 150,
26 | color = {0.113725, 0.117647, 0.066667, 1}, font_color = {1, 1, 1, 1},
27 | alignment = 3
28 | })
29 |
30 | self.createInput({
31 | input_function = "edit_mods",
32 | function_owner = self,
33 | label = "v",
34 | position = {0.8, 0.35, 0.956},
35 | rotation = {0, 90, 0},
36 | scale = {0.2, 0.4, 0.4},
37 | width = 200,
38 | height = 200,
39 | font_size = 150,
40 | color = {0.1137, 0.1176, 0.0666, 1},
41 | font_color = {1, 1, 1, 1},
42 | tooltip = "Edit All Mods",
43 | alignment = 3
44 | })
45 |
46 | function takeBlock(spawned, name, color, reference)
47 | spawned.setColorTint(color)
48 | spawned.editInput({index=0, value=name})
49 | spawned.editInput({index=1, value=reference.getRotationValue()})
50 | spawned.editInput({index=2, value=reference.getDescription()})
51 | spawned.editInput({index=3, value="= " .. reference.getRotationValue()+reference.getDescription()})
52 |
53 | spawned.setScale({2.29,0.2,1.17})
54 | spawned.tooltip = false
55 | spawned.setName(_blockName)
56 | spawned.setLock(true)
57 |
58 | dices[reference.getGUID()] = spawned.getGUID()
59 | orderBlocks()
60 | end
61 |
62 | function orderBlocks()
63 | local blockPosition = {x=-1.21, y=2.30, z=8.34}
64 | local zone = getObjectFromGUID(_sz)
65 | local objs = zone.getObjects()
66 | local difference = 1.29
67 | for i=0, #objs do
68 | local obj = objs[i]
69 | if obj then
70 | if obj.getName() == _blockName then
71 | obj.setPositionSmooth(blockPosition, false, true)
72 | obj.setRotationSmooth({0,90,0},false,true)
73 | blockPosition.x = blockPosition.x+difference
74 | end
75 | end
76 | end
77 | end
78 |
79 | function onObjectEnterScriptingZone(zone, obj)
80 | if zone.getGUID() == _sz then
81 | if obj.tag == "Dice" then
82 | if obj.getDescription() == "" then
83 | obj.setDescription("0")
84 |
85 | end
86 |
87 | color = obj.getColorTint()
88 | if getSides(obj) == 20 then
89 | local takeParams = {
90 | position = _blockPosition,
91 | rotation = {0.00, 90.00, 0.00},
92 | callback_function = function(block) takeBlock(block, obj.getName(), color, obj) end,
93 | }
94 | getObjectFromGUID(_blockBag).takeObject(takeParams)
95 |
96 | end
97 | end
98 |
99 | end
100 | end
101 |
102 | function onObjectLeaveScriptingZone(zone, obj)
103 | if zone.getGUID() == _sz then
104 | if dices[obj.getGUID()] then
105 | getObjectFromGUID(dices[obj.getGUID()]).destruct()
106 | dices[obj.getGUID()] = nil
107 | orderBlocks()
108 | end
109 | end
110 |
111 | end
112 |
113 | function onObjectRandomize(obj, color)
114 | if color == _color then
115 | if dices[obj.getGUID()] then
116 | --getObjectFromGUID(dices[obj.getGUID()]).call("updateValue")
117 | local block = getObjectFromGUID(dices[obj.getGUID()])
118 | local rollWatch = function() return obj.resting end
119 | local rollEnd = function()
120 | block.editInput({index=1, value = obj.getRotationValue()})
121 | block.call("updateResult", nil)
122 | end
123 | Wait.condition(rollEnd, rollWatch)
124 | end
125 | end
126 | end
127 |
128 | function roll_all()
129 | local zone = getObjectFromGUID(_sz)
130 | local objs = zone.getObjects()
131 | for i=0, #objs do
132 | local obj = objs[i]
133 | if obj then
134 | if obj.getName() == _blockName then
135 | obj.call("roll_die")
136 | end
137 | end
138 | end
139 | end
140 |
141 | function edit_mods(obj, color, _input, stillEditing)
142 | if not stillEditing then
143 | local zone = getObjectFromGUID(_sz)
144 | local objs = zone.getObjects()
145 | for i=0, #objs do
146 | local obj = objs[i]
147 | if obj then
148 | if obj.getName() == _blockName then
149 | obj.call("updateModifier", {input=_input})
150 | end
151 | end
152 | end
153 | end
154 | end
--------------------------------------------------------------------------------
/dice-rolling-tool.lua:
--------------------------------------------------------------------------------
1 | local _dice = {
2 | diceSets = {
3 | [4] = 0,
4 | [6] = 0,
5 | [8] = 0,
6 | [10] = 0,
7 | [12] = 0,
8 | [20] = 0
9 | },
10 | modifier = 0
11 | }
12 |
13 | local registeredDice = {}
14 |
15 | function onload()
16 | self.createButton(
17 | {
18 | click_function = "calculate",
19 | function_owner = self,
20 | label = "Calculate",
21 | position = {0, 0.25, -1.18},
22 | scale = {0.5, 0.5, 0.5},
23 | width = 3075,
24 | height = 600,
25 | font_size = 400
26 | }
27 | )
28 | self.createButton(
29 | {
30 | click_function = "setDiceVal",
31 | function_owner = self,
32 | label = "Dice",
33 | position = {-1, 0.25, -1.75},
34 | scale = {0.5, 0.5, 0.5},
35 | width = 1175,
36 | height = 450,
37 | font_size = 150,
38 | tooltip = "Dice",
39 | alignment = 3
40 | }
41 | )
42 |
43 | self.createButton(
44 | {
45 | click_function = "reset",
46 | function_owner = self,
47 | label = "X",
48 | position = {0, 0.27, -1.75},
49 | scale = {0.5, 0.5, 0.5},
50 | width = 575,
51 | height = 450,
52 | font_size = 250,
53 | color = {0.098, 0.098, 0.098, 1},
54 | font_color = {1, 1, 1, 1},
55 | tooltip = "Reset",
56 | alignment = 3
57 | }
58 | )
59 |
60 | self.createInput(
61 | {
62 | input_function = "setModVal",
63 | function_owner = self,
64 | label = "Mod",
65 | position = {1, 0.25, -1.75},
66 | scale = {0.5, 0.5, 0.5},
67 | width = 1175,
68 | height = 450,
69 | font_size = 400,
70 | tooltip = "Mod",
71 | alignment = 3
72 | }
73 | )
74 | end
75 |
76 | function onCollisionEnter(info)
77 | if info then
78 | local obj = info.collision_object
79 | if obj then
80 | if obj.type == "Dice" and not registered(obj.guid) then
81 | local sides = #obj.getRotationValues()
82 | _dice.diceSets[sides] = _dice.diceSets[sides] + 1
83 | table.insert(registeredDice, obj.guid)
84 | updateDiceVal()
85 | end
86 | end
87 | end
88 | end
89 |
90 | function registered(guid)
91 | for i, v in ipairs(registeredDice) do
92 | if v == guid then
93 | return true
94 | end
95 | end
96 | return false
97 | end
98 |
99 | function setDiceVal(obj, player_color)
100 | updateDiceVal()
101 | end
102 |
103 | function updateDiceVal()
104 | local str = ""
105 | for k, v in pairs(_dice.diceSets) do
106 | if v > 0 then
107 | if string.len(str) > 0 then
108 | str = str .. "+" .. v .. "d" .. k
109 | else
110 | str = v .. "d" .. k
111 | end
112 | end
113 | end
114 | self.editButton({index = 1, label = str})
115 | end
116 |
117 | function setModVal()
118 | _dice.modifier = tonumber(self.getInputs()[1].value)
119 | end
120 |
121 | function reset()
122 | _dice.diceSets = {
123 | [4] = 0,
124 | [6] = 0,
125 | [8] = 0,
126 | [10] = 0,
127 | [12] = 0,
128 | [20] = 0
129 | }
130 | _dice.modifier = 0
131 | self.editButton({index = 1, label = ""})
132 | self.editInput({index = 0, value = ""})
133 | self.editButton({index = 0, label = "Calculate"})
134 | self.setDescription("")
135 | registeredDice = {}
136 | end
137 |
138 | function calculate(obj, player_clicker_color, alt_click)
139 | local green = "2ECC40"
140 | local red = "AAAAAAaa"
141 | local rolledString = self.getButtons()[2].label
142 |
143 | self.setDescription("")
144 | local log = ""
145 | local result = 0
146 |
147 | for k, v in pairs(_dice.diceSets) do
148 | if v > 0 then
149 | local subset = calcSet({sides = k, dice = v})
150 | log = log .. "Rolling " .. v .. "d" .. k .. ": (" .. subset.result .. ")\n "
151 | for i = 1, #subset.rolls do
152 | log =
153 | log ..
154 | string.format("([%s]%s[-] [%s]%s[-])", green, subset.rolls[i].roll, red, subset.rolls[i].scrap)
155 | end
156 | log = log .. "\n"
157 | result = result + subset.result
158 | end
159 | end
160 | log =
161 | log ..
162 | string.format("\n[%s][b]Total: %s + %s = %s[/b][-]", green, result, _dice.modifier, result + _dice.modifier)
163 |
164 | local inCombat = Global.call("isInCombat")
165 | log(inCombat)
166 | log(type(inCombat))
167 | if inCombat then
168 | -- monitoring purposes
169 | printToColor(
170 | string.format("Rolling %s: %s+%s", rolledString, result, _dice.modifier),
171 | "Black",
172 | {0.666, 0.666, 0.666, 1}
173 | )
174 | end
175 | result = result + _dice.modifier
176 | self.setDescription(log)
177 | self.editButton({index = 0, label = result})
178 | end
179 |
180 | function calcSet(set)
181 | local result = 0
182 | local rolls = {}
183 | for i = 1, set.dice do
184 | math.randomseed(math.random(250, 12456))
185 | local roll1 = math.random(1, set.sides)
186 | math.randomseed(math.random(roll1 * math.random(750, 98723)))
187 | local roll2 = math.random(1, set.sides)
188 |
189 | local roll = math.max(roll1, roll2)
190 | table.insert(rolls, {roll = roll, scrap = math.min(roll1, roll2)})
191 | result = result + roll
192 | end
193 | return {result = result, rolls = rolls}
194 | end
195 |
196 | function split(str, pat)
197 | local t = {}
198 | local fpat = "(.-)" .. pat
199 | local last_end = 1
200 | local s,
201 | e,
202 | cap = str:find(fpat, 1)
203 | while s do
204 | if s ~= 1 or cap ~= "" then
205 | table.insert(t, cap)
206 | end
207 | last_end = e + 1
208 | s,
209 | e,
210 | cap = str:find(fpat, last_end)
211 | end
212 | if last_end <= #str then
213 | cap = str:sub(last_end)
214 | table.insert(t, cap)
215 | end
216 | return t
217 | end
218 |
--------------------------------------------------------------------------------
/exploding_dice/exploding-dice.lua:
--------------------------------------------------------------------------------
1 | ref_customDieSides = {["4"] = 0, ["6"] = 1, ["8"] = 2, ["10"] = 3, ["12"] = 4, ["20"] = 5}
2 | ref_customDieSides_rev = {4, 6, 8, 10, 12, 20}
3 | ref_defaultDieSides = {"Die_4", "Die_6", "Die_8", "Die_10", "Die_12", "Die_20"}
4 |
5 | local sides = nil
6 | local rolling = false
7 | local refDie = nil
8 | local crit = nil
9 | local custom_dice = false
10 |
11 | function onLoad()
12 | sides = self.getRotationValues()
13 | custom_dice = self.getCustomObject() ~= nil
14 |
15 | self.addContextMenuItem("Reroll dice", reroll)
16 |
17 | toRoll(self)
18 | end
19 |
20 | function setCustom(params)
21 | ref_diceCustom[params.side] = params.url
22 | end
23 |
24 | function selfReroll(params)
25 | if self.getLock() then
26 | self.setLock(false)
27 | self.setColorTint(Color.Green)
28 | end
29 | end
30 |
31 | function reroll(player_color)
32 | local objs = Player[player_color].getSelectedObjects()
33 |
34 | if #objs > 1 then
35 | for i = 1, #objs do
36 | callIfCallable(objs[i].call("selfReroll"))
37 | --objs[i].call("selfReroll")
38 | end
39 | elseif self.getLock() then
40 | self.setLock(false)
41 | self.setColorTint(Color.Green)
42 | end
43 | end
44 |
45 | function onDestroy()
46 | if refDie ~= nil then
47 | refDie.destruct()
48 | end
49 | end
50 |
51 | function onRandomize()
52 | if not rolling and not self.getLock() then
53 | monitorDie(self)
54 | end
55 | end
56 |
57 | function monitorDie(die)
58 | rolling = true
59 | function monitorDie_coroutine()
60 | repeat
61 | coroutine.yield(0)
62 | until die.resting == true
63 | rolling = false
64 | die.setLock(true)
65 | didRoll(die)
66 |
67 | local gm = self.getGMNotes()
68 | if gm ~= nil and gm ~= "" then
69 | local json = JSON.decode(gm)
70 | if json["crit"] then
71 | crit = json["crit"]
72 | end
73 | end
74 |
75 | if crit then
76 | local value = die.getValue()
77 | if crit == 0 then
78 | explode(die)
79 | elseif value >= #sides - crit then
80 | explode(die)
81 | end
82 | elseif die.getValue() == #sides then
83 | explode(die)
84 | end
85 |
86 | return 1
87 | end
88 | startLuaCoroutine(self, "monitorDie_coroutine")
89 | end
90 |
91 | function explode(die)
92 | if #sides ~= 4 then
93 | local s = ref_customDieSides[tostring(#sides)]
94 | explodeWith(ref_customDieSides_rev[s])
95 | end
96 | end
97 |
98 | function explodeWith(dieSides)
99 | local spawnPos = self.getPosition()
100 | spawnPos.x = spawnPos.x + math.random(-1.5, 1.5)
101 | spawnPos.z = spawnPos.z + math.random(-1.5, 1.5)
102 |
103 | local selfScale = self.getScale()
104 |
105 | if not custom_dice then
106 | dieSides = "Die" .. dieSides
107 | end
108 |
109 | spawnObject(
110 | {
111 | type = custom_dice ~= nil and "Custom_Dice" or dieSides,
112 | position = spawnPos,
113 | rotation = randomRotation(),
114 | scale = {selfScale.x - 0.05, selfScale.y - 0.05, selfScale.z - 0.05},
115 | callback_function = function(obj)
116 | obj.setLuaScript(self.getLuaScript())
117 | obj.setGMNotes(self.getGMNotes())
118 | refDie = obj
119 | if custom_dice ~= nil then
120 | obj.setCustomObject(
121 | {
122 | image = ref_diceCustom[dieSides],
123 | type = ref_customDieSides[tostring(dieSides)]
124 | }
125 | )
126 | obj.reload()
127 | end
128 | end
129 | }
130 | )
131 | end
132 |
133 | function toRoll(die)
134 | die.setColorTint(Color.Green)
135 | end
136 |
137 | function didRoll(die)
138 | die.setColorTint(Color.Red)
139 | end
140 |
141 | --Gets a random rotation vector
142 | function randomRotation()
143 | --Credit for this function goes to Revinor (forums)
144 | --Get 3 random numbers
145 | local u1 = math.random()
146 | local u2 = math.random()
147 | local u3 = math.random()
148 | --Convert them into quats to avoid gimbal lock
149 | local u1sqrt = math.sqrt(u1)
150 | local u1m1sqrt = math.sqrt(1 - u1)
151 | local qx = u1m1sqrt * math.sin(2 * math.pi * u2)
152 | local qy = u1m1sqrt * math.cos(2 * math.pi * u2)
153 | local qz = u1sqrt * math.sin(2 * math.pi * u3)
154 | local qw = u1sqrt * math.cos(2 * math.pi * u3)
155 | --Apply rotation
156 | local ysqr = qy * qy
157 | local t0 = -2.0 * (ysqr + qz * qz) + 1.0
158 | local t1 = 2.0 * (qx * qy - qw * qz)
159 | local t2 = -2.0 * (qx * qz + qw * qy)
160 | local t3 = 2.0 * (qy * qz - qw * qx)
161 | local t4 = -2.0 * (qx * qx + ysqr) + 1.0
162 | --Correct
163 | if t2 > 1.0 then
164 | t2 = 1.0
165 | end
166 | if t2 < -1.0 then
167 | ts = -1.0
168 | end
169 | --Convert back to X/Y/Z
170 | local xr = math.asin(t2)
171 | local yr = math.atan2(t3, t4)
172 | local zr = math.atan2(t1, t0)
173 | --Return result
174 | return {math.deg(xr), math.deg(yr), math.deg(zr)}
175 | end
176 |
177 | function callIfCallable(f)
178 | return function(...)
179 | error,
180 | result = pcall(f, ...)
181 | if error then -- f exists and is callable
182 | print("ok")
183 | return result
184 | end
185 | -- nothing to do, as though not called, or print('error', result)
186 | end
187 | end
188 |
--------------------------------------------------------------------------------
/exploding_dice/exploding-note.lua:
--------------------------------------------------------------------------------
1 | function onLoad()
2 | self.createButton(
3 | {
4 | click_function = "calculateTotal",
5 | function_owner = self,
6 | label = "TOT",
7 | position = {0, 2.5, -0.37},
8 | rotation = {0, 180, 0},
9 | scale = {0.3, 0.5, 0.5},
10 | width = 350,
11 | height = 300,
12 | color = {0, 0, 0, 1},
13 | font_color = {1, 1, 1, 1},
14 | tooltip = "Total"
15 | }
16 | )
17 | self.createButton(
18 | {
19 | click_function = "clearDice",
20 | function_owner = self,
21 | label = "X",
22 | position = {-0.46, 2.5, 0.44},
23 | rotation = {0.00, 180.00, 0.00},
24 | scale = {0.5, 0.5, 0.5},
25 | width = 65,
26 | height = 100,
27 | font_size = 50,
28 | color = {0, 0, 0, 1},
29 | font_color = {1, 0, 0, 1},
30 | tooltip = "Clear Dice"
31 | }
32 | )
33 |
34 | self.createButton(
35 | {
36 | click_function = "clearTotal",
37 | function_owner = self,
38 | label = "Clear Total",
39 | position = {-0.36, 2.5, 0.439999997615814},
40 | rotation = {0, 180, 0},
41 | scale = {0.2, 0.5, 0.3},
42 | width = 315,
43 | height = 185,
44 | font_size = 50,
45 | color = {0, 0, 0, 1},
46 | font_color = {1, 0, 0, 1},
47 | tooltip = ""
48 | }
49 | )
50 | end
51 |
52 | function calculateTotal()
53 | local desc = self.getDescription()
54 | if desc ~= "" then
55 | local numbers = mysplit(desc, ", ")
56 | local tot = 0
57 | for i = 1, #numbers do
58 | tot = tot + numbers[i]
59 | end
60 | self.editButton({index = 0, label = tot})
61 | end
62 | end
63 |
64 | function clearDice()
65 | local desc = self.getGMNotes()
66 | if desc ~= "" then
67 | local objs = mysplit(desc, ",")
68 | for i = 1, #objs do
69 | local o = getObjectFromGUID(objs[i])
70 | o.destruct()
71 | end
72 | self.setGMNotes("")
73 | end
74 | end
75 |
76 | function clearTotal()
77 | self.setDescription("")
78 | local oldTot = self.getButtons()[1].label
79 |
80 | self.editButton({index = 0, label = "TOT"})
81 | self.editButton({index = 2, tooltip = "Old Total: " .. oldTot})
82 | end
83 |
84 | function mysplit(inputstr, sep)
85 | if sep == nil then
86 | sep = "%s"
87 | end
88 | local t = {}
89 | i = 1
90 | for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
91 | t[i] = str
92 | i = i + 1
93 | end
94 | return t
95 | end
96 |
--------------------------------------------------------------------------------
/hide-me.lua:
--------------------------------------------------------------------------------
1 | function onload()
2 | local gm = self.getGMNotes()
3 | if gm == "" then
4 | self.setGMNotes("true")
5 | gm = "true"
6 | end
7 |
8 | if gm == "true" then
9 | self.addContextMenuItem("[2ECC40]Visible[-]", hideMe)
10 | else
11 | self.addContextMenuItem("[FF4136]Invisible[-]", showMe)
12 | end
13 | end
14 |
15 | function hideMe()
16 | self.setGMNotes("false")
17 | self.setInvisibleTo(
18 | {
19 | "White",
20 | "Brown",
21 | "Red",
22 | "Orange",
23 | "Yellow",
24 | "Green",
25 | "Teal",
26 | "Blue",
27 | "Purple",
28 | "Pink",
29 | "Grey"
30 | }
31 | )
32 |
33 | self.clearContextMenu()
34 | self.addContextMenuItem("[FF4136]Invisible[-]", showMe)
35 | end
36 |
37 | function showMe()
38 | self.setGMNotes("true")
39 | self.setInvisibleTo({})
40 |
41 | self.clearContextMenu()
42 | self.addContextMenuItem("[2ECC40]Visible[-]", hideMe)
43 | end
--------------------------------------------------------------------------------
/image-changer.lua:
--------------------------------------------------------------------------------
1 | --Runs when the scripted button inside the button is clicked
2 | function buttonPress()
3 | if lockout == false then
4 | local gm = self.getGMNotes()
5 | local obj = getObjectFromGUID(gm)
6 |
7 | local img = self.getDescription()
8 | obj.setCustomObject({image = img})
9 | obj.reload()
10 |
11 | obj.highlightOn(Color.White, 2)
12 |
13 | self.AssetBundle.playTriggerEffect(0) --triggers animation/sound
14 | lockout = true --locks out the button
15 | startLockoutTimer() --Starts up a timer to remove lockout
16 | end
17 | end
18 |
19 | --Runs on load, creates button and makes sure the lockout is off
20 | function onload()
21 | self.createButton(
22 | {
23 | label = "Big Red Button\n\nBy: MrStump",
24 | click_function = "buttonPress",
25 | function_owner = self,
26 | position = {0, 0.25, 0},
27 | height = 1400,
28 | width = 1400
29 | }
30 | )
31 | lockout = false
32 | end
33 |
34 | --Starts a timer that, when it ends, will unlock the button
35 | function startLockoutTimer()
36 | Timer.create({identifier = self.getGUID(), function_name = "unlockLockout", delay = 0.5})
37 | end
38 |
39 | --Unlocks button
40 | function unlockLockout()
41 | lockout = false
42 | end
43 |
44 | --Ends the timer if the object is destroyed before the timer ends, to prevent an error
45 | function onDestroy()
46 | Timer.destroy(self.getGUID())
47 | end
48 |
--------------------------------------------------------------------------------
/interactable.lua:
--------------------------------------------------------------------------------
1 | function onLoad(save_state)
2 | self.createButton(
3 | {
4 | click_function = "make_interact",
5 | function_owner = self,
6 | label = "Make Interactable",
7 | position = {0, 0.5, 0.8},
8 | scale = {0.5, 0.5, 0.5},
9 | width = 3300,
10 | height = 600,
11 | font_size = 400,
12 | color = {0.192, 0.701, 0.168, 1}
13 | }
14 | )
15 |
16 | self.createButton(
17 | {
18 | click_function = "make_not_interact",
19 | function_owner = self,
20 | label = "Make Non-Interactable",
21 | position = {0, 0.5, 1.6},
22 | scale = {0.5, 0.5, 0.5},
23 | width = 4200,
24 | height = 600,
25 | font_size = 400,
26 | color = {0.856, 0.1, 0.094, 1}
27 | }
28 | )
29 | end
30 |
31 | function isMe(id)
32 | return id == self.getGUID()
33 | end
34 |
35 | function onCollisionEnter(info)
36 | local id = info.collision_object.getGUID()
37 | self.setDescription("Found: " .. id .. "\nMyself: " .. self.guid)
38 | end
39 |
40 | function make_interact(obj, player_clicker_color, alt_click)
41 | local id = self.getDescription()
42 | if Player[player_clicker_color].admin and not isMe(id) then
43 | local id = self.getDescription()
44 | if id == "" then
45 | return
46 | end
47 | local o = getObjectFromGUID(id)
48 |
49 | o.interactable = true
50 | self.setDescription("")
51 | Player[player_clicker_color].pingTable(getObjectFromGUID(id).getPosition())
52 |
53 | local code = "function onload() self.interactable = true end"
54 | o.setLuaScript(code)
55 | end
56 | end
57 |
58 | function make_not_interact(obj, player_clicker_color, alt_click)
59 | if Player[player_clicker_color].admin and not isMe(id) then
60 | local id = self.getDescription()
61 | if id == "" then
62 | return
63 | end
64 | local o = getObjectFromGUID(id)
65 | o.interactable = false
66 | o.setLock(true)
67 | self.setDescription("")
68 | Player[player_clicker_color].pingTable(getObjectFromGUID(id).getPosition())
69 |
70 | local code = "function onload() self.interactable = false end"
71 | o.setLuaScript(code)
72 | end
73 | end
74 |
--------------------------------------------------------------------------------
/item-positioner.lua:
--------------------------------------------------------------------------------
1 | local _objs = {
2 | ["d645e1"] = {pos = {5.52, 10.47, 8.68}, start = {}, moved = false},
3 | ["3d7a9b"] = {pos = {9.84, 10.47, 14.15}, start = {}, moved = false},
4 | ["62b14e"] = {pos = {11.66, 10.47, 6.45}, start = {}, moved = false},
5 | ["989b93"] = {pos = {5.49, 10.47, -3.39}, start = {}, moved = false},
6 | ["53caf9"] = {pos = {9.90, 10.47, -8.87}, start = {}, moved = false},
7 | ["2c0d91"] = {pos = {11.68, 10.47, -1.18}, start = {}, moved = false},
8 | ["9462fd"] = {pos = {14.96, 10.47, 2.68}, start = {}, moved = false},
9 | ["016301"] = {pos = {1.95, 10.47, 12.58}, start = {}, moved = false},
10 | ["7b3148"] = {pos = {1.91, 10.47, -7.35}, start = {}, moved = false},
11 | ["cb43e0"] = {pos = {0.66, 8.61, 5.34}, start = {}, moved = false},
12 | ["c9d7ee"] = {pos = {0.70, 8.61, -0.09}, start = {}, moved = false},
13 | ["76e7e6"] = {pos = {-2.44, 7.12, 3.72}, start = {}, moved = false},
14 | ["4b84cd"] = {pos = {-2.44, 7.12, 1.32}, start = {}, moved = false},
15 | ["5cd489"] = {pos = {-4.96, 7.12, 0.46}, start = {}, moved = false},
16 | ["e30a6a"] = {pos = {-4.96, 7.12, 4.55}, start = {}, moved = false}
17 | }
18 |
19 | local set = false
20 |
21 | function onLoad()
22 | local buttons = {
23 | {
24 | label = "d645e1",
25 | position = {1.2, 0.2, 0},
26 | scale = {0.5, 0.5, 0.5},
27 | width = 650,
28 | height = 200
29 | },
30 | {
31 | label = "3d7a9b",
32 | position = {1.5, 0.2, 0.4},
33 | scale = {0.5, 0.5, 0.5},
34 | width = 650,
35 | height = 200
36 | },
37 | {
38 | label = "62b14e",
39 | position = {0.9, 0.2, 0.8},
40 | scale = {0.5, 0.5, 0.5},
41 | width = 650,
42 | height = 200
43 | },
44 | {
45 | label = "989b93",
46 | position = {-1.2, 0.2, 0},
47 | scale = {0.5, 0.5, 0.5},
48 | width = 650,
49 | height = 200
50 | },
51 | {
52 | label = "53caf9",
53 | position = {-1.5, 0.2, 0.4},
54 | scale = {0.5, 0.5, 0.5},
55 | width = 650,
56 | height = 200
57 | },
58 | {
59 | label = "2c0d91",
60 | position = {-0.9, 0.2, 0.8},
61 | scale = {0.5, 0.5, 0.5},
62 | width = 650,
63 | height = 200
64 | },
65 | {
66 | label = "9462fd",
67 | position = {0, 0.2, 1.2},
68 | scale = {0.5, 0.5, 0.5},
69 | width = 650,
70 | height = 200
71 | },
72 | {
73 | label = "016301",
74 | position = {1.4, 0.2, -0.4},
75 | scale = {0.5, 0.5, 0.5},
76 | width = 650,
77 | height = 200
78 | },
79 | {
80 | label = "7b3148",
81 | position = {-1.4, 0.2, -0.4},
82 | scale = {0.5, 0.5, 0.5},
83 | width = 650,
84 | height = 200
85 | },
86 | {
87 | label = "cb43e0",
88 | position = {0.25, 0.2, -0.7},
89 | scale = {0.5, 0.5, 0.5},
90 | width = 450,
91 | height = 200
92 | },
93 | {
94 | label = "c9d7ee",
95 | position = {-0.25, 0.2, -0.7},
96 | scale = {0.5, 0.5, 0.5},
97 | width = 450,
98 | height = 200
99 | },
100 | {
101 | label = "76e7e6",
102 | position = {0.35, 0.2, -1.1},
103 | scale = {0.5, 0.5, 0.5},
104 | width = 450,
105 | height = 200
106 | },
107 | {
108 | label = "4b84cd",
109 | position = {-0.35, 0.2, -1.1},
110 | scale = {0.5, 0.5, 0.5},
111 | width = 450,
112 | height = 200
113 | },
114 | {
115 | label = "5cd489",
116 | position = {-0.4, 0.2, -1.3},
117 | scale = {0.5, 0.5, 0.5},
118 | width = 450,
119 | height = 200
120 | },
121 | {
122 | label = "e30a6a",
123 | position = {0.4, 0.2, -1.3},
124 | scale = {0.5, 0.5, 0.5},
125 | width = 450,
126 | height = 200
127 | }
128 | }
129 | for i = 1, #buttons do
130 | local funcName = "button_" .. i
131 | local func = function(_, c)
132 | button_click(c, buttons[i].label)
133 | end
134 | self.setVar(funcName, func)
135 | self.createButton(
136 | {
137 | click_function = funcName,
138 | function_owner = self,
139 | label = buttons[i].label,
140 | position = buttons[i].position,
141 | scale = {0.5, 0.5, 0.5},
142 | width = buttons[i].width,
143 | height = buttons[i].height
144 | }
145 | )
146 | end
147 |
148 | self.createButton(
149 | {
150 | click_function = "interactable",
151 | function_owner = self,
152 | label = "Interactable",
153 | position = {0, 0.2, -0.2},
154 | scale = {0.5, 0.5, 0.5},
155 | width = 650,
156 | height = 300
157 | }
158 | )
159 | self.createButton(
160 | {
161 | click_function = "setup",
162 | function_owner = self,
163 | label = "Setup",
164 | position = {0, 0.2, 0.1},
165 | scale = {0.5, 0.5, 0.5},
166 | width = 650,
167 | height = 300
168 | }
169 | )
170 | end
171 |
172 | function button_click(color, guid)
173 | if not set then
174 | notSet()
175 | return
176 | end
177 |
178 | local o = getObjectFromGUID(guid)
179 | local obj = _objs[guid]
180 | if (obj) then
181 | if not obj.moved then
182 | o.setPositionSmooth(obj.pos, false, false)
183 | obj.moved = true
184 | else
185 | o.setPositionSmooth(obj.start, false, false)
186 | obj.moved = false
187 | end
188 | end
189 | end
190 |
191 | function notSet()
192 | broadcastToColor("Need to set the thing", "Black", {r = 1, g = 1, b = 1})
193 | end
194 |
195 | function setup()
196 | for guid, a in pairs(_objs) do
197 | local obj = getObjectFromGUID(guid)
198 | _objs[guid].start = obj.getPosition()
199 | end
200 |
201 | set = true
202 | end
203 |
204 | function interactable()
205 | if not set then
206 | notSet()
207 | return
208 | end
209 | for guid, a in pairs(_objs) do
210 | local obj = getObjectFromGUID(guid)
211 | obj.interactable = not obj.interactable
212 | end
213 | end
214 |
--------------------------------------------------------------------------------
/item-stack.lua:
--------------------------------------------------------------------------------
1 | function onLoad()
2 | self.createButton(
3 | {
4 | click_function = "stack",
5 | function_owner = self,
6 | label = " ",
7 | position = {0, 0.1, 0},
8 | scale = {0.5, 0.5, 0.5},
9 | width = 750,
10 | height = 750,
11 | font_size = 400,
12 | color = {0.5, 0.5, 0.5, 1},
13 | tooltip = "Stack buttons"
14 | }
15 | )
16 |
17 | self.setGMNotes("")
18 | end
19 |
20 | function onCollisionEnter(info)
21 | if info then
22 | local obj = info.collision_object
23 | if obj then
24 | if obj.interactable then
25 | if obj.getGUID() then
26 | local returner = {}
27 | local gm = self.getGMNotes()
28 | local json = JSON.decode(gm)
29 | if json then
30 | returner = json
31 | end
32 |
33 | table.insert(returner, obj.getGUID())
34 | self.setGMNotes(JSON.encode(returner))
35 | end
36 | end
37 | end
38 | end
39 | end
40 |
41 | -- function onObjectCollisionEnter(hit_object, collision_info)
42 | -- -- collision_info table:
43 | -- -- collision_object Object
44 | -- -- contact_points Table {Vector, ...}
45 | -- -- relative_velocity Vector
46 |
47 | -- local returner = {}
48 | -- local gm = self.getGMNotes()
49 | -- local json = JSON.decode(gm)
50 | -- if #json > 0 then
51 | -- returner = json
52 | -- end
53 |
54 | -- if hit_object.interactable then
55 | -- local id = hit_object.getGUID()
56 | -- table.insert(returner, id)
57 | -- self.setGMNotes(JSON.encode(returner))
58 | -- end
59 | -- end
60 |
61 | function stack()
62 | local gm = self.getGMNotes()
63 | local objs = JSON.decode(gm)
64 |
65 | local pos = self.getPosition()
66 | local rot = self.getRotation()
67 |
68 | pos.x = pos.x - 7
69 | pos.y = pos.y + 10
70 |
71 | for i, obj in ipairs(objs) do
72 | local o = getObjectFromGUID(obj)
73 | if o then
74 | Wait.time(
75 | function()
76 | o.setPosition(pos)
77 | o.setRotation({0, 0, 0})
78 | end,
79 | 0.2 * i
80 | )
81 | end
82 | end
83 | self.setGMNotes("")
84 | end
85 |
--------------------------------------------------------------------------------
/macro-maker.lua:
--------------------------------------------------------------------------------
1 | function onLoad()
2 | self.createButton(
3 | {
4 | click_function = "work_macro",
5 | function_owner = self,
6 | label = "Activate Macro",
7 | position = {0, 0.5, 0.8},
8 | scale = {0.5, 0.5, 0.5},
9 | width = 3300,
10 | height = 600,
11 | font_size = 400,
12 | color = {0.2026, 0.4071, 0.9773, 1}
13 | }
14 | )
15 | end
16 |
17 | function none()
18 | end
19 |
20 | function onCollisionEnter(info)
21 | if info.collision_object.interactable then
22 | local id = info.collision_object.getGUID()
23 | local gm = self.getGMNotes()
24 | local macro = JSON.decode(gm)
25 | macro.obj = id
26 | self.setGMNotes(JSON.encode(macro))
27 | end
28 | end
29 |
30 | function onHover(player_color)
31 | if player_color == "Black" then
32 | local gm = self.getGMNotes()
33 | if gm == "" or gm == nil then
34 | self.setGMNotes(
35 | [[{
36 | "obj":"aaaaaa",
37 | "position":[999,999,999],
38 | "rotation":[999,999,999],
39 | "interact": true,
40 | "lock": true,
41 | "visible": true
42 | }]]
43 | )
44 | self.highlightOn(Color.Green, 1)
45 | end
46 | end
47 | end
48 |
49 | function work_macro()
50 | -- position
51 | -- make interactable
52 | -- make visible
53 | --[[
54 | {
55 | "obj":"aaaaaa",
56 | "position":[1,1,1],
57 | "rotation":[1,1,1],
58 | "interact": true,
59 | "lock": true,
60 | "visible": true
61 | }
62 | ]]
63 | -- with position = 999 then the token will take relative position
64 | local gm = self.getGMNotes()
65 | if gm then
66 | local macro = JSON.decode(gm)
67 |
68 | local obj = getObjectFromGUID(macro.obj)
69 | local pos,
70 | rot,
71 | interact
72 | if exists(macro.position) ~= nil then
73 | pos = {
74 | x = correctPositionCoordinate("x", macro.position[1], obj),
75 | y = correctPositionCoordinate("y", macro.position[2], obj),
76 | z = correctPositionCoordinate("z", macro.position[3], obj)
77 | }
78 | obj.setPosition(pos)
79 | end
80 | if exists(macro.rotation) then
81 | rot = {
82 | x = correctRotationCoordinate("x", macro.rotation[1], obj),
83 | y = correctRotationCoordinate("y", macro.rotation[2], obj),
84 | z = correctRotationCoordinate("z", macro.rotation[3], obj)
85 | }
86 | obj.setRotation(rot)
87 | end
88 | if exists(macro.interact) then
89 | interact = macro.interact
90 | if exists(macro.lock) then
91 | toggle_interact(obj, interact, macro.lock)
92 | else
93 | toggle_interact(obj, interact, true)
94 | end
95 | end
96 |
97 | if exists(macro.visible) then
98 | if macro.visible then
99 | obj.setColorTint({r = 1, g = 1, b = 1, a = 1})
100 | else
101 | obj.setColorTint({r = 1, g = 1, b = 1, a = 0})
102 | end
103 | end
104 | end
105 | end
106 |
107 | function correctPositionCoordinate(xyz, coord, obj)
108 | if coord == 999 then
109 | return obj.getPosition()[xyz]
110 | else
111 | return coord
112 | end
113 | end
114 |
115 | function correctRotationCoordinate(xyz, coord, obj)
116 | if coord == 999 then
117 | return obj.getRotation()[xyz]
118 | else
119 | return coord
120 | end
121 | end
122 |
123 | function exists(variable)
124 | return variable ~= nil
125 | end
126 |
127 | function toggle_interact(o, interact, lock)
128 | o.interactable = interact
129 | o.setLock(lock)
130 | local code = "function onload() self.interactable = " .. tostring(interact) .. " end"
131 | o.setLuaScript(code)
132 | end
133 |
--------------------------------------------------------------------------------
/notecard 2.0.lua:
--------------------------------------------------------------------------------
1 | --local commander = "9d42ad"
2 | local commander = "878b50"
3 |
4 | function onLoad()
5 | local data = {
6 | click_function = "parse",
7 | function_owner = self,
8 | label = "Parse",
9 | position = {-0.39, 2.4, -0.43},
10 | rotation = {0, 180, 0},
11 | scale = {0.1, 1, 0.18},
12 | width = 1100,
13 | height = 400,
14 | font_size = 400,
15 | color = {0.1341, 0.1341, 0.1341, 1},
16 | font_color = {1, 1, 1, 1}
17 | }
18 | self.createButton(data)
19 | end
20 |
21 | --/|2|r50-68|12|6|2d6+4
22 |
23 | function parse()
24 | if self.getDescription() ~= "" and self.getName() ~= "" then
25 | local vars = JSON.decode(self.getDescription())
26 | local npc_commander = getObjectFromGUID(commander)
27 |
28 | if vars.name then
29 | npc_commander.call("setName", {input = vars.name})
30 | end
31 |
32 | if vars.ini then
33 | npc_commander.call("setINI", {input = vars.ini})
34 | end
35 |
36 | if vars.hp then
37 | npc_commander.call("setHP", {input = vars.hp})
38 | end
39 |
40 | if vars.ac then
41 | npc_commander.call("setAC", {input = vars.ac})
42 | end
43 |
44 | if vars.mov then
45 | npc_commander.call("setMovement", {input = vars.mov})
46 | end
47 |
48 | if vars.size then
49 | npc_commander.call("setSize", {input = vars.size})
50 | end
51 |
52 | if vars.image then
53 | npc_commander.setDescription(vars.image)
54 | npc_commander.call("toggleIsBoss", {input = true})
55 | else
56 | npc_commander.call("toggleIsBoss", {input = false})
57 | end
58 |
59 | if vars.side then
60 | npc_commander.call("setSide", {input = vars.side})
61 | else
62 | npc_commander.call("setSide", {input = "enemy"})
63 | end
64 |
65 | if self.getGMNotes() ~= "" then
66 | -- this means i have multiple that i want to make
67 | local number = tonumber(self.getGMNotes())
68 | npc_commander.call("setNumberToCreate", {input = number})
69 | else
70 | npc_commander.call("setNumberToCreate", {input = 1})
71 | end
72 |
73 | -- local stuff = mysplit(mysplit(self.getDescription(), "\n")[1], "|")
74 | -- local npc_commander = getObjectFromGUID(commander)
75 | -- npc_commander.call("setName", {input = stuff[1]})
76 | -- npc_commander.call("setINI", {input = stuff[2]})
77 | -- npc_commander.call("setHP", {input = stuff[3]})
78 | -- npc_commander.call("setAC", {input = stuff[4]})
79 | -- npc_commander.call("setATK", {input = stuff[5]})
80 | -- npc_commander.call("setDMG", {input = stuff[6]})
81 |
82 | -- if stuff[7] then
83 | -- npc_commander.call("setMovement", {input = stuff[7]})
84 | -- end
85 |
86 | -- if stuff[8] then
87 | -- npc_commander.call("setSize", {input = stuff[8]})
88 | -- end
89 |
90 | -- local second_line = mysplit(self.getDescription(), "\n")[2]
91 | -- if second_line ~= nil and second_line ~= "" then
92 | -- -- this means it is a boss
93 | -- npc_commander.setDescription(second_line)
94 | -- npc_commander.call("toggleIsBoss", {input = true})
95 | -- else
96 | -- npc_commander.call("toggleIsBoss", {input = false})
97 | -- end
98 |
99 | -- if self.getGMNotes() ~= "" then
100 | -- -- this means i have multiple that i want to make
101 | -- local number = tonumber(self.getGMNotes())
102 | -- npc_commander.call("setNumberToCreate", {input = number})
103 | -- end
104 | end
105 | end
106 |
107 | function mysplit(inputstr, sep)
108 | if sep == nil then
109 | sep = "%s"
110 | end
111 | local t = {}
112 | i = 1
113 | for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
114 | t[i] = str
115 | i = i + 1
116 | end
117 | return t
118 | end
119 |
--------------------------------------------------------------------------------
/pin-positioner.lua:
--------------------------------------------------------------------------------
1 | --Runs when the scripted button inside the button is clicked
2 | function buttonPress()
3 | if lockout == false then
4 | local desc = self.getDescription()
5 | if desc ~= "" then
6 | local obj = getObjectFromGUID(desc)
7 |
8 | local notes = obj.getGMNotes()
9 | local pos = {}
10 | local rot = {}
11 |
12 | if notes == "" then
13 | pos = {115.27, 11.88, -79.46}
14 | rot = {347.94, 314.99, 0.35}
15 | else
16 | local vars = JSON.decode(notes)
17 | pos = {vars.pos[1], vars.pos[2], vars.pos[3]}
18 | rot = {vars.rot[1], vars.rot[2], vars.rot[3]}
19 | end
20 | obj.setPositionSmooth(pos, false, true)
21 | obj.setRotationSmooth(rot, false, true)
22 | obj.setLock(true)
23 | self.setDescription("")
24 | end
25 |
26 | self.AssetBundle.playTriggerEffect(0) --triggers animation/sound
27 | lockout = true --locks out the button
28 | startLockoutTimer() --Starts up a timer to remove lockout
29 | end
30 | end
31 |
32 | --Runs on load, creates button and makes sure the lockout is off
33 | function onload()
34 | self.createButton(
35 | {
36 | label = "Big Red Button\n\nBy: MrStump",
37 | click_function = "buttonPress",
38 | function_owner = self,
39 | position = {0, 0.25, 0},
40 | height = 1400,
41 | width = 1400
42 | }
43 | )
44 | lockout = false
45 | end
46 |
47 | function onCollisionEnter(info)
48 | local obj = info.collision_object
49 | if obj.interactable then
50 | if obj.getGUID() then
51 | self.setDescription(obj.getGUID())
52 | end
53 | end
54 | end
55 |
56 | --Starts a timer that, when it ends, will unlock the button
57 | function startLockoutTimer()
58 | Timer.create({identifier = self.getGUID(), function_name = "unlockLockout", delay = 0.5})
59 | end
60 |
61 | --Unlocks button
62 | function unlockLockout()
63 | lockout = false
64 | end
65 |
66 | --Ends the timer if the object is destroyed before the timer ends, to prevent an error
67 | function onDestroy()
68 | Timer.destroy(self.getGUID())
69 | end
70 |
--------------------------------------------------------------------------------
/pin.lua:
--------------------------------------------------------------------------------
1 | function onLoad(save_state)
2 | local desc = self.getDescription()
3 | local label = ""
4 | if desc ~= "" then
5 | label = desc
6 | end
7 |
8 | --self.createButton(
9 | -- {
10 | -- click_function = "none",
11 | -- function_owner = self,
12 | -- label = label,
13 | -- position = {0, 0, 1},
14 | -- rotation = {-90, 0, 0},
15 | -- scale = {0.5, 0.5, 0.5},
16 | -- width = 2000,
17 | -- height = 900,
18 | -- font_size = 250,
19 | -- alignment = 3
20 | -- }
21 | --)
22 |
23 | self.UI.setAttribute("txt", "text", label)
24 | if label == "" then
25 | self.UI.setAttribute("bg", "color", "#ffffff00")
26 | else
27 | self.UI.setAttribute("bg", "color", "#ffffffaa")
28 | if hasSecondLine(label) then
29 | self.UI.setAttribute("bg", "height", "60")
30 | else
31 | self.UI.setAttribute("bg", "height", "30")
32 | end
33 | end
34 |
35 | self.addContextMenuItem("[1A4F8B]Aquila[-]", aquila)
36 | self.addContextMenuItem("[76922B]Ekehm[-]", ekehm)
37 | self.addContextMenuItem("[813CA3]Mourning Lands[-]", ml)
38 | self.addContextMenuItem("[9B1412]Oshil[-]", oshil)
39 | self.addContextMenuItem("[B03900]Trisen[-]", trisen)
40 | self.addContextMenuItem("[8AB90D]Zunirth[-]", zunirth)
41 | self.addContextMenuItem("[39CCCC]Save[-]", save)
42 | self.addContextMenuItem("[1E6D6D]Reposition[-]", repos)
43 | end
44 |
45 | local _reposPos = {129.35, 4, -29.81}
46 | function repos(player_color)
47 | if (player_color == "Black") then
48 | self.setPositionSmooth(_reposPos, false, false)
49 | self.setRotation({0, 270, 0})
50 | self.setLock(false)
51 | end
52 | end
53 |
54 | function save()
55 | local curPos = self.getPosition()
56 | local curRot = self.getRotation()
57 | local vals = {
58 | pos = {
59 | tonumber(string.format("%.2f", curPos.x)),
60 | tonumber(string.format("%.2f", curPos.y)),
61 | tonumber(string.format("%.2f", curPos.z))
62 | },
63 | rot = {
64 | tonumber(string.format("%.2f", curRot.x)),
65 | tonumber(string.format("%.2f", curRot.y)),
66 | tonumber(string.format("%.2f", curRot.z))
67 | }
68 | }
69 | self.setGMNotes(JSON.encode(vals))
70 | end
71 |
72 | function none()
73 | end
74 |
75 | function aquila()
76 | self.setColorTint({r = 27 / 255, g = 80 / 255, b = 140 / 255})
77 | end
78 |
79 | function trisen()
80 | self.setColorTint({r = 176 / 255, g = 58 / 255, b = 0 / 255})
81 | end
82 |
83 | function oshil()
84 | self.setColorTint({r = 155 / 255, g = 21 / 255, b = 19 / 255})
85 | end
86 |
87 | function zunirth()
88 | self.setColorTint({r = 138 / 255, g = 185 / 255, b = 14 / 255})
89 | end
90 |
91 | function ml()
92 | self.setColorTint({r = 130 / 255, g = 61 / 255, b = 163 / 255})
93 | end
94 |
95 | function ekehm()
96 | self.setColorTint({r = 119 / 255, g = 146 / 255, b = 44 / 255})
97 | end
98 |
99 | local lineHeight = 30
100 | local offset = 10
101 | function onObjectPickUp(player_color, picked_up_object)
102 | if picked_up_object.getGUID() == self.getGUID() then
103 | --self.editButton(
104 | -- {
105 | -- index = 0,
106 | -- label = self.getDescription()
107 | -- }
108 | --)
109 | local label = self.getDescription()
110 | self.UI.setAttribute("txt", "text", label)
111 | if label == "" then
112 | self.UI.setAttribute("bg", "color", "#ffffff00")
113 | else
114 | self.UI.setAttribute("bg", "color", "#ffffffaa")
115 | if hasSecondLine(label) then
116 | self.UI.setAttribute("bg", "height", tostring(lineHeight * 2))
117 | else
118 | self.UI.setAttribute("bg", "height", tostring(lineHeight))
119 | end
120 | end
121 | end
122 | end
123 |
124 | function hasSecondLine(txt)
125 | return string.find(txt, "\n") ~= nil
126 | end
127 |
--------------------------------------------------------------------------------
/pin.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/player_manager/conditions/blinded.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/blinded.png
--------------------------------------------------------------------------------
/player_manager/conditions/charmed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/charmed.png
--------------------------------------------------------------------------------
/player_manager/conditions/concentration.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/concentration.png
--------------------------------------------------------------------------------
/player_manager/conditions/deafened.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/deafened.png
--------------------------------------------------------------------------------
/player_manager/conditions/frightened.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/frightened.png
--------------------------------------------------------------------------------
/player_manager/conditions/grappled.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/grappled.png
--------------------------------------------------------------------------------
/player_manager/conditions/incapacitated.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/incapacitated.png
--------------------------------------------------------------------------------
/player_manager/conditions/invisible.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/invisible.png
--------------------------------------------------------------------------------
/player_manager/conditions/on fire.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/on fire.png
--------------------------------------------------------------------------------
/player_manager/conditions/paralyzed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/paralyzed.png
--------------------------------------------------------------------------------
/player_manager/conditions/petrified.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/petrified.png
--------------------------------------------------------------------------------
/player_manager/conditions/poisoned.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/poisoned.png
--------------------------------------------------------------------------------
/player_manager/conditions/restrained.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/restrained.png
--------------------------------------------------------------------------------
/player_manager/conditions/stunned.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/conditions/stunned.png
--------------------------------------------------------------------------------
/player_manager/move-token-snippet.lua:
--------------------------------------------------------------------------------
1 | function onUpdate()
2 | self.interactable = false
3 | local mypos = self.getPosition()
4 | if measuredObject == nil or measuredObject.held_by_color == nil then
5 | destroyObject(self)
6 | return
7 | end
8 | local opos = measuredObject.getPosition()
9 | local oheld = measuredObject.held_by_color
10 | opos.y = opos.y - (Player[myPlayer].lift_height * 5)
11 | mdiff = mypos - opos
12 | if oheld then
13 | mDistance = math.abs(mdiff.x)
14 | zDistance = math.abs(mdiff.z)
15 | if zDistance > mDistance then
16 | mDistance = zDistance
17 | end
18 | mDistance = mDistance * (5.0 / Grid.sizeX)
19 | mDistance = (math.floor((mDistance + 2.5) / 5.0) * 5)
20 | self.editButton({index = 0, label = tostring(mDistance)})
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/player_manager/move-token-snippet.min.lua:
--------------------------------------------------------------------------------
1 | function onUpdate()self.interactable=false;local a=self.getPosition()if measuredObject==nil or measuredObject.held_by_color==nil then destroyObject(self)return end;local b=measuredObject.getPosition()local c=measuredObject.held_by_color;b.y=b.y-Player[myPlayer].lift_height*5;mdiff=a-b;if c then mDistance=math.abs(mdiff.x)zDistance=math.abs(mdiff.z)if zDistance>mDistance then mDistance=zDistance end;mDistance=mDistance*5.0/Grid.sizeX;mDistance=math.floor((mDistance+2.5)/5.0)*5;self.editButton({index=0,label=tostring(mDistance)})end end
--------------------------------------------------------------------------------
/player_manager/player-manager-area.lua:
--------------------------------------------------------------------------------
1 | function onLoad()
2 | (self.getComponent("BoxCollider") or self.getComponent("MeshCollider")).set("enabled", false)
3 | Wait.condition(
4 | function()
5 | (self.getComponent("BoxCollider") or self.getComponent("MeshCollider")).set("enabled", false)
6 | end,
7 | function()
8 | return not (self.loading_custom)
9 | end
10 | )
11 | end
12 | function onUpdate()
13 | if (parent ~= nil) then
14 | if (not parent.resting) then
15 | self.setPosition(parent.getPosition())
16 |
17 | local scale = parent.getScale()
18 | if scale.x <= 1 then -- minumum size for medium crea
19 | self.setScale({x = 1.70, y = 0.01, z = 1.70})
20 | end
21 | end
22 | else
23 | self.destruct()
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/player_manager/player-manager-area.min.lua:
--------------------------------------------------------------------------------
1 | function onLoad()(self.getComponent("BoxCollider")or self.getComponent("MeshCollider")).set("enabled",false)Wait.condition(function()(self.getComponent("BoxCollider")or self.getComponent("MeshCollider")).set("enabled",false)end,function()return not self.loading_custom end)end;function onUpdate()if parent~=nil then if not parent.resting then self.setPosition(parent.getPosition())local a=parent.getScale()if a.x<=1 then self.setScale({x=1.70,y=0.01,z=1.70})end end else self.destruct()end end
--------------------------------------------------------------------------------
/player_manager/player-manager.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
50 |
51 |
--------------------------------------------------------------------------------
/player_manager/readme.md:
--------------------------------------------------------------------------------
1 | This is a snippet, meaning that it must be put as a piece of code somewhere else. The variables within need to be changed accordingly for your own table. If you need a representation of how to implement it, just read the changelog that was introduced with this file and you should be able how I implemented it.
2 |
3 | Credits to https://game-icons.net for all the icons that can be found in /states/
4 |
--------------------------------------------------------------------------------
/player_manager/shapes/circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/shapes/circle.png
--------------------------------------------------------------------------------
/player_manager/shapes/cone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/shapes/cone.png
--------------------------------------------------------------------------------
/player_manager/shapes/cube.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Zavian/Tabletop-Simulator-Scripts/912056c197148f715400a8f7cf102ffc8d079090/player_manager/shapes/cube.png
--------------------------------------------------------------------------------
/player_manager/state-player-manager.min.lua:
--------------------------------------------------------------------------------
1 | local a=nil;local b=nil;function manage_state(c,d,e)if master~=""then a=getObjectFromGUID(master)end;if c.color=="Black"then self.UI.setAttribute(e,"active","false")else self.UI.setAttribute(e,"active","false")a.call("manage_condition",{c=e})end end;function onCollisionEnter(f)if master~=""then a=getObjectFromGUID(master)end;if a~=nil then local g=f.collision_object;if isCondition(g.getName():gsub(" ","_"))then self.UI.setAttribute(string.lower(g.getName()),"active","true")g.destruct()elseif g.getName()=="Clear Area"then removeArea()elseif isAreaObject(g.getName())then makeJoined(g)end end end;function isCondition(h)h=string.lower(h)local i={"blinded","charmed","concentration","deafened","frightened","grappled","incapacitated","invisible","on_fire","paralyzed","petrified","poisoned","restrained","stunned"}for j=1,#i do if i[j]==h then return true end end;return false end;function makeJoined(g)removeArea()g.jointTo(self,{type="Fixed",collision=false})g.setVar("parent",self)g.setLuaScript('function onLoad()(self.getComponent("BoxCollider")or self.getComponent("MeshCollider")).set("enabled",false)Wait.condition(function()(self.getComponent("BoxCollider")or self.getComponent("MeshCollider")).set("enabled",false)end,function()return not self.loading_custom end)end;function onUpdate()if parent~=nil then if not parent.resting then self.setPosition(parent.getPosition())local a=parent.getScale()if a.x<=1 then self.setScale({x=1.70,y=0.01,z=1.70})end end else self.destruct()end end')g.getComponent("MeshRenderer").set("receiveShadows",false)g.mass=0;g.bounciness=0;g.drag=0;g.use_snap_points=false;g.use_grid=false;g.use_gravity=false;g.auto_raise=false;g.sticky=false;g.interactable=true;Wait.time(function()local k=g.getScale()g.setScale({x=k.x,y=0.01,z=k.z})g.setRotationSmooth({x=0,y=g.getRotation().y,z=0},false,true)b=g end,0.5)end;function removeArea()if b then b.destruct()b=nil end end;function isAreaObject(l)local m={"10'r","15'r","20'r","30'r","40'r","10'cone","15'cone","30'cone","60'cone","10'c","15'c","20'c","30'c","40'c"}for j=1,#m do if l==m[j]then return true end end;return false end
--------------------------------------------------------------------------------
/potion maker/potion maker.lua:
--------------------------------------------------------------------------------
1 | function mysplit(inputstr, sep)
2 | if sep == nil then
3 | sep = "%s"
4 | end
5 | local t = {}
6 | i = 1
7 | for str in string.gmatch(inputstr, "([^" .. sep .. "]+)") do
8 | t[i] = str
9 | i = i + 1
10 | end
11 | return t
12 | end
13 |
14 | --Runs when the scripted button inside the button is clicked
15 | function buttonPress()
16 | if lockout == false then
17 | --Call on any other function here. For example:
18 | --Global.call("Function Name", {table of parameters if needed})
19 | --You could also add your own scrting here. For example:
20 | --print("The button was pressed. Hoozah.")
21 |
22 | local text = self.UI.getAttribute("text", "value")
23 | local desc = self.getDescription()
24 |
25 | local data = JSON.decode(text)
26 |
27 | local obj = getObjectFromGUID(desc)
28 |
29 | obj.setName(data.title .. data.description)
30 | obj.setDescription(data.lore)
31 | obj.highlightOn(Color.Green, 1)
32 |
33 | obj.setColorTint(hexToRgb(data.color))
34 |
35 | self.AssetBundle.playTriggerEffect(0) --triggers animation/sound
36 | lockout = true --locks out the button
37 | startLockoutTimer() --Starts up a timer to remove lockout
38 | end
39 | end
40 |
41 | function colorTranslate(color)
42 | --[[
43 | arr["Green"] = "u";
44 | arr["Navy"] = "r";
45 | arr["BlueViolet"] = "e";
46 | arr["#c46709"] = "l";
47 | --]]
48 | local r = ""
49 | if color == "u" then
50 | r = "Green"
51 | elseif color == "r" then
52 | r = "Blue"
53 | elseif color == "e" then
54 | r = "Purple"
55 | elseif color == "l" then
56 | r = {r = 0.768627, g = 0.403922, b = 0.035294}
57 | else
58 | r = "White"
59 | end
60 |
61 | return r
62 | end
63 |
64 | --Runs on load, creates button and makes sure the lockout is off
65 | function onload()
66 | self.createButton(
67 | {
68 | label = "Big Red Button\n\nBy: MrStump",
69 | click_function = "buttonPress",
70 | function_owner = self,
71 | position = {0, 0.25, 0},
72 | height = 1400,
73 | width = 1400
74 | }
75 | )
76 | lockout = false
77 |
78 | self.UI.setAttribute("text", "onValueChanged", self.getGUID() .. "/UIUpdateValue(value)")
79 | end
80 |
81 | function onCollisionEnter(info)
82 | local guid = info.collision_object.guid
83 | if info.collision_object.interactable then
84 | self.setDescription(guid)
85 | info.collision_object.highlightOn(Color.Yellow, 1)
86 | else
87 | self.setDescription("")
88 | end
89 | end
90 |
91 | function UIUpdateValue(player, text, id)
92 | self.UI.setAttribute("text", "value", text)
93 | end
94 |
95 | --Starts a timer that, when it ends, will unlock the button
96 | function startLockoutTimer()
97 | Timer.create({identifier = self.getGUID(), function_name = "unlockLockout", delay = 0.5})
98 | end
99 |
100 | --Unlocks button
101 | function unlockLockout()
102 | lockout = false
103 | end
104 |
105 | --Ends the timer if the object is destroyed before the timer ends, to prevent an error
106 | function onDestroy()
107 | Timer.destroy(self.getGUID())
108 | end
109 |
110 | function hexToRgb(hex)
111 | hex = hex:gsub("#", "")
112 | if #hex < 8 then
113 | hex = hex .. "ff"
114 | end
115 | return color(
116 | tonumber("0x" .. hex:sub(1, 2), 16) / 255,
117 | tonumber("0x" .. hex:sub(3, 4), 16) / 255,
118 | tonumber("0x" .. hex:sub(5, 6), 16) / 255,
119 | tonumber("0x" .. hex:sub(7, 8), 16) / 255
120 | )
121 | end
122 |
--------------------------------------------------------------------------------
/potion maker/potion maker.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/reset-characters.lua:
--------------------------------------------------------------------------------
1 | --Runs when the scripted button inside the button is clicked
2 |
3 | local original_pos = {}
4 | local original_rot = {}
5 | local first = true
6 |
7 | function buttonPress()
8 | if lockout == false then
9 | local notes = self.getGMNotes()
10 | local j = JSON.decode(notes)
11 |
12 | local tokens = nil
13 | local coin = nil
14 | local point = nil
15 | local coinPos = nil
16 |
17 | if j.players then
18 | tokens = j.players
19 | point = {
20 | x = j.startingPoint.x and j.startingPoint.x or self.getPosition().x,
21 | y = j.startingPoint.y and j.startingPoint.y or 5,
22 | z = j.startingPoint.z and j.startingPoint.z or self.getPosition().z
23 | }
24 | end
25 | if j.coin then
26 | coin = j.coin
27 | coinPos = {
28 | x = j.coinPos.x and j.coinPos.x or self.getPosition().x,
29 | y = j.coinPos.y and j.coinPos.y or 5,
30 | z = j.coinPos.z and j.coinPos.z or self.getPosition().z
31 | }
32 | end
33 | local spacing = j.spacing and j.spacing or 1.7
34 |
35 | if first then
36 | original_pos = {}
37 | original_rot = {}
38 |
39 | if tokens then
40 | for i = 1, #tokens do
41 | --local token_info = tokens[i]
42 | local obj = getObjectFromGUID(tokens[i])
43 | original_pos[tokens[i]] = obj.getPosition()
44 | original_pos[tokens[i]][2] = original_pos[tokens[i]][2] + 2
45 |
46 | original_rot[tokens[i]] = obj.getRotation()
47 |
48 | local pos = point
49 | local rotation = {0, 90.00, 0}
50 |
51 | obj.setRotationSmooth(rotation, false, true)
52 | obj.setPositionSmooth(pos, false, false)
53 |
54 | point.z = point.z - spacing
55 | if i % 3 == 0 then
56 | point.z = j.startingPoint.z and j.startingPoint.z or self.getPosition().z
57 | point.x = point.x + spacing
58 | end
59 | end
60 |
61 | if coin then
62 | local obj = getObjectFromGUID(coin)
63 | obj.setRotationSmooth({0, 90.0, 0}, false, true)
64 | obj.setPositionSmooth(coinPos, false, false)
65 | end
66 | else
67 | log("I do need some tokens from the resetter thinking")
68 | end
69 | first = false
70 | else
71 | first = true
72 | for i = 1, #tokens do
73 | local obj = getObjectFromGUID(tokens[i])
74 | obj.setPositionSmooth(original_pos[tokens[i]], false, false)
75 | obj.setRotationSmooth(original_rot[tokens[i]], false, true)
76 | end
77 | end
78 | end
79 | end
80 |
81 | --Runs on load, creates button and makes sure the lockout is off
82 | function onload()
83 | self.createButton(
84 | {
85 | label = "Big Red Button\n\nBy: MrStump",
86 | click_function = "buttonPress",
87 | function_owner = self,
88 | position = {0, 0.25, 0},
89 | height = 1400,
90 | width = 1400
91 | }
92 | )
93 | lockout = false
94 | end
95 |
96 | --Starts a timer that, when it ends, will unlock the button
97 | function startLockoutTimer()
98 | Timer.create({identifier = self.getGUID(), function_name = "unlockLockout", delay = 0.5})
99 | end
100 |
101 | --Unlocks button
102 | function unlockLockout()
103 | lockout = false
104 | end
105 |
106 | --Ends the timer if the object is destroyed before the timer ends, to prevent an error
107 | function onDestroy()
108 | Timer.destroy(self.getGUID())
109 | end
110 |
--------------------------------------------------------------------------------
/table-updater.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------