init.lua 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. --- Entry point.
  2. -- @module advtrains_doc_integration
  3. local worldpath = minetest.get_worldpath()
  4. local modpath = minetest.get_modpath("advtrains_doc_integration")
  5. local S = minetest.get_translator("advtrains_doc_integration")
  6. advtrains_doc_integration = {}
  7. for _, m in ipairs{
  8. "mathutils", "utils", "bc", "describe", "hypertext", "latex",
  9. } do
  10. advtrains_doc_integration[m] = dofile(("%s/%s.lua"):format(modpath, m))
  11. end
  12. local utils = advtrains_doc_integration.utils
  13. local function dlxtrains_livery_information(prototype)
  14. if not dlxtrains then
  15. return nil
  16. end
  17. local old_update_livery = dlxtrains.update_livery
  18. dlxtrains.update_livery = function(_, _, x)
  19. return coroutine.yield(x)
  20. end
  21. local env = {
  22. coroutine = coroutine,
  23. dlxtrains = table.copy(dlxtrains),
  24. }
  25. local function main(G, f)
  26. setfenv(0, G)
  27. f()
  28. return error()
  29. end
  30. local t = {coroutine.resume(coroutine.create(main), env, prototype.custom_may_destroy or function() end)}
  31. dlxtrains.update_livery = old_update_livery
  32. if not t[1] then
  33. return nil
  34. end
  35. return unpack(t, 2)
  36. end
  37. local advtrains_livery_tools_information
  38. do -- helper for Marnack's Advtrains livery tools
  39. local atliv = {}
  40. function atliv:get_textures_from_design(design)
  41. local tp = type(design)
  42. if tp == "string" then
  43. return self:get_textures_from_design(self.liveries[design])
  44. elseif tp ~= "table" then
  45. return
  46. end
  47. local template = self.templates[design.livery_template_name]
  48. if not template then
  49. return nil
  50. end
  51. local odef = template.overlays
  52. local textures = utils.map(template.base_textures, function(str) return {str} end)
  53. for _, overlay in utils.spairs(design.overlays) do
  54. local o = odef[overlay.id]
  55. local t = textures[(o or {}).slot_idx]
  56. if t and o then
  57. local alpha = math.min(255, math.max(0, o.alpha or 255))
  58. table.insert(t, string.format("(%s^[colorize:%s:%d)", utils.texture_escape(o.texture), utils.texture_escape(overlay.color), alpha))
  59. end
  60. end
  61. return utils.map(textures, function(st) return table.concat(st, "^") end)
  62. end
  63. local mt = {
  64. __index = atliv,
  65. }
  66. advtrains_livery_tools_information = function(wname)
  67. if not advtrains_livery_database then
  68. return nil
  69. end
  70. local tnames = advtrains_livery_database.get_livery_template_names_for_wagon(wname)
  71. if next(tnames) == nil then
  72. return nil
  73. end
  74. local templates = {}
  75. for _, tname in pairs(tnames) do
  76. templates[tname] = advtrains_livery_database.get_wagon_livery_template(wname, tname)
  77. end
  78. local lnames = advtrains_livery_database.get_predefined_livery_names(wname)
  79. local lnames_t = {}
  80. local liveries = {}
  81. for _, lid in pairs(lnames) do
  82. local lname = lid.livery_name
  83. liveries[lname] = advtrains_livery_database.get_predefined_livery(wname, lname)
  84. table.insert(lnames_t, lname)
  85. end
  86. table.sort(tnames)
  87. table.sort(lnames_t)
  88. local obj = {
  89. templates = templates,
  90. template_names = tnames,
  91. liveries = liveries,
  92. livery_names = lnames_t,
  93. }
  94. return setmetatable(obj, mt)
  95. end
  96. end
  97. local prototype_cache = {}
  98. advtrains_doc_integration.prototypes = prototype_cache -- ONLY FOR DEBUGGING
  99. local function adjust_wagon_prototype(itemname, prototype)
  100. local p = prototype_cache[itemname]
  101. if p then
  102. return p
  103. end
  104. p = table.copy(prototype)
  105. if p._doc_wagon_longdesc then
  106. p.longdesc = p._long_wagon_longdesc
  107. end
  108. p.horn_sound = utils.adjust_soundspec(p.horn_sound)
  109. local pax, driver = 0, 0
  110. if p.seats and p.seat_groups then
  111. for _, v in pairs(p.seats) do
  112. if p.seat_groups[v.group].driving_ctrl_access then
  113. driver = driver + 1
  114. else
  115. pax = pax + 1
  116. end
  117. p.seat_groups[v.group].count = (p.seat_groups[v.group].count or 0) + 1
  118. end
  119. end
  120. p.max_passengers = pax
  121. p.max_drivers = driver
  122. p.max_seats = pax+driver
  123. p.doors = {}
  124. for _, state in pairs {"open", "close"} do
  125. local st = (prototype.doors or {})[state] or {}
  126. local state_data = {
  127. sound = utils.adjust_soundspec(st.sound),
  128. }
  129. p.doors[state] = state_data
  130. end
  131. local bikelivdef = p.livery_definition
  132. local dlxlivdef = dlxtrains_livery_information(p)
  133. local atlivdef = advtrains_livery_tools_information(itemname)
  134. p.dlxtrains_livery = dlxlivdef
  135. p.advtrains_livery_tools = atlivdef
  136. local txbase = p.textures
  137. p.livery_textures = {}
  138. if dlxlivdef then
  139. -- DlxTrains: no "default" livery
  140. for i = 0, dlxlivdef.count-1 do
  141. local texture = string.format("%s_%s.png", dlxlivdef.filename_prefix, dlxlivdef[i].code)
  142. p.livery_textures[2*i] = {texture}
  143. p.livery_textures[2*i+1] = {texture .. "^[transformR180"}
  144. end
  145. else
  146. p.livery_textures[0] = txbase
  147. end
  148. if bikelivdef then
  149. local slot = p.livery_texture_slot
  150. local components = bikelivdef.components
  151. local basefile = bikelivdef.base_texture_file
  152. for _, pdef in ipairs(bikelivdef.presets) do
  153. local tx = table.copy(txbase)
  154. local st = {basefile}
  155. for _, l in ipairs(pdef.livery_stack.layers) do
  156. table.insert(st, string.format("(%s^[colorize:%s)", utils.texture_escape(components[l.component].texture_file), utils.texture_escape(l.color)))
  157. end
  158. tx[slot] = table.concat(st, "^")
  159. table.insert(p.livery_textures, tx)
  160. end
  161. end
  162. if atlivdef then
  163. for _, dname in ipairs(atlivdef.livery_names) do
  164. table.insert(p.livery_textures, atlivdef:get_textures_from_design(dname) or txbase)
  165. end
  166. end
  167. prototype_cache[itemname] = p
  168. return p
  169. end
  170. local registered_on_prototype_loaded = {}
  171. --- Register a callback that will be run when a prototype becomes available.
  172. -- @tparam function callback The callback to run when the prototype
  173. -- becomes available. The callback function is passed the itemname and the
  174. -- prototype of the wagon.
  175. function advtrains_doc_integration.register_on_prototype_loaded(callback)
  176. table.insert(registered_on_prototype_loaded, callback)
  177. end
  178. minetest.register_on_mods_loaded(function()
  179. for itemname, prototype in pairs(advtrains.wagon_prototypes) do
  180. prototype = adjust_wagon_prototype(itemname, prototype)
  181. prototype.name = itemname
  182. for _, cb in ipairs(registered_on_prototype_loaded) do
  183. cb(itemname, prototype)
  184. end
  185. end
  186. end)
  187. --- Write a wagon datasheet to a LaTeX file in the world path.
  188. -- @tparam string itemname The item name of the wagon prototype.
  189. function advtrains_doc_integration.write_wagon_info_as_latex(itemname)
  190. local filename = string.format("%s/atdoc_wagon_%s.tex", worldpath, itemname:gsub(":", "_"))
  191. local description = advtrains_doc_integration.latex.describe_wagon_prototype(itemname)
  192. if description then
  193. minetest.safe_file_write(filename, description)
  194. end
  195. end
  196. --- Write a wagon datasheet for each wagon using @{write_wagon_info_as_latex}.
  197. function advtrains_doc_integration.write_all_wagons_as_latex()
  198. for k in pairs(prototype_cache) do
  199. advtrains_doc_integration.write_wagon_info_as_latex(k)
  200. end
  201. end
  202. minetest.register_chatcommand("atdoc_write", {
  203. params = "",
  204. description = S("Export Advtrains-related information"),
  205. privs = {server = true},
  206. func = function()
  207. advtrains_doc_integration.write_all_wagons_as_latex()
  208. end,
  209. })
  210. dofile(modpath .. "/doc_ui.lua")
  211. if minetest.get_modpath("mtt") then
  212. dofile(modpath .. "/mtt.lua")
  213. end