2023-04-22 16:56:01 -04:00
|
|
|
-- Bundled by luabundle {"version":"1.6.0"}
|
|
|
|
local __bundle_require, __bundle_loaded, __bundle_register, __bundle_modules = (function(superRequire)
|
|
|
|
local loadingPlaceholder = {[{}] = true}
|
|
|
|
|
|
|
|
local register
|
|
|
|
local modules = {}
|
|
|
|
|
|
|
|
local require
|
|
|
|
local loaded = {}
|
|
|
|
|
|
|
|
register = function(name, body)
|
|
|
|
if not modules[name] then
|
|
|
|
modules[name] = body
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
require = function(name)
|
|
|
|
local loadedModule = loaded[name]
|
|
|
|
|
|
|
|
if loadedModule then
|
|
|
|
if loadedModule == loadingPlaceholder then
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if not modules[name] then
|
|
|
|
if not superRequire then
|
|
|
|
local identifier = type(name) == 'string' and '\"' .. name .. '\"' or tostring(name)
|
|
|
|
error('Tried to require ' .. identifier .. ', but no such module has been registered')
|
|
|
|
else
|
|
|
|
return superRequire(name)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
loaded[name] = loadingPlaceholder
|
|
|
|
loadedModule = modules[name](require, loaded, register, modules)
|
|
|
|
loaded[name] = loadedModule
|
|
|
|
end
|
|
|
|
|
|
|
|
return loadedModule
|
|
|
|
end
|
|
|
|
|
|
|
|
return require, loaded, register, modules
|
|
|
|
end)(nil)
|
|
|
|
__bundle_register("__root", function(require, _LOADED, __bundle_register, __bundle_modules)
|
|
|
|
require("playercards/customizable/SummonedServitorUpgradeSheet")
|
|
|
|
end)
|
|
|
|
__bundle_register("playercards/customizable/SummonedServitorUpgradeSheet", function(require, _LOADED, __bundle_register, __bundle_modules)
|
2022-10-19 19:07:47 -04:00
|
|
|
-- Customizable Cards: Summoned Servitor
|
|
|
|
|
|
|
|
-- Color information for buttons
|
|
|
|
boxSize = 35
|
|
|
|
|
|
|
|
-- static values
|
2023-08-27 21:09:46 -04:00
|
|
|
xInitial = -0.935
|
|
|
|
xOffset = 0.068
|
2022-10-19 19:07:47 -04:00
|
|
|
|
|
|
|
-- z-values (lines on the sheet)
|
2023-08-27 21:09:46 -04:00
|
|
|
posZ = {
|
|
|
|
-0.92,
|
|
|
|
-0.625,
|
|
|
|
-0.33,
|
|
|
|
0.055,
|
|
|
|
0.26,
|
|
|
|
0.56,
|
|
|
|
0.765,
|
|
|
|
1.06
|
2022-10-19 19:07:47 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
-- box setup (amount of boxes per line and amount of marked boxes in that line)
|
2023-08-27 21:09:46 -04:00
|
|
|
existingBoxes = { 1, 1, 1, 1, 1, 2, 3, 5 }
|
|
|
|
inputBoxes = {}
|
2022-10-19 19:07:47 -04:00
|
|
|
|
2023-04-22 16:56:01 -04:00
|
|
|
-- Locations of the slot selectors
|
2023-08-27 21:09:46 -04:00
|
|
|
SLOT_ICON_POSITIONS = {
|
|
|
|
arcane = { x = 0.160, z = 0.65 },
|
|
|
|
ally = { x = -0.073, z = 0.65 }
|
2023-04-22 16:56:01 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
-- These match with ArkhamDB's way of storing the data in the dropdown menu
|
2023-08-27 21:09:46 -04:00
|
|
|
SLOT_INDICES = { arcane = "1", ally = "0", none = "" }
|
|
|
|
--selectedSlot = SLOT_INDICES.none
|
|
|
|
|
|
|
|
customizations = {
|
|
|
|
[1] = {
|
|
|
|
checkboxes = {
|
|
|
|
posZ = -0.92,
|
|
|
|
count = 1,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[2] = {
|
|
|
|
checkboxes = {
|
|
|
|
posZ = -0.625,
|
|
|
|
count = 1,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[3] = {
|
|
|
|
checkboxes = {
|
|
|
|
posZ = -0.33,
|
|
|
|
count = 1,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[4] = {
|
|
|
|
checkboxes = {
|
|
|
|
posZ = 0.055,
|
|
|
|
count = 1,
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[5] = {
|
|
|
|
checkboxes = {
|
|
|
|
posZ = 0.26,
|
|
|
|
count = 1,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[6] = {
|
|
|
|
checkboxes = {
|
|
|
|
posZ = 0.56,
|
|
|
|
count = 2,
|
|
|
|
}
|
|
|
|
-- Row 6 includes the selection of Arcane/Ally slot, presented with buttons but stored
|
|
|
|
-- as a text field
|
|
|
|
},
|
|
|
|
[7] = {
|
|
|
|
checkboxes = {
|
|
|
|
posZ = 0.765,
|
|
|
|
count = 3,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
[8] = {
|
|
|
|
checkboxes = {
|
|
|
|
posZ = 1.06,
|
|
|
|
count = 5,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
2023-04-22 16:56:01 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
require("playercards/customizable/UpgradeSheetLibrary")
|
|
|
|
end)
|
|
|
|
__bundle_register("playercards/customizable/UpgradeSheetLibrary", function(require, _LOADED, __bundle_register, __bundle_modules)
|
|
|
|
-- Common code for handling customizable card upgrade sheets
|
|
|
|
-- Define UI elements in the base card file, then include this
|
|
|
|
-- UI element definition is an array of tables, each with this structure. A row may include
|
|
|
|
-- checkboxes (number defined by count), a text field, both, or neither (if the row has custom
|
|
|
|
-- handling, as Living Ink does)
|
|
|
|
-- {
|
|
|
|
-- checkboxes = {
|
|
|
|
-- posZ = -0.71,
|
|
|
|
-- count = 1,
|
|
|
|
-- },
|
|
|
|
-- textField = {
|
|
|
|
-- position = { 0.005, 0.25, -0.58 },
|
|
|
|
-- width = 875
|
|
|
|
-- }
|
|
|
|
-- }
|
|
|
|
-- Fields should also be defined for xInitial (left edge of the checkboxes) and xOffset (amount to
|
|
|
|
-- shift X from one box to the next) as well as boxSize (checkboxes) and inputFontSize.
|
|
|
|
--
|
|
|
|
-- selectedUpgrades holds the state of checkboxes and text input, each element being:
|
|
|
|
-- selectedUpgrades[row] = { xp = #, text = "" }
|
|
|
|
|
|
|
|
local playmatApi = require("playermat/PlaymatApi")
|
|
|
|
|
|
|
|
-- Y position for UI elements. Visibility of checkboxes moves the checkbox inside the card object
|
|
|
|
-- when not selected.
|
|
|
|
local Y_VISIBLE = 0.25
|
|
|
|
local Y_INVISIBLE = -0.5
|
|
|
|
|
|
|
|
-- Used for Summoned Servitor and Living Ink
|
|
|
|
local VECTOR_COLOR = {
|
|
|
|
unselected = { 0.5, 0.5, 0.5, 0.75 },
|
|
|
|
mystic = { 0.597, 0.195, 0.796 }
|
|
|
|
}
|
2023-04-22 16:56:01 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
-- These match with ArkhamDB's way of storing the data in the dropdown menu
|
|
|
|
local SUMMONED_SERVITOR_SLOT_INDICES = { arcane = "1", ally = "0", none = "" }
|
|
|
|
|
|
|
|
local rowCheckboxFirstIndex = { }
|
|
|
|
local rowInputIndex = { }
|
|
|
|
local selectedUpgrades = { }
|
2022-10-19 19:07:47 -04:00
|
|
|
|
|
|
|
-- save state when going into bags / decks
|
|
|
|
function onDestroy() self.script_state = onSave() end
|
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function onSave()
|
|
|
|
return JSON.encode({
|
|
|
|
selections = selectedUpgrades
|
|
|
|
})
|
|
|
|
end
|
2022-10-19 19:07:47 -04:00
|
|
|
|
|
|
|
-- Startup procedure
|
2023-08-27 21:09:46 -04:00
|
|
|
function onLoad(savedData)
|
|
|
|
if savedData ~= "" then
|
|
|
|
local loadedData = JSON.decode(savedData)
|
|
|
|
if loadedData.selections ~= nil then
|
|
|
|
selectedUpgrades = loadedData.selections
|
2022-10-19 19:07:47 -04:00
|
|
|
end
|
2023-08-27 21:09:46 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
selfId = getSelfId()
|
2022-10-19 19:07:47 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
maybeLoadLivingInkSkills()
|
|
|
|
createUi()
|
|
|
|
maybeUpdateLivingInkSkillDisplay()
|
|
|
|
maybeUpdateServitorSlotDisplay()
|
2022-10-19 19:07:47 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
self.addContextMenuItem("Clear Selections", function() resetSelections() end)
|
|
|
|
self.addContextMenuItem("Scale: 1x", function() self.setScale({ 1, 1, 1 }) end)
|
|
|
|
self.addContextMenuItem("Scale: 2x", function() self.setScale({ 2, 1, 2 }) end)
|
|
|
|
self.addContextMenuItem("Scale: 3x", function() self.setScale({ 3, 1, 3 }) end)
|
2022-10-19 19:07:47 -04:00
|
|
|
end
|
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
-- Grabs the ID from the metadata for special functions (Living Ink, Summoned Servitor)
|
|
|
|
function getSelfId()
|
|
|
|
local metadata = JSON.decode(self.getGMNotes())
|
|
|
|
return metadata.id
|
2022-10-19 19:07:47 -04:00
|
|
|
end
|
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function isUpgradeActive(row)
|
|
|
|
return customizations[row] ~= nil
|
|
|
|
and customizations[row].checkboxes ~= nil
|
|
|
|
and customizations[row].checkboxes.count ~= nil
|
|
|
|
and customizations[row].checkboxes.count > 0
|
|
|
|
and selectedUpgrades[row] ~= nil
|
|
|
|
and selectedUpgrades[row].xp ~= nil
|
|
|
|
and selectedUpgrades[row].xp >= customizations[row].checkboxes.count
|
|
|
|
end
|
|
|
|
|
|
|
|
function resetSelections()
|
|
|
|
selectedUpgrades = { }
|
|
|
|
updateDisplay()
|
|
|
|
end
|
2022-10-19 19:07:47 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function createUi()
|
|
|
|
if customizations == nil then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
for i = 1, #customizations do
|
|
|
|
if customizations[i].checkboxes ~= nil then
|
|
|
|
createRowCheckboxes(i)
|
2022-10-19 19:07:47 -04:00
|
|
|
end
|
2023-08-27 21:09:46 -04:00
|
|
|
if customizations[i].textField ~= nil then
|
|
|
|
createRowTextField(i)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
maybeMakeLivingInkSkillSelectionButtons()
|
|
|
|
maybeMakeServitorSlotSelectionButtons()
|
|
|
|
updateDisplay()
|
2022-10-19 19:07:47 -04:00
|
|
|
end
|
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function createRowCheckboxes(rowIndex)
|
|
|
|
local checkboxes = customizations[rowIndex].checkboxes
|
|
|
|
rowCheckboxFirstIndex[rowIndex] = 0
|
|
|
|
local previousButtons = self.getButtons()
|
|
|
|
if previousButtons ~= nil then
|
|
|
|
rowCheckboxFirstIndex[rowIndex] = #previousButtons
|
|
|
|
end
|
|
|
|
for col = 1, checkboxes.count do
|
|
|
|
local funcName = "checkboxRow" .. rowIndex .. "Col" .. col
|
|
|
|
local func = function() clickCheckbox(rowIndex, col) end
|
|
|
|
self.setVar(funcName, func)
|
|
|
|
local checkboxPos = getCheckboxPosition(rowIndex, col)
|
|
|
|
|
|
|
|
self.createButton({
|
|
|
|
click_function = funcName,
|
|
|
|
function_owner = self,
|
|
|
|
position = checkboxPos,
|
|
|
|
height = boxSize * 10,
|
|
|
|
width = boxSize * 10,
|
|
|
|
font_size = 1000,
|
|
|
|
scale = { 0.1, 0.1, 0.1 },
|
|
|
|
color = { 0, 0, 0 },
|
|
|
|
font_color = { 0, 0, 0 }
|
|
|
|
})
|
|
|
|
end
|
|
|
|
end
|
2022-10-19 19:07:47 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function getCheckboxPosition(row, col)
|
|
|
|
return {
|
|
|
|
x = xInitial + col * xOffset,
|
|
|
|
y = Y_VISIBLE,
|
|
|
|
z = customizations[row].checkboxes.posZ
|
|
|
|
}
|
|
|
|
end
|
2022-10-19 19:07:47 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function createRowTextField(rowIndex)
|
|
|
|
local textField = customizations[rowIndex].textField
|
|
|
|
|
|
|
|
rowInputIndex[rowIndex] = 0
|
|
|
|
local previousInputs = self.getInputs()
|
|
|
|
if previousInputs ~= nil then
|
|
|
|
rowInputIndex[rowIndex] = #previousInputs
|
|
|
|
end
|
|
|
|
local funcName = "textbox" .. rowIndex
|
|
|
|
local func = function(_, _, val, sel) clickTextbox(rowIndex, val, sel) end
|
|
|
|
self.setVar(funcName, func)
|
|
|
|
|
|
|
|
self.createInput({
|
|
|
|
input_function = funcName,
|
|
|
|
function_owner = self,
|
|
|
|
label = "Click to type",
|
|
|
|
alignment = 2,
|
|
|
|
position = textField.position,
|
|
|
|
scale = { 0.1, 0.1, 0.1 },
|
|
|
|
width = textField.width * 10,
|
|
|
|
height = inputFontsize * 10 + 75,
|
|
|
|
font_size = inputFontsize * 10.5,
|
|
|
|
color = "White",
|
|
|
|
value = ""
|
|
|
|
})
|
|
|
|
end
|
2022-10-19 19:07:47 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function updateDisplay()
|
|
|
|
for i = 1, #customizations do
|
|
|
|
updateRowDisplay(i)
|
|
|
|
end
|
|
|
|
maybeUpdateLivingInkSkillDisplay()
|
|
|
|
maybeUpdateServitorSlotDisplay()
|
|
|
|
end
|
|
|
|
|
|
|
|
function updateRowDisplay(rowIndex)
|
|
|
|
if customizations[rowIndex].checkboxes ~= nil then
|
|
|
|
updateCheckboxes(rowIndex)
|
|
|
|
end
|
|
|
|
if customizations[rowIndex].textField ~= nil then
|
|
|
|
updateTextField(rowIndex)
|
|
|
|
end
|
|
|
|
end
|
2022-10-19 19:07:47 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function updateCheckboxes(rowIndex)
|
|
|
|
local checkboxCount = customizations[rowIndex].checkboxes.count
|
|
|
|
local selected = 0
|
|
|
|
if selectedUpgrades[rowIndex] ~= nil and selectedUpgrades[rowIndex].xp ~= nil then
|
|
|
|
selected = selectedUpgrades[rowIndex].xp
|
|
|
|
end
|
|
|
|
local checkboxIndex = rowCheckboxFirstIndex[rowIndex]
|
|
|
|
for col = 1, checkboxCount do
|
|
|
|
local pos = getCheckboxPosition(rowIndex, col)
|
|
|
|
if col <= selected then
|
|
|
|
pos.y = Y_VISIBLE
|
|
|
|
else
|
|
|
|
pos.y = Y_INVISIBLE
|
|
|
|
end
|
2022-10-19 19:07:47 -04:00
|
|
|
self.editButton({
|
2023-08-27 21:09:46 -04:00
|
|
|
index = checkboxIndex,
|
|
|
|
position = pos
|
2022-10-19 19:07:47 -04:00
|
|
|
})
|
2023-08-27 21:09:46 -04:00
|
|
|
checkboxIndex = checkboxIndex + 1
|
|
|
|
end
|
2022-10-19 19:07:47 -04:00
|
|
|
end
|
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function updateTextField(rowIndex)
|
|
|
|
local inputIndex = rowInputIndex[rowIndex]
|
|
|
|
if selectedUpgrades[rowIndex] ~= nil and selectedUpgrades[rowIndex].text ~= nil then
|
|
|
|
self.editInput({
|
|
|
|
index = inputIndex,
|
|
|
|
value = " " .. selectedUpgrades[rowIndex].text
|
|
|
|
})
|
|
|
|
end
|
2022-10-19 19:07:47 -04:00
|
|
|
end
|
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function clickCheckbox(row, col, buttonIndex)
|
|
|
|
if selectedUpgrades[row] == nil then
|
|
|
|
selectedUpgrades[row] = { }
|
|
|
|
selectedUpgrades[row].xp = 0
|
|
|
|
end
|
|
|
|
if selectedUpgrades[row].xp == col then
|
|
|
|
selectedUpgrades[row].xp = col - 1
|
|
|
|
else
|
|
|
|
selectedUpgrades[row].xp = col
|
|
|
|
end
|
|
|
|
updateCheckboxes(row)
|
|
|
|
playmatApi.syncAllCustomizableCards()
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Updates saved value for given text box when it loses focus
|
|
|
|
function clickTextbox(rowIndex, value, selected)
|
|
|
|
if selected == false then
|
|
|
|
if selectedUpgrades[rowIndex] == nil then
|
|
|
|
selectedUpgrades[rowIndex] = { }
|
2022-10-19 19:07:47 -04:00
|
|
|
end
|
2023-08-27 21:09:46 -04:00
|
|
|
selectedUpgrades[rowIndex].text = value:gsub("^%s*(.-)%s*$", "%1")
|
|
|
|
-- Editing isn't actually done yet, and will block the update. Wait a frame so it's finished
|
|
|
|
Wait.frames(function() updateRowDisplay(rowIndex) end, 1)
|
|
|
|
end
|
|
|
|
end
|
2022-10-19 19:07:47 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
---------------------------------------------------------
|
|
|
|
-- Living Ink related functions
|
|
|
|
---------------------------------------------------------
|
|
|
|
|
|
|
|
-- Builds the list of boolean skill selections from the Row 1 text field
|
|
|
|
function maybeLoadLivingInkSkills()
|
|
|
|
if selfId ~= "09079-c" then return end
|
|
|
|
selectedSkills = {
|
|
|
|
willpower = false,
|
|
|
|
intellect = false,
|
|
|
|
combat = false,
|
|
|
|
agility = false
|
|
|
|
}
|
|
|
|
if selectedUpgrades[1] ~= nil and selectedUpgrades[1].text ~= nil then
|
|
|
|
for skill in string.gmatch(selectedUpgrades[1].text, "([^,]+)") do
|
|
|
|
selectedSkills[skill] = true
|
2022-10-19 19:07:47 -04:00
|
|
|
end
|
2023-08-27 21:09:46 -04:00
|
|
|
end
|
|
|
|
end
|
2023-04-22 16:56:01 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
function clickSkill(skillname)
|
|
|
|
selectedSkills[skillname] = not selectedSkills[skillname]
|
|
|
|
maybeUpdateLivingInkSkillDisplay()
|
|
|
|
updateSelectedLivingInkSkillText()
|
2023-04-22 16:56:01 -04:00
|
|
|
end
|
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
-- Creates the invisible buttons overlaying the skill icons
|
|
|
|
function maybeMakeLivingInkSkillSelectionButtons()
|
|
|
|
if selfId ~= "09079-c" then return end
|
|
|
|
|
|
|
|
local buttonData = {
|
|
|
|
function_owner = self,
|
|
|
|
position = { y = 0.2 },
|
|
|
|
height = 130,
|
|
|
|
width = 130,
|
|
|
|
color = { 0, 0, 0, 0 },
|
|
|
|
}
|
|
|
|
|
|
|
|
for skillname, _ in pairs(selectedSkills) do
|
|
|
|
local funcName = "clickSkill" .. skillname
|
|
|
|
self.setVar(funcName, function() clickSkill(skillname) end)
|
|
|
|
|
|
|
|
buttonData.click_function = funcName
|
|
|
|
buttonData.position.x = -1 * SKILL_ICON_POSITIONS[skillname].x
|
|
|
|
buttonData.position.z = SKILL_ICON_POSITIONS[skillname].z
|
2023-04-22 16:56:01 -04:00
|
|
|
self.createButton(buttonData)
|
2023-08-27 21:09:46 -04:00
|
|
|
end
|
2023-04-22 16:56:01 -04:00
|
|
|
end
|
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
-- Builds a comma-delimited string of skills and places it in the Row 1 text field
|
|
|
|
function updateSelectedLivingInkSkillText()
|
|
|
|
local skillString = ""
|
|
|
|
if selectedSkills.willpower then
|
|
|
|
skillString = skillString .. "willpower" .. ","
|
|
|
|
end
|
|
|
|
if selectedSkills.intellect then
|
|
|
|
skillString = skillString .. "intellect" .. ","
|
|
|
|
end
|
|
|
|
if selectedSkills.combat then
|
|
|
|
skillString = skillString .. "combat" .. ","
|
|
|
|
end
|
|
|
|
if selectedSkills.agility then
|
|
|
|
skillString = skillString .. "agility" .. ","
|
|
|
|
end
|
|
|
|
if selectedUpgrades[1] == nil then
|
|
|
|
selectedUpgrades[1] = { }
|
|
|
|
end
|
|
|
|
selectedUpgrades[1].text = skillString
|
2023-04-22 16:56:01 -04:00
|
|
|
end
|
2023-08-27 21:09:46 -04:00
|
|
|
|
|
|
|
-- Refresh the vector circles indicating a skill is selected. Since we can only have one table of
|
|
|
|
-- vectors set, have to refresh all 4 at once
|
|
|
|
function maybeUpdateLivingInkSkillDisplay()
|
|
|
|
if selfId ~= "09079-c" then return end
|
|
|
|
local circles = {}
|
|
|
|
for skill, isSelected in pairs(selectedSkills) do
|
|
|
|
if isSelected then
|
|
|
|
local circle = getCircleVector(SKILL_ICON_POSITIONS[skill])
|
|
|
|
if circle ~= nil then
|
|
|
|
table.insert(circles, circle)
|
|
|
|
end
|
2023-04-22 16:56:01 -04:00
|
|
|
end
|
2023-08-27 21:09:46 -04:00
|
|
|
end
|
|
|
|
self.setVectorLines(circles)
|
|
|
|
end
|
|
|
|
|
|
|
|
function getCircleVector(center)
|
|
|
|
local diameter = Vector(0, 0, 0.1)
|
|
|
|
local pointOfOrigin = Vector(center.x, Y_VISIBLE, center.z)
|
|
|
|
local vec
|
|
|
|
local vecList = {}
|
|
|
|
local arcStep = 5
|
|
|
|
for i = 0, 360, arcStep do
|
|
|
|
diameter:rotateOver('y', arcStep)
|
|
|
|
vec = pointOfOrigin + diameter
|
|
|
|
vec.y = pointOfOrigin.y
|
|
|
|
table.insert(vecList, vec)
|
|
|
|
end
|
|
|
|
|
|
|
|
return {
|
|
|
|
points = vecList,
|
|
|
|
color = VECTOR_COLOR.mystic,
|
|
|
|
thickness = 0.02,
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
---------------------------------------------------------
|
|
|
|
-- Summoned Servitor related functions
|
|
|
|
---------------------------------------------------------
|
|
|
|
|
|
|
|
-- Creates the invisible buttons overlaying the slot words
|
|
|
|
function maybeMakeServitorSlotSelectionButtons()
|
|
|
|
if selfId ~= "09080-c" then return end
|
|
|
|
|
|
|
|
local buttonData = {
|
|
|
|
click_function = "clickArcane",
|
|
|
|
function_owner = self,
|
|
|
|
position = { x = -1 * SLOT_ICON_POSITIONS.arcane.x, y = 0.2, z = SLOT_ICON_POSITIONS.arcane.z },
|
|
|
|
height = 130,
|
|
|
|
width = 130,
|
|
|
|
color = { 0, 0, 0, 0 },
|
|
|
|
}
|
|
|
|
self.createButton(buttonData)
|
|
|
|
|
|
|
|
buttonData.click_function = "clickAlly"
|
|
|
|
buttonData.position.x = -1 * SLOT_ICON_POSITIONS.ally.x
|
|
|
|
self.createButton(buttonData)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- toggles the clicked slot
|
|
|
|
function clickArcane()
|
|
|
|
if selectedUpgrades[6] == nil then
|
|
|
|
selectedUpgrades[6] = { }
|
|
|
|
end
|
|
|
|
if selectedUpgrades[6].text == SUMMONED_SERVITOR_SLOT_INDICES.arcane then
|
|
|
|
selectedUpgrades[6].text = SUMMONED_SERVITOR_SLOT_INDICES.none
|
|
|
|
else
|
|
|
|
selectedUpgrades[6].text = SUMMONED_SERVITOR_SLOT_INDICES.arcane
|
|
|
|
end
|
|
|
|
maybeUpdateServitorSlotDisplay()
|
|
|
|
end
|
|
|
|
|
|
|
|
-- toggles the clicked slot
|
|
|
|
function clickAlly()
|
|
|
|
if selectedUpgrades[6] == nil then
|
|
|
|
selectedUpgrades[6] = { }
|
|
|
|
end
|
|
|
|
if selectedUpgrades[6].text == SUMMONED_SERVITOR_SLOT_INDICES.ally then
|
|
|
|
selectedUpgrades[6].text = SUMMONED_SERVITOR_SLOT_INDICES.none
|
|
|
|
else
|
|
|
|
selectedUpgrades[6].text = SUMMONED_SERVITOR_SLOT_INDICES.ally
|
|
|
|
end
|
|
|
|
maybeUpdateServitorSlotDisplay()
|
2023-04-22 16:56:01 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
-- Refresh the vector circles indicating a slot is selected.
|
2023-08-27 21:09:46 -04:00
|
|
|
function maybeUpdateServitorSlotDisplay()
|
|
|
|
if selfId ~= "09080-c" then return end
|
|
|
|
|
|
|
|
local center = SLOT_ICON_POSITIONS["arcane"]
|
|
|
|
local arcaneVecList = {
|
|
|
|
Vector(center.x + 0.12, Y_VISIBLE, center.z + 0.05),
|
|
|
|
Vector(center.x - 0.12, Y_VISIBLE, center.z + 0.05),
|
|
|
|
Vector(center.x - 0.12, Y_VISIBLE, center.z - 0.05),
|
|
|
|
Vector(center.x + 0.12, Y_VISIBLE, center.z - 0.05),
|
|
|
|
Vector(center.x + 0.12, Y_VISIBLE, center.z + 0.05),
|
|
|
|
}
|
|
|
|
|
|
|
|
center = SLOT_ICON_POSITIONS["ally"]
|
|
|
|
local allyVecList = {
|
|
|
|
Vector(center.x + 0.07, Y_VISIBLE, center.z + 0.05),
|
|
|
|
Vector(center.x - 0.07, Y_VISIBLE, center.z + 0.05),
|
|
|
|
Vector(center.x - 0.07, Y_VISIBLE, center.z - 0.05),
|
|
|
|
Vector(center.x + 0.07, Y_VISIBLE, center.z - 0.05),
|
|
|
|
Vector(center.x + 0.07, Y_VISIBLE, center.z + 0.05),
|
|
|
|
}
|
|
|
|
|
|
|
|
local arcaneVecColor = VECTOR_COLOR.unselected
|
|
|
|
local allyVecColor = VECTOR_COLOR.unselected
|
|
|
|
|
|
|
|
if selectedUpgrades[6] ~= nil and selectedUpgrades[6].text == SUMMONED_SERVITOR_SLOT_INDICES.arcane then
|
|
|
|
arcaneVecColor = VECTOR_COLOR.mystic
|
|
|
|
elseif selectedUpgrades[6] ~= nil and selectedUpgrades[6].text == SUMMONED_SERVITOR_SLOT_INDICES.ally then
|
|
|
|
allyVecColor = VECTOR_COLOR.mystic
|
|
|
|
end
|
|
|
|
|
|
|
|
self.setVectorLines({
|
|
|
|
{
|
|
|
|
points = arcaneVecList,
|
|
|
|
color = arcaneVecColor,
|
|
|
|
thickness = 0.02,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
points = allyVecList,
|
|
|
|
color = allyVecColor,
|
|
|
|
thickness = 0.02,
|
2023-04-22 16:56:01 -04:00
|
|
|
}
|
2023-08-27 21:09:46 -04:00
|
|
|
})
|
|
|
|
end
|
|
|
|
end)
|
|
|
|
__bundle_register("playermat/PlaymatApi", function(require, _LOADED, __bundle_register, __bundle_modules)
|
|
|
|
do
|
|
|
|
local PlaymatApi = { }
|
|
|
|
local internal = { }
|
|
|
|
|
|
|
|
local MAT_IDS = {
|
|
|
|
White = "8b081b",
|
|
|
|
Orange = "bd0ff4",
|
|
|
|
Green = "383d8b",
|
|
|
|
Red = "0840d5"
|
|
|
|
}
|
|
|
|
|
|
|
|
local CLUE_COUNTER_GUIDS = {
|
|
|
|
White = "37be78",
|
|
|
|
Orange = "1769ed",
|
|
|
|
Green = "032300",
|
|
|
|
Red = "d86b7c"
|
|
|
|
}
|
|
|
|
|
|
|
|
local CLUE_CLICKER_GUIDS = {
|
|
|
|
White = "db85d6",
|
|
|
|
Orange = "3f22e5",
|
|
|
|
Green = "891403",
|
|
|
|
Red = "4111de"
|
|
|
|
}
|
|
|
|
|
|
|
|
-- Returns the color of the by position requested playermat as string
|
|
|
|
---@param startPos Table Position of the search, table get's roughly cut into 4 quarters to assign a playermat
|
|
|
|
PlaymatApi.getMatColorByPosition = function(startPos)
|
|
|
|
if startPos.x < -42 then
|
|
|
|
if startPos.z > 0 then
|
|
|
|
return "White"
|
|
|
|
else
|
|
|
|
return "Orange"
|
|
|
|
end
|
|
|
|
else
|
|
|
|
if startPos.z > 0 then
|
|
|
|
return "Green"
|
|
|
|
else
|
|
|
|
return "Red"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Returns the color of the player's hand that is seated next to the playermat
|
|
|
|
---@param matColor String Color of the playermat
|
|
|
|
PlaymatApi.getPlayerColor = function(matColor)
|
|
|
|
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
|
|
|
return mat.getVar("playerColor")
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Returns the color of the playermat that owns the playercolor's hand
|
|
|
|
---@param handColor String Color of the playermat
|
|
|
|
PlaymatApi.getMatColor = function(handColor)
|
|
|
|
local matColors = {"White", "Orange", "Green", "Red"}
|
|
|
|
for i, mat in ipairs(internal.getMatForColor("All")) do
|
|
|
|
local color = mat.getVar("playerColor")
|
|
|
|
if color == handColor then return matColors[i] end
|
|
|
|
end
|
|
|
|
return "NOT_FOUND"
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Returns the result of a cast in the specificed playermat's area
|
|
|
|
---@param matColor String Color of the playermat
|
|
|
|
PlaymatApi.searchPlaymat = function(matColor)
|
|
|
|
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
|
|
|
return mat.call("searchAroundSelf")
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Returns if there is the card "Dream-Enhancing Serum" on the requested playermat
|
|
|
|
---@param matColor String Color of the playermat
|
|
|
|
PlaymatApi.isDES = function(matColor)
|
|
|
|
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
|
|
|
return mat.getVar("isDES")
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Returns the draw deck of the requested playmat
|
|
|
|
---@param matColor String Color of the playermat
|
|
|
|
PlaymatApi.getDrawDeck = function(matColor)
|
|
|
|
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
|
|
|
mat.call("getDrawDiscardDecks")
|
|
|
|
return mat.getVar("drawDeck")
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Returns the position of the discard pile of the requested playmat
|
|
|
|
---@param matColor String Color of the playermat
|
|
|
|
PlaymatApi.getDiscardPosition = function(matColor)
|
|
|
|
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
|
|
|
return mat.call("returnGlobalDiscardPosition")
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Transforms a local position into a global position
|
|
|
|
---@param localPos Table Local position to be transformed
|
|
|
|
---@param matColor String Color of the playermat
|
|
|
|
PlaymatApi.transformLocalPosition = function(localPos, matColor)
|
|
|
|
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
|
|
|
return mat.positionToWorld(localPos)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Returns the rotation of the requested playmat
|
|
|
|
---@param matColor String Color of the playermat
|
|
|
|
PlaymatApi.returnRotation = function(matColor)
|
|
|
|
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
|
|
|
return mat.getRotation()
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Triggers the Upkeep for the requested playmat
|
|
|
|
---@param matColor String Color of the playermat
|
|
|
|
---@param playerColor String Color of the calling player (for messages)
|
|
|
|
PlaymatApi.doUpkeepFromHotkey = function(matColor, playerColor)
|
|
|
|
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
|
|
|
return mat.call("doUpkeepFromHotkey", playerColor)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Returns the active investigator id
|
|
|
|
---@param matColor String Color of the playermat
|
|
|
|
PlaymatApi.returnInvestigatorId = function(matColor)
|
|
|
|
local mat = getObjectFromGUID(MAT_IDS[matColor])
|
|
|
|
return mat.getVar("activeInvestigatorId")
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Sets the requested playermat's snap points to limit snapping to matching card types or not. If
|
|
|
|
-- matchTypes is true, the main card slot snap points will only snap assets, while the
|
|
|
|
-- investigator area point will only snap Investigators. If matchTypes is false, snap points will
|
|
|
|
-- be reset to snap all cards.
|
|
|
|
---@param matchCardTypes Boolean. Whether snap points should only snap for the matching card
|
|
|
|
-- types.
|
|
|
|
---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also
|
|
|
|
-- accepts "All" as a special value which will apply the setting to all four mats.
|
|
|
|
PlaymatApi.setLimitSnapsByType = function(matchCardTypes, matColor)
|
|
|
|
for _, mat in ipairs(internal.getMatForColor(matColor)) do
|
|
|
|
mat.call("setLimitSnapsByType", matchCardTypes)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Sets the requested playermat's draw 1 button to visible
|
|
|
|
---@param isDrawButtonVisible Boolean. Whether the draw 1 button should be visible or not
|
|
|
|
---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also
|
|
|
|
-- accepts "All" as a special value which will apply the setting to all four mats.
|
|
|
|
PlaymatApi.showDrawButton = function(isDrawButtonVisible, matColor)
|
|
|
|
for _, mat in ipairs(internal.getMatForColor(matColor)) do
|
|
|
|
mat.call("showDrawButton", isDrawButtonVisible)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Shows or hides the clickable clue counter for the requested playermat
|
|
|
|
---@param showCounter Boolean. Whether the clickable counter should be present or not
|
|
|
|
---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also
|
|
|
|
-- accepts "All" as a special value which will apply the setting to all four mats.
|
|
|
|
PlaymatApi.clickableClues = function(showCounter, matColor)
|
|
|
|
for _, mat in ipairs(internal.getMatForColor(matColor)) do
|
|
|
|
mat.call("clickableClues", showCounter)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat
|
|
|
|
---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also
|
|
|
|
-- accepts "All" as a special value which will apply the setting to all four mats.
|
|
|
|
PlaymatApi.removeClues = function(matColor)
|
|
|
|
for _, mat in ipairs(internal.getMatForColor(matColor)) do
|
|
|
|
mat.call("removeClues")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Reports the clue count for the requested playermat
|
|
|
|
---@param useClickableCounters Boolean Controls which type of counter is getting checked
|
|
|
|
PlaymatApi.getClueCount = function(useClickableCounters, matColor)
|
|
|
|
local count = 0
|
|
|
|
for _, mat in ipairs(internal.getMatForColor(matColor)) do
|
|
|
|
count = count + tonumber(mat.call("getClueCount", useClickableCounters))
|
2023-04-22 16:56:01 -04:00
|
|
|
end
|
2023-08-27 21:09:46 -04:00
|
|
|
return count
|
|
|
|
end
|
2023-04-22 16:56:01 -04:00
|
|
|
|
2023-08-27 21:09:46 -04:00
|
|
|
-- Adds the specified amount of resources to the requested playermat's resource counter
|
|
|
|
PlaymatApi.gainResources = function(amount, matColor)
|
|
|
|
for _, mat in ipairs(internal.getMatForColor(matColor)) do
|
|
|
|
mat.call("gainResources", amount)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Discard a non-hidden card from the corresponding player's hand
|
|
|
|
PlaymatApi.doDiscardOne = function(matColor)
|
|
|
|
for _, mat in ipairs(internal.getMatForColor(matColor)) do
|
|
|
|
mat.call("doDiscardOne")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
PlaymatApi.syncAllCustomizableCards = function()
|
|
|
|
for _, mat in ipairs(internal.getMatForColor("All")) do
|
|
|
|
mat.call("syncAllCustomizableCards")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- Convenience function to look up a mat's object by color, or get all mats.
|
|
|
|
---@param matColor String for one of the active player colors - White, Orange, Green, Red. Also
|
|
|
|
-- accepts "All" as a special value which will return all four mats.
|
|
|
|
---@return: Array of playermat objects. If a single mat is requested, will return a single-element
|
|
|
|
-- array to simplify processing by consumers.
|
|
|
|
internal.getMatForColor = function(matColor)
|
|
|
|
local targetMatGuid = MAT_IDS[matColor]
|
|
|
|
if targetMatGuid != nil then
|
|
|
|
return { getObjectFromGUID(targetMatGuid) }
|
|
|
|
end
|
|
|
|
if matColor == "All" then
|
|
|
|
return {
|
|
|
|
getObjectFromGUID(MAT_IDS.White),
|
|
|
|
getObjectFromGUID(MAT_IDS.Orange),
|
|
|
|
getObjectFromGUID(MAT_IDS.Green),
|
|
|
|
getObjectFromGUID(MAT_IDS.Red),
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return PlaymatApi
|
2023-04-22 16:56:01 -04:00
|
|
|
end
|
|
|
|
end)
|
|
|
|
return __bundle_require("__root")
|