--- 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", "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