653 lines
20 KiB
Plaintext
653 lines
20 KiB
Plaintext
--[[ Character Sheet Template by: MrStump
|
|
|
|
You can set up your own character sheet if you follow these steps.
|
|
|
|
Step 1) Change the character sheet image
|
|
-Right click on the character sheet, click Custom
|
|
-Replace the image URL with one for your character sheet
|
|
-Click import, make sure your sheet loads
|
|
-SAVE THE GAME (the table setup)
|
|
-LOAD FROM THAT SAVE YOU JUST MADE
|
|
|
|
Step 2) Edit script to fit your character sheet
|
|
-Below you will see some general options, and then the big data table
|
|
-The data table is what determines how many of which buttons are made
|
|
-Checkboxes
|
|
-Counters
|
|
-Textboxes
|
|
-By default, there are 3 of each. You can add more or remove entries
|
|
-If you intend to add/remove, be sure only to add/remove ENTRIES
|
|
-This is what an entry looks like:
|
|
{
|
|
pos = {-0.977,0.1,-0.589},
|
|
size = 800,
|
|
state = false
|
|
},
|
|
-Deleting the whole thing would remove that specific item on the sheet
|
|
-Copy and pasting it after another entry would create another
|
|
-Each entry type has unique data points (pos, size, state, etc)
|
|
-Do not try to add in your own data points or remove them individually
|
|
-There is a summary of what each point does at the top of its category
|
|
|
|
Step 3) Save and check script changes
|
|
-Hit Save & Apply in the script window to save your code
|
|
-You can edit your code as needed and Save+Apply as often as needed
|
|
-When you are finished, make disableSave = false below then Save+apply
|
|
-This enables saving, so your sheet will remember whats on it.
|
|
|
|
Bonus) Finding/Editing Positions for elements
|
|
I have included a tool to get positions for buttons in {x,y,z} form
|
|
Place it where you want the center of your element to be
|
|
Then copy the table from the notes (lower right of screen)
|
|
You can highlight it and CTRL+C
|
|
Paste it into the data table where needed (pos=)
|
|
If you want to manually tweek the values:
|
|
{0,0,0} is the center of the character sheet
|
|
{1,0,0} is right, {-1,0,0} is left
|
|
{0,0,-1} is up, {0,0,1} is down
|
|
0.1 for Y is the height off of the page.
|
|
If it was 0, it would be down inside the model of the sheet
|
|
|
|
Begin editing below: ]]
|
|
|
|
--Set this to true while editing and false when you have finished
|
|
disableSave = false
|
|
--Remember to set this to false once you are done making changes
|
|
--Then, after you save & apply it, save your game too
|
|
|
|
--Color information for button text (r,g,b, values of 0-1)
|
|
buttonFontColor = {0,0,0}
|
|
--Color information for button background
|
|
buttonColor = {1,1,1}
|
|
--Change scale of button (Avoid changing if possible)
|
|
buttonScale = {0.1,0.1,0.1}
|
|
|
|
--This is the button placement information
|
|
defaultButtonData = {
|
|
--Add checkboxes
|
|
checkbox = {
|
|
--[[
|
|
pos = the position (pasted from the helper tool)
|
|
size = height/width/font_size for checkbox
|
|
state = default starting value for checkbox (true=checked, false=not)
|
|
]]
|
|
--End of checkboxes
|
|
},
|
|
--Add counters that have a + and - button
|
|
counter = {
|
|
--[[
|
|
pos = the position (pasted from the helper tool)
|
|
size = height/width/font_size for counter
|
|
value = default starting value for counter
|
|
hideBG = if background of counter is hidden (true=hidden, false=not)
|
|
]]
|
|
--1st Player Experience
|
|
{
|
|
pos = {-1.00,0.1,-1.030},
|
|
size = 800,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--1st Player Physical Trauma
|
|
{
|
|
pos = {-1.270,0.1,-0.840},
|
|
size = 600,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--1st Player Mental Trauma
|
|
{
|
|
pos = {-0.920,0.1,-0.840},
|
|
size = 600,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--2nd Player Experience
|
|
{
|
|
pos = {-0.171,0.1,-1.025},
|
|
size = 800,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--2nd Player Physical Trauma
|
|
{
|
|
pos = {-0.401,0.1,-0.840},
|
|
size = 600,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--2nd Player Mental Trauma
|
|
{
|
|
pos = {-0.101,0.1,-0.840},
|
|
size = 600,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--3rd Player Experience
|
|
{
|
|
pos = {0.659,0.1,-1.010},
|
|
size = 800,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--3rd Player Physical Trauma
|
|
{
|
|
pos = {0.429,0.1,-0.840},
|
|
size = 600,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--3rd Player Mental Trauma
|
|
{
|
|
pos = {0.719,0.1,-0.840},
|
|
size = 600,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--4th Player Experience
|
|
{
|
|
pos = {1.507,0.1,-1.010},
|
|
size = 800,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--4th Player Physical Trauma
|
|
{
|
|
pos = {1.237,0.1,-0.840},
|
|
size = 600,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--4th Player Mental Trauma
|
|
{
|
|
pos = {1.517,0.1,-0.840},
|
|
size = 600,
|
|
value = 0,
|
|
hideBG = true
|
|
},
|
|
--End of counters
|
|
},
|
|
--Add editable text boxes
|
|
textbox = {
|
|
--[[
|
|
pos = the position (pasted from the helper tool)
|
|
rows = how many lines of text you want for this box
|
|
width = how wide the text box is
|
|
font_size = size of text. This and "rows" effect overall height
|
|
label = what is shown when there is no text. "" = nothing
|
|
value = text entered into box. "" = nothing
|
|
alignment = Number to indicate how you want text aligned
|
|
(1=Automatic, 2=Left, 3=Center, 4=Right, 5=Justified)
|
|
]]
|
|
--1st Player Name
|
|
{
|
|
pos = {-1.215,0.1,-1.330},
|
|
rows = 1,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--1st Player Investigator
|
|
{
|
|
pos = {-1.215,0.1,-1.175},
|
|
rows = 1,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--1st Player Story Assets/Weaknesses
|
|
{
|
|
pos = {-1.215,0.1,-0.478},
|
|
rows = 7,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--2nd Player Name
|
|
{
|
|
pos = {-0.386,0.1,-1.330},
|
|
rows = 1,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--2nd Player Investigator
|
|
{
|
|
pos = {-0.386,0.1,-1.175},
|
|
rows = 1,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--2nd Player Story Assets/Weaknesses
|
|
{
|
|
pos = {-0.386,0.1,-0.478},
|
|
rows = 7,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--3rd Player Name
|
|
{
|
|
pos = {0.444,0.1,-1.320},
|
|
rows = 1,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--3rd Player Investigator
|
|
{
|
|
pos = {0.444,0.1,-1.165},
|
|
rows = 1,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--3rd Player Story Assets/Weaknesses
|
|
{
|
|
pos = {0.444,0.1,-0.474},
|
|
rows = 7,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--4th Player Name
|
|
{
|
|
pos = {1.272,0.1,-1.310},
|
|
rows = 1,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--4th Player Investigator
|
|
{
|
|
pos = {1.272,0.1,-1.155},
|
|
rows = 1,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--4th Player Story Assets/Weaknesses
|
|
--pos = {1.222,0.1,-0.420},
|
|
{
|
|
pos = {1.272,0.1,-0.470},
|
|
rows = 7,
|
|
width = 3800,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--Campaign Notes 1
|
|
{
|
|
pos = {-0.930,0.1,0.990},
|
|
rows = 24,
|
|
width = 6200,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--Campaign Notes 2
|
|
{
|
|
pos = {0.620,0.1,0.357},
|
|
rows = 14,
|
|
width = 6200,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--Campaign Notes 3
|
|
{
|
|
pos = {0.620,0.1,1.357},
|
|
rows = 10,
|
|
width = 6200,
|
|
font_size = 300,
|
|
label = "Empty",
|
|
value = "",
|
|
alignment = 2
|
|
},
|
|
--End of textboxes
|
|
}
|
|
}
|
|
|
|
|
|
|
|
--Lua beyond this point, I recommend doing something more fun with your life
|
|
|
|
|
|
|
|
--Save function
|
|
local alreadySaving = false -- Copy this too!
|
|
function updateSave()
|
|
|
|
function string.replaceText(text, old, new)
|
|
local b,e = text:find(old,1,true)
|
|
if b==nil then
|
|
return text
|
|
else
|
|
return text:sub(1,b-1) .. new .. text:sub(e+1)
|
|
end
|
|
end
|
|
|
|
function wait(time)
|
|
local start = os.time()
|
|
repeat coroutine.yield(0) until os.time() > start + time
|
|
end
|
|
|
|
function deepcopy(orig)
|
|
local orig_type = type(orig)
|
|
local copy
|
|
if orig_type == 'table' then
|
|
copy = {}
|
|
for orig_key, orig_value in next, orig, nil do
|
|
copy[deepcopy(orig_key)] = deepcopy(orig_value)
|
|
end
|
|
setmetatable(copy, deepcopy(getmetatable(orig)))
|
|
else -- number, string, boolean, etc
|
|
copy = orig
|
|
end
|
|
return copy
|
|
end
|
|
|
|
function startSaving()
|
|
while alreadySaving do
|
|
wait(0.01)
|
|
end
|
|
alreadySaving = true
|
|
local ref_buttonData = deepcopy(ref_buttonData)
|
|
local input_values = {}
|
|
local checkbox_values = {}
|
|
local counter_values = {}
|
|
|
|
local GUID = self.getGUID()
|
|
local counter = 1
|
|
for _, val in ipairs(ref_buttonData.textbox) do
|
|
if val.value != nil then
|
|
input_values[counter] = val.value
|
|
val.value = "u"..GUID..":iv:"..counter.."u"
|
|
counter = counter + 1
|
|
end
|
|
if val.label != nil then
|
|
input_values[counter] = val.label
|
|
val.label = "u"..GUID..":iv:"..counter.."u"
|
|
counter = counter + 1
|
|
end
|
|
end
|
|
|
|
local counter = 1
|
|
for _, val in ipairs(ref_buttonData.checkbox) do
|
|
if val.value != nil then
|
|
checkbox_values[counter] = val.value
|
|
val.value = "u"..GUID..":bv:"..counter.."u"
|
|
counter = counter + 1
|
|
end
|
|
end
|
|
|
|
local counter = 1
|
|
for _, val in ipairs(ref_buttonData.counter) do
|
|
if val.value != nil then
|
|
counter_values[counter] = val.value
|
|
val.value = "u"..GUID..":cv:"..counter.."u"
|
|
counter = counter + 1
|
|
if val.counters != nil then
|
|
for _, val2 in ipairs(val.counters) do
|
|
if val2.value != nil then
|
|
counter_values[counter] = val2.value
|
|
val2.value = "u"..GUID..":cv:"..counter.."u"
|
|
counter = counter + 1
|
|
end
|
|
if val2.change_value != nil then
|
|
counter_values[counter] = val2.change_value
|
|
val2.change_value = "u"..GUID..":cv:"..counter.."u"
|
|
counter = counter + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
|
|
saved_data = JSON.encode(ref_buttonData)
|
|
|
|
local counter = 1
|
|
for _, val in ipairs(ref_buttonData.textbox) do
|
|
if val.value != nil then
|
|
saved_data = saved_data:replaceText("u"..GUID..":iv:"..counter.."u", string.gsub(input_values[counter], "[\\\"']", "\\%1"))
|
|
val.value = input_values[counter]
|
|
counter = counter + 1
|
|
end
|
|
if val.label != nil then
|
|
saved_data = saved_data:replaceText("u"..GUID..":iv:"..counter.."u", string.gsub(input_values[counter], "[\\\"']", "\\%1"))
|
|
val.label = input_values[counter]
|
|
counter = counter + 1
|
|
end
|
|
end
|
|
|
|
local counter = 1
|
|
for _, val in ipairs(ref_buttonData.checkbox) do
|
|
if val.value != nil then
|
|
val.value = checkbox_values[counter]
|
|
saved_data = saved_data:replaceText("u"..GUID..":bv:"..counter.."u", string.gsub(checkbox_values[counter], "[\\\"']", "\\%1"))
|
|
counter = counter + 1
|
|
end
|
|
end
|
|
|
|
local counter = 1
|
|
for _, val in ipairs(ref_buttonData.counter) do
|
|
if val.value != nil then
|
|
val.value = counter_values[counter]
|
|
saved_data = saved_data:replaceText("u"..GUID..":cv:"..counter.."u", string.gsub(counter_values[counter], "[\\\"']", "\\%1"))
|
|
counter = counter + 1
|
|
|
|
if val.counters != nil then
|
|
for _, val2 in ipairs(val.counters) do
|
|
if val2.value != nil then
|
|
val2.value = counter_values[counter]
|
|
saved_data = saved_data:replaceText("u"..GUID..":cv:"..counter.."u", string.gsub(counter_values[counter], "[\\\"']", "\\%1"))
|
|
counter = counter + 1
|
|
end
|
|
if val2.change_value != nil then
|
|
val2.change_value = counter_values[counter]
|
|
saved_data = saved_data:replaceText("u"..GUID..":cv:"..counter.."u", string.gsub(counter_values[counter], "[\\\"']", "\\%1"))
|
|
counter = counter + 1
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
end
|
|
if disableSave==true then saved_data="" end
|
|
self.script_state = saved_data
|
|
|
|
alreadySaving = false
|
|
return 1
|
|
end
|
|
startLuaCoroutine(self, "startSaving")
|
|
end
|
|
|
|
--Startup procedure
|
|
function onload(saved_data)
|
|
if disableSave==true then saved_data="" end
|
|
if saved_data ~= "" then
|
|
local loaded_data = JSON.decode(saved_data)
|
|
ref_buttonData = loaded_data
|
|
else
|
|
ref_buttonData = defaultButtonData
|
|
end
|
|
|
|
spawnedButtonCount = 0
|
|
createCheckbox()
|
|
createCounter()
|
|
createTextbox()
|
|
end
|
|
|
|
|
|
|
|
--Click functions for buttons
|
|
|
|
|
|
|
|
--Checks or unchecks the given box
|
|
function click_checkbox(tableIndex, buttonIndex)
|
|
if ref_buttonData.checkbox[tableIndex].state == true then
|
|
ref_buttonData.checkbox[tableIndex].state = false
|
|
self.editButton({index=buttonIndex, label=""})
|
|
else
|
|
ref_buttonData.checkbox[tableIndex].state = true
|
|
self.editButton({index=buttonIndex, label=string.char(10008)})
|
|
end
|
|
updateSave()
|
|
end
|
|
|
|
--Applies value to given counter display
|
|
function click_counter(tableIndex, buttonIndex, amount)
|
|
ref_buttonData.counter[tableIndex].value = ref_buttonData.counter[tableIndex].value + amount
|
|
self.editButton({index=buttonIndex, label=ref_buttonData.counter[tableIndex].value})
|
|
updateSave()
|
|
end
|
|
|
|
--Updates saved value for given text box
|
|
function click_textbox(i, value, selected)
|
|
if selected == false then
|
|
ref_buttonData.textbox[i].value = value
|
|
updateSave()
|
|
end
|
|
end
|
|
|
|
--Dud function for if you have a background on a counter
|
|
function click_none() end
|
|
|
|
|
|
|
|
--Button creation
|
|
|
|
|
|
|
|
--Makes checkboxes
|
|
function createCheckbox()
|
|
for i, data in ipairs(ref_buttonData.checkbox) do
|
|
--Sets up reference function
|
|
local buttonNumber = spawnedButtonCount
|
|
local funcName = "checkbox"..i
|
|
local func = function() click_checkbox(i, buttonNumber) end
|
|
self.setVar(funcName, func)
|
|
--Sets up label
|
|
local label = ""
|
|
if data.state==true then label=string.char(10008) end
|
|
--Creates button and counts it
|
|
self.createButton({
|
|
label=label, click_function=funcName, function_owner=self,
|
|
position=data.pos, height=data.size, width=data.size,
|
|
font_size=data.size, scale=buttonScale,
|
|
color=buttonColor, font_color=buttonFontColor
|
|
})
|
|
spawnedButtonCount = spawnedButtonCount + 1
|
|
end
|
|
end
|
|
|
|
--Makes counters
|
|
function createCounter()
|
|
for i, data in ipairs(ref_buttonData.counter) do
|
|
--Sets up display
|
|
local displayNumber = spawnedButtonCount
|
|
--Sets up label
|
|
local label = data.value
|
|
--Sets height/width for display
|
|
local size = data.size
|
|
if data.hideBG == true then size = 0 end
|
|
--Creates button and counts it
|
|
self.createButton({
|
|
label=label, click_function="click_none", function_owner=self,
|
|
position=data.pos, height=size, width=size,
|
|
font_size=data.size, scale=buttonScale,
|
|
color=buttonColor, font_color=buttonFontColor
|
|
})
|
|
spawnedButtonCount = spawnedButtonCount + 1
|
|
|
|
--Sets up add 1
|
|
local funcName = "counterAdd"..i
|
|
local func = function() click_counter(i, displayNumber, 1) end
|
|
self.setVar(funcName, func)
|
|
--Sets up label
|
|
local label = "+"
|
|
--Sets up position
|
|
local offsetDistance = (data.size/2 + data.size/4) * (buttonScale[1] * 0.002)
|
|
local pos = {data.pos[1] + offsetDistance, data.pos[2], data.pos[3]}
|
|
--Sets up size
|
|
local size = data.size / 2
|
|
--Creates button and counts it
|
|
self.createButton({
|
|
label=label, click_function=funcName, function_owner=self,
|
|
position=pos, height=size, width=size,
|
|
font_size=size, scale=buttonScale,
|
|
color=buttonColor, font_color=buttonFontColor
|
|
})
|
|
spawnedButtonCount = spawnedButtonCount + 1
|
|
|
|
--Sets up subtract 1
|
|
local funcName = "counterSub"..i
|
|
local func = function() click_counter(i, displayNumber, -1) end
|
|
self.setVar(funcName, func)
|
|
--Sets up label
|
|
local label = "-"
|
|
--Set up position
|
|
local pos = {data.pos[1] - offsetDistance, data.pos[2], data.pos[3]}
|
|
--Creates button and counts it
|
|
self.createButton({
|
|
label=label, click_function=funcName, function_owner=self,
|
|
position=pos, height=size, width=size,
|
|
font_size=size, scale=buttonScale,
|
|
color=buttonColor, font_color=buttonFontColor
|
|
})
|
|
spawnedButtonCount = spawnedButtonCount + 1
|
|
end
|
|
end
|
|
|
|
function createTextbox()
|
|
for i, data in ipairs(ref_buttonData.textbox) do
|
|
--Sets up reference function
|
|
local funcName = "textbox"..i
|
|
local func = function(_,_,val,sel) click_textbox(i,val,sel) end
|
|
self.setVar(funcName, func)
|
|
|
|
self.createInput({
|
|
input_function = funcName,
|
|
function_owner = self,
|
|
label = data.label,
|
|
alignment = data.alignment,
|
|
position = data.pos,
|
|
scale = buttonScale,
|
|
width = data.width,
|
|
height = (data.font_size*data.rows)+24,
|
|
font_size = data.font_size,
|
|
color = buttonColor,
|
|
font_color = buttonFontColor,
|
|
value = data.value,
|
|
})
|
|
end
|
|
end
|