SCED/src/core/PlayAreaSelector.ttslua
2024-06-26 13:59:20 +02:00

215 lines
6.3 KiB
Plaintext

require("core/PlayAreaImageData") -- this fills the variable "PLAYAREA_IMAGE_DATA"
local optionPanelApi = require("core/OptionPanelApi")
local playAreaApi = require("core/PlayAreaApi")
local typeIndex, selectionIndex, plainNameCache
function onSave()
return JSON.encode({
typeIndex = typeIndex,
selectionIndex = selectionIndex
})
end
function onLoad(savedData)
if savedData and savedData ~= "" then
local loadedData = JSON.decode(savedData) or {}
typeIndex = loadedData.typeIndex or 1
selectionIndex = loadedData.selectionIndex or 1
end
self.createButton({
function_owner = self,
click_function = "onClick_toggleGallery",
tooltip = "Show Image Gallery",
position = {0, 0.06, 0},
height = 1500,
width = 1500,
color = { 1, 1, 1, 0 }
})
Wait.time(updatePlayAreaGallery, 0.5)
math.randomseed(os.time())
end
-- click function for main button
function onClick_toggleGallery(_, playerColor)
Global.call("togglePlayAreaGallery", playerColor)
end
function getDataSubTableByIndex(dataTable, index)
local loopId = 1
for i, v in pairs(dataTable) do
if index == loopId then return v end
loopId = loopId + 1
end
return {}
end
function updatePlayAreaGallery()
-- get subtables
local dataForType = getDataSubTableByIndex(PLAYAREA_IMAGE_DATA, typeIndex)
local dataForSelection = getDataSubTableByIndex(dataForType, selectionIndex)
-- get global xml to insert elements
local globalXml = UI.getXmlTable()
-- selectable items
local itemSelection = getXmlTableElementById(globalXml, 'itemSelection')
itemSelection.children = {}
local i = 0
for itemName, _ in pairs(dataForType) do
i = i + 1
table.insert(itemSelection.children,
{
tag = "Panel",
attributes = { class = "itemPanel", id = "typePanel" .. i },
children = {
tag = "Text",
value = itemName,
attributes = { class = "itemText", id = "typeListText" .. i }
}
})
end
-- selectable images for that item
local playareaList = getXmlTableElementById(globalXml, 'playareaList')
playareaList.children = {}
for i, v in ipairs(dataForSelection) do
table.insert(playareaList.children,
{
tag = "VerticalLayout",
attributes = { class = "imageBox", id = "image" .. i },
children = {
{
tag = 'Image',
attributes = { class = "playareaImage", image = v.URL }
},
{
tag = 'Text',
value = v.Name,
attributes = { class = "imageName" }
}
}
})
end
playareaList.attributes.height = round(#playareaList.children / 2, 0) * 380
Global.call("updateGlobalXml", globalXml)
Wait.time(highlightTabAndItem, 0.1)
end
function onClick_imageTab(_, _, tabId)
typeIndex = tonumber(tabId:sub(9))
selectionIndex = 1
updatePlayAreaGallery()
end
function onClick_listItem(_, _, listId)
selectionIndex = tonumber(listId:sub(10))
updatePlayAreaGallery()
end
function onClick_image(player, _, id)
local imageIndex = tonumber(id:sub(6))
local dataForType = getDataSubTableByIndex(PLAYAREA_IMAGE_DATA, typeIndex)
local dataForSelection = getDataSubTableByIndex(dataForType, selectionIndex)
local newURL = dataForSelection[imageIndex].URL
playAreaApi.updateSurface(newURL)
Global.call("togglePlayAreaGallery", player.color)
end
function highlightTabAndItem()
-- highlight active tab
for i = 1, 5 do
local color = "#888888"
if i == typeIndex then color = "#ffffff" end
UI.setAttribute("imageTab" .. i, "color", color)
end
-- highlight item
UI.setAttribute("typePanel" .. selectionIndex, "color", "grey")
UI.setAttribute("typeListText" .. selectionIndex, "color", "black")
end
-- loops through an XML table and returns the specified object
---@param ui table XmlTable (get this via getXmlTable)
---@param id string Id of the object to return
function getXmlTableElementById(ui, id)
for _, obj in ipairs(ui) do
if obj.attributes and obj.attributes.id and obj.attributes.id == id then return obj end
if obj.children then
local result = getXmlTableElementById(obj.children, id)
if result then return result end
end
end
return nil
end
-- utility function
function round(num, numDecimalPlaces)
local mult = 10 ^ (numDecimalPlaces or 0)
return math.floor(num * mult + 0.5) / mult
end
function maybeUpdatePlayAreaImage(scenarioName)
-- check if option is enabled
local optionPanelState = optionPanelApi.getOptions()
if not optionPanelState["changePlayAreaImage"] then return end
-- initialize cache if nil
if not plainNameCache then
plainNameCache = {}
for i, dataForType in pairs(PLAYAREA_IMAGE_DATA) do
for j, dataForCycle in pairs(dataForType) do
for k, data in ipairs(dataForCycle) do
local plainName = getPlainName(data.Name)
-- override plainName for all images in the "Other Images" category (except the default image)
if i == "Other Images" and data.Name ~= "Default Image" then
plainName = "Generic"
end
if not plainNameCache[plainName] then
plainNameCache[plainName] = {}
end
table.insert(plainNameCache[plainName], data.URL)
end
end
end
end
-- look for matching playarea image or use generic ones instead
local listOfEligibleImages = {}
if plainNameCache[scenarioName] then
listOfEligibleImages = plainNameCache[scenarioName]
else
listOfEligibleImages = plainNameCache["Generic"]
end
-- get a random entry from the eligible list
local newImageIndex = math.random(#listOfEligibleImages)
playAreaApi.updateSurface(listOfEligibleImages[newImageIndex])
end
-- attempts to extract the plain scenario name from the playarea image name
function getPlainName(str)
-- remove prefix type 1
str = str:gsub("%w+%-%w%s%-%s", "") -- matches "II-B - Thousand Shapes of Horror 1"
-- remove prefix type 2
str = str:gsub("%w+%-%w%s", "") -- matches "59-Z Congress of Keys 1"
-- remove prefix type 3
str = str:gsub("%w+%s%-%s", "") -- matches "III - The Secret Name 4"
-- remove prefix type 4
str = str:gsub("%?+%s%-%s", "") -- matches "??? - Fatal Mirage"
-- remove suffix (numbering)
str = str:gsub("%s%d+", "")
return str
end