233 lines
6.9 KiB
Lua

--- Entry point.
-- @module advtrains_doc_integration
local worldpath = minetest.get_worldpath()
local modpath = minetest.get_modpath("advtrains_doc_integration")
local S = minetest.get_translator("advtrains_doc_integration")
advtrains_doc_integration = {}
for _, m in ipairs{
"mathutils", "utils", "bc", "describe", "hypertext", "latex",
} do
advtrains_doc_integration[m] = dofile(("%s/%s.lua"):format(modpath, m))
end
local utils = advtrains_doc_integration.utils
local function dlxtrains_livery_information(prototype)
if not dlxtrains then
return nil
end
local old_update_livery = dlxtrains.update_livery
dlxtrains.update_livery = function(_, _, x)
return coroutine.yield(x)
end
local env = {
coroutine = coroutine,
dlxtrains = table.copy(dlxtrains),
}
local function main(G, f)
setfenv(0, G)
f()
return error()
end
local t = {coroutine.resume(coroutine.create(main), env, prototype.custom_may_destroy or function() end)}
dlxtrains.update_livery = old_update_livery
if not t[1] then
return nil
end
return unpack(t, 2)
end
local advtrains_livery_tools_information
do -- helper for Marnack's Advtrains livery tools
local atliv = {}
function atliv:get_textures_from_design(design)
local tp = type(design)
if tp == "string" then
return self:get_textures_from_design(self.liveries[design])
elseif tp ~= "table" then
return
end
local template = self.templates[design.livery_template_name]
if not template then
return nil
end
local odef = template.overlays
local textures = utils.map(template.base_textures, function(str) return {str} end)
for _, overlay in utils.spairs(design.overlays) do
local o = odef[overlay.id]
local t = textures[(o or {}).slot_idx]
if t and o then
local alpha = math.min(255, math.max(0, o.alpha or 255))
table.insert(t, string.format("(%s^[colorize:%s:%d)", utils.texture_escape(o.texture), utils.texture_escape(overlay.color), alpha))
end
end
return utils.map(textures, function(st) return table.concat(st, "^") end)
end
local mt = {
__index = atliv,
}
advtrains_livery_tools_information = function(wname)
if not advtrains_livery_database then
return nil
end
local tnames = advtrains_livery_database.get_livery_template_names_for_wagon(wname)
if next(tnames) == nil then
return nil
end
local templates = {}
for _, tname in pairs(tnames) do
templates[tname] = advtrains_livery_database.get_wagon_livery_template(wname, tname)
end
local lnames = advtrains_livery_database.get_predefined_livery_names(wname)
local lnames_t = {}
local liveries = {}
for _, lid in pairs(lnames) do
local lname = lid.livery_name
liveries[lname] = advtrains_livery_database.get_predefined_livery(wname, lname)
table.insert(lnames_t, lname)
end
table.sort(tnames)
table.sort(lnames_t)
local obj = {
templates = templates,
template_names = tnames,
liveries = liveries,
livery_names = lnames_t,
}
return setmetatable(obj, mt)
end
end
local prototype_cache = {}
advtrains_doc_integration.prototypes = prototype_cache -- ONLY FOR DEBUGGING
local function adjust_wagon_prototype(itemname, prototype)
local p = prototype_cache[itemname]
if p then
return p
end
p = table.copy(prototype)
if p._doc_wagon_longdesc then
p.longdesc = p._long_wagon_longdesc
end
p.horn_sound = utils.adjust_soundspec(p.horn_sound)
local pax, driver = 0, 0
if p.seats and p.seat_groups then
for _, v in pairs(p.seats) do
if p.seat_groups[v.group].driving_ctrl_access then
driver = driver + 1
else
pax = pax + 1
end
p.seat_groups[v.group].count = (p.seat_groups[v.group].count or 0) + 1
end
end
p.max_passengers = pax
p.max_drivers = driver
p.max_seats = pax+driver
p.doors = {}
for _, state in pairs {"open", "close"} do
local st = (prototype.doors or {})[state] or {}
local state_data = {
sound = utils.adjust_soundspec(st.sound),
}
p.doors[state] = state_data
end
local bikelivdef = p.livery_definition
local dlxlivdef = dlxtrains_livery_information(p)
local atlivdef = advtrains_livery_tools_information(itemname)
p.dlxtrains_livery = dlxlivdef
p.advtrains_livery_tools = atlivdef
local txbase = p.textures
p.livery_textures = {}
if dlxlivdef then
-- DlxTrains: no "default" livery
for i = 0, dlxlivdef.count-1 do
local texture = string.format("%s_%s.png", dlxlivdef.filename_prefix, dlxlivdef[i].code)
p.livery_textures[2*i] = {texture}
p.livery_textures[2*i+1] = {texture .. "^[transformR180"}
end
else
p.livery_textures[0] = txbase
end
if bikelivdef then
local slot = p.livery_texture_slot
local components = bikelivdef.components
local basefile = bikelivdef.base_texture_file
for _, pdef in ipairs(bikelivdef.presets) do
local tx = table.copy(txbase)
local st = {basefile}
for _, l in ipairs(pdef.livery_stack.layers) do
table.insert(st, string.format("(%s^[colorize:%s)", utils.texture_escape(components[l.component].texture_file), utils.texture_escape(l.color)))
end
tx[slot] = table.concat(st, "^")
table.insert(p.livery_textures, tx)
end
end
if atlivdef then
for _, dname in ipairs(atlivdef.livery_names) do
table.insert(p.livery_textures, atlivdef:get_textures_from_design(dname) or txbase)
end
end
prototype_cache[itemname] = p
return p
end
local registered_on_prototype_loaded = {}
--- Register a callback that will be run when a prototype becomes available.
-- @tparam function callback The callback to run when the prototype
-- becomes available. The callback function is passed the itemname and the
-- prototype of the wagon.
function advtrains_doc_integration.register_on_prototype_loaded(callback)
table.insert(registered_on_prototype_loaded, callback)
end
minetest.register_on_mods_loaded(function()
for itemname, prototype in pairs(advtrains.wagon_prototypes) do
prototype = adjust_wagon_prototype(itemname, prototype)
prototype.name = itemname
for _, cb in ipairs(registered_on_prototype_loaded) do
cb(itemname, prototype)
end
end
end)
--- Write a wagon datasheet to a LaTeX file in the world path.
-- @tparam string itemname The item name of the wagon prototype.
function advtrains_doc_integration.write_wagon_info_as_latex(itemname)
local filename = string.format("%s/atdoc_wagon_%s.tex", worldpath, itemname:gsub(":", "_"))
local description = advtrains_doc_integration.latex.describe_wagon_prototype(itemname)
if description then
minetest.safe_file_write(filename, description)
end
end
--- Write a wagon datasheet for each wagon using @{write_wagon_info_as_latex}.
function advtrains_doc_integration.write_all_wagons_as_latex()
for k in pairs(prototype_cache) do
advtrains_doc_integration.write_wagon_info_as_latex(k)
end
end
minetest.register_chatcommand("atdoc_write", {
params = "",
description = S("Export Advtrains-related information"),
privs = {server = true},
func = function()
advtrains_doc_integration.write_all_wagons_as_latex()
end,
})
dofile(modpath .. "/doc_ui.lua")
if minetest.get_modpath("mtt") then
dofile(modpath .. "/mtt.lua")
end