317 lines
11 KiB
Lua
317 lines
11 KiB
Lua
local S = minetest.get_translator "advtrains_doc_integration"
|
|
local D = advtrains_doc_integration.describe
|
|
local H = advtrains_doc_integration.hypertext
|
|
local utils = advtrains_doc_integration.utils
|
|
local fsescape = minetest.formspec_escape
|
|
|
|
local function S2(a, b)
|
|
return S(a, S(b))
|
|
end
|
|
|
|
local function addlist(lst, tbl, title, fallback1, fallback2, mapf)
|
|
if not tbl then
|
|
if fallback2 then
|
|
table.insert(lst, fallback2)
|
|
elseif fallback2 == false and fallback1 then
|
|
table.insert(lst, fallback1)
|
|
end
|
|
elseif next(tbl) ~= nil then
|
|
table.insert(lst, title)
|
|
for k, v in pairs(tbl) do
|
|
if mapf then
|
|
k = mapf(k, v)
|
|
end
|
|
table.insert(lst, H.listitem(k, true))
|
|
end
|
|
elseif fallback1 then
|
|
table.insert(lst, fallback1)
|
|
end
|
|
end
|
|
|
|
local function blankline(st)
|
|
return table.insert(st, "")
|
|
end
|
|
|
|
local wlivprev = {}
|
|
|
|
local function get_livery_preview_selection(pname, itemname)
|
|
return (wlivprev[pname] or {})[itemname] or 0
|
|
end
|
|
|
|
local function get_livery_preview(itemname, id)
|
|
local tx = (advtrains_doc_integration.prototypes[itemname] or {}).livery_textures
|
|
return tx[id] or tx[0]
|
|
end
|
|
|
|
local function render_livery_textures(pname, itemname)
|
|
local str = table.concat(utils.map(get_livery_preview(itemname, get_livery_preview_selection(pname, itemname)), fsescape), ",")
|
|
return str
|
|
end
|
|
|
|
local function set_livery_preview_selection(pname, itemname, id)
|
|
local t = wlivprev[pname]
|
|
if not t then
|
|
t = {}
|
|
wlivprev[pname] = t
|
|
end
|
|
t[itemname] = id
|
|
end
|
|
|
|
local function doc_render_wagon_information(prototype, pname)
|
|
local desctext = {}
|
|
if prototype._doc_wagon_longdesc then
|
|
table.insert(desctext, tostring(prototype._doc_wagon_longdesc))
|
|
blankline(desctext)
|
|
end
|
|
table.insert(desctext, H.header(S("Basic Information")))
|
|
table.insert(desctext, S("Itemstring: @1", H.mono(prototype.name)))
|
|
addlist(desctext, prototype.drops, S("Drops:"), S("Drops nothing"), false, function(_, v) return H.describe_item(v) end)
|
|
addlist(desctext, prototype.drives_on, S("Drives on:"), nil, nil, H.mono)
|
|
addlist(desctext, prototype.coupler_types_front, S("Compatible front couplers:"), S2("Front coupler: @1", "Absent"), S2("Front coupler: @1", "Universal"), H.describe_coupler)
|
|
addlist(desctext, prototype.coupler_types_back, S("Compatible rear couplers:"), S2("Rear coupler: @1", "Absent"), S2("Rear coupler: @1", "Universal"), H.describe_coupler)
|
|
table.insert(desctext, S("Wagon span: @1", prototype.wagon_span and D.length(2*prototype.wagon_span) or S("Undefined")))
|
|
table.insert(desctext, S("Maximum speed: @1", prototype.max_speed and D.speed(prototype.max_speed) or S("Undefined")))
|
|
table.insert(desctext, S2("Motive power: @1", prototype.is_locomotive and "Present" or "Absent"))
|
|
table.insert(desctext, S("Horn sound: @1", H.describe_sound("playhorn", prototype.horn_sound)))
|
|
if prototype.doors.open.sound or prototype.doors.close.sound then
|
|
table.insert(desctext, S("Door sound: @1 (when opening), @2 (when closing)",
|
|
H.describe_sound("playdooropen", prototype.doors.open.sound),
|
|
H.describe_sound("playdoorclose", prototype.doors.close.sound)))
|
|
else
|
|
table.insert(desctext, S2("Door sound: @1", "Undefined"))
|
|
end
|
|
|
|
blankline(desctext)
|
|
table.insert(desctext, H.header(S("Wagon Capacity")))
|
|
table.insert(desctext, S("Passenger seats: @1", prototype.max_passengers))
|
|
table.insert(desctext, S("Driver seats: @1", prototype.max_drivers))
|
|
if prototype.has_inventory then
|
|
addlist(desctext, prototype.inventory_list_sizes, S("Cargo inventory size:"), S2("Cargo inventory: @1", "Present"), false, function(k, v)
|
|
return string.format("%s: %d", H.mono(k), v)
|
|
end)
|
|
else
|
|
table.insert(desctext, S2("Cargo inventory: @1", "Absent"))
|
|
end
|
|
if techage and prototype.techage_liquid_capacity then
|
|
table.insert(desctext, S("Liquid Capacity (Techage): @1", string.format("%d", prototype.techage_liquid_capacity)))
|
|
end
|
|
|
|
blankline(desctext)
|
|
table.insert(desctext, H.header(S("Wagon Appearance")))
|
|
table.insert(desctext, S("Mesh: @1", prototype.mesh and H.mono(prototype.mesh) or "None"))
|
|
addlist(desctext, prototype.textures, S("Textures:"), S("No textures"), false, function(_, v) return H.mono(v) end)
|
|
|
|
local livsel = get_livery_preview_selection(pname, prototype.name)
|
|
local livrst = (livsel ~= 0 and not prototype.dlxtrains_livery) and " " .. H.action("preview_0", S("[Reset Preview]")) or ""
|
|
local livids = 0
|
|
local function livprev(desc)
|
|
livids = livids+1
|
|
local label = H.plain(desc)
|
|
if livids == livsel then
|
|
label = H.bold(desc)
|
|
end
|
|
return H.action(string.format("preview_%d", livids), label, true)
|
|
end
|
|
|
|
local dlxlivdef = prototype.dlxtrains_livery
|
|
table.insert(desctext, S2("DlxTrains livery system: @1", dlxlivdef and "Supported" or "Unsupported"))
|
|
if dlxlivdef then
|
|
livids = -1
|
|
table.insert(desctext, "Livery presets:")
|
|
for k = 0, dlxlivdef.count-1 do
|
|
table.insert(desctext, H.listitem(string.format("%s (%s, %s)", H.mono(dlxlivdef[k].code), livprev(S("default")), livprev(S("weathered"))), true))
|
|
end
|
|
end
|
|
|
|
local bikeliv = S("Unsupported")
|
|
local bikelivdesc = nil
|
|
if prototype.set_livery then
|
|
if prototype.livery_definition then
|
|
bikeliv = S("Supported by the multi_component_liveries mod")
|
|
bikelivdesc = {}
|
|
addlist(bikelivdesc, prototype.livery_definition.components, S("Livery components:"), nil, nil, function(_, v) return H.plain(v.description) end)
|
|
addlist(bikelivdesc, prototype.livery_definition.presets, S("Livery presets:") .. livrst, nil, nil, function(_, v) return livprev(v.description) end)
|
|
bikelivdesc = table.concat(bikelivdesc, "\n")
|
|
else
|
|
bikeliv = S("Supported")
|
|
end
|
|
end
|
|
table.insert(desctext, S("Livery system with bike painter: @1", bikeliv))
|
|
table.insert(desctext, bikelivdesc)
|
|
|
|
local atlivdef = prototype.advtrains_livery_tools
|
|
table.insert(desctext, S2("Advtrains livery tools (Marnack): @1", atlivdef and "Supported" or "Unsupported"))
|
|
if atlivdef then
|
|
addlist(desctext, atlivdef.template_names, S("Livery templates:"), nil, nil, function(_, v) return H.plain(v) end)
|
|
addlist(desctext, atlivdef.livery_names, S("Livery presets:") .. livrst, nil, nil, function(_, v) return livprev(v) end)
|
|
end
|
|
|
|
blankline(desctext)
|
|
table.insert(desctext, H.header(S("Implementation Details")))
|
|
local attachment_offset_support = S("Unsupported")
|
|
if advtrains_attachment_offset_patch then
|
|
local t = advtrains_attachment_offset_patch
|
|
if prototype.get_on == t.get_on_override and prototype.get_off == t.get_off_override then
|
|
attachment_offset_support = S("Supported")
|
|
end
|
|
end
|
|
|
|
table.insert(desctext, S("Proper player attachment positioning: @1", attachment_offset_support))
|
|
for k, v in pairs {
|
|
custom_on_activate = "Custom instantiation callback",
|
|
custom_on_step = "Custom step function",
|
|
custom_on_velocity_change = "Custom velocity change callback",
|
|
} do
|
|
table.insert(desctext, S2(v .. ": @1", prototype[k] and "Defined" or "Undefined"))
|
|
end
|
|
|
|
local x0, y0 = doc.FORMSPEC.ENTRY_START_X+0.25, doc.FORMSPEC.ENTRY_START_Y
|
|
local x1, y1 = doc.FORMSPEC.ENTRY_END_X+0.75, doc.FORMSPEC.ENTRY_END_Y+0.625
|
|
local width, height = x1-x0, y1-y0
|
|
local mside = height/2
|
|
|
|
local mesh = fsescape(prototype.mesh or "")
|
|
local textures = render_livery_textures(pname, prototype.name)
|
|
local fstext = {
|
|
string.format("hypertext[%f,%f;%f,%f;entry_body;%s]", x0, y0, width-mside, height+0.875, fsescape(table.concat(desctext, "\n"))),
|
|
string.format("item_image[%f,%f;%f,%f;%s]", x1-mside, y0+0.0625, mside, mside, fsescape(prototype.name)),
|
|
string.format("model[%f,%f;%f,%f;%s;%s;%s;%f,%f]",
|
|
x1-mside, y1-mside, mside, mside, "wagon_model", mesh, textures, -30, 135),
|
|
}
|
|
return table.concat(fstext, "\n")
|
|
end
|
|
|
|
if doc then
|
|
advtrains_doc_integration.register_on_prototype_loaded(function(itemname, prototype)
|
|
minetest.override_item(itemname, {_doc_items_create_entry = false})
|
|
doc.add_entry("advtrains_wagons", itemname, {
|
|
name = ItemStack(itemname):get_short_description(),
|
|
data = prototype,
|
|
})
|
|
if doc.sub.identifier then
|
|
doc.sub.identifier.register_object(itemname, "advtrains_wagons", itemname)
|
|
end
|
|
end)
|
|
|
|
if doc.sub.items then
|
|
local register_factoid = doc.sub.items.register_factoid
|
|
local function ndef_field_factoid(cat, ftype, f, ...)
|
|
local ftp = type(f)
|
|
if ftp == "string" then
|
|
local desc = f
|
|
f = function(x)
|
|
if x ~= nil then
|
|
return desc
|
|
end
|
|
end
|
|
end
|
|
local keys = {...}
|
|
local idx = function(t)
|
|
for _, k in ipairs(keys) do
|
|
if type(t) ~= "table" then
|
|
return nil
|
|
end
|
|
t = t[k]
|
|
end
|
|
return t
|
|
end
|
|
local function fgen(_, def)
|
|
return f(idx(def)) or ""
|
|
end
|
|
return register_factoid(cat, ftype, fgen)
|
|
end
|
|
local function group_factoid(cat, gr, f)
|
|
local function func(x)
|
|
return f(x or 0)
|
|
end
|
|
return ndef_field_factoid(cat, "groups", func, "groups", gr)
|
|
end
|
|
for cat, cinfo in pairs{
|
|
nodes = {
|
|
not_blocking_trains = S("This block does not block trains."),
|
|
save_in_at_nodedb = S("This block is saved in the Advtrains node database."),
|
|
},
|
|
} do
|
|
for group, ginfo in pairs(cinfo) do
|
|
local tp = type(ginfo)
|
|
if tp == "string" then
|
|
group_factoid(cat, group, function(x)
|
|
if x > 0 then
|
|
return ginfo
|
|
end
|
|
end)
|
|
elseif tp == "function" then
|
|
group_factoid(cat, group, ginfo)
|
|
end
|
|
end
|
|
end
|
|
for fname, t in pairs {
|
|
advtrains = {
|
|
on_train_enter = S("This track reacts to passing trains."),
|
|
on_train_approach = S("This track reacts to approaching trains."),
|
|
},
|
|
luaautomation = {
|
|
fire_event = S("This block handles LuaATC events."),
|
|
},
|
|
} do
|
|
for subfname, val in pairs(t) do
|
|
local function f(x)
|
|
if x ~= nil then
|
|
return val
|
|
end
|
|
end
|
|
ndef_field_factoid("nodes", "groups", f, fname, subfname)
|
|
end
|
|
end
|
|
register_factoid("nodes", "groups", function(_, ndef)
|
|
if ndef.advtrains then
|
|
local atdef = ndef.advtrains
|
|
if atdef.set_aspect then
|
|
return S("This is a signal with a variable aspect.")
|
|
elseif atdef.get_aspect then
|
|
return S("This is a signal with a static aspect.")
|
|
end
|
|
end
|
|
if ndef.at_conns then
|
|
return S("This track has the following conns table by default: @1", D.conns(ndef.at_conns) or "?")
|
|
end
|
|
return ""
|
|
end)
|
|
end
|
|
|
|
doc.add_category("advtrains_wagons", {
|
|
name = S("Wagons"),
|
|
build_formspec = doc_render_wagon_information,
|
|
})
|
|
end
|
|
|
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
if formname ~= "doc:entry" then
|
|
return
|
|
end
|
|
local pname = player:get_player_name()
|
|
local cat, ent = doc.get_selection(pname)
|
|
if cat ~= "advtrains_wagons" or ent == nil then
|
|
return
|
|
end
|
|
local act = fields.entry_body
|
|
local prototype = advtrains_doc_integration.prototypes[ent]
|
|
local sounds = {
|
|
["action:playhorn"] = prototype.horn_sound,
|
|
["action:playdooropen"] = prototype.doors.open.sound,
|
|
["action:playdoorclose"] = prototype.doors.close.sound,
|
|
}
|
|
if not act then
|
|
return
|
|
elseif sounds[act] then
|
|
minetest.sound_play(sounds[act], {to_player = pname}, true)
|
|
else
|
|
local txid = string.match(act, [[^action:preview_(%d+)$]])
|
|
txid = tonumber(txid)
|
|
if txid then
|
|
set_livery_preview_selection(pname, ent, txid)
|
|
doc.show_entry(pname, cat, ent)
|
|
end
|
|
end
|
|
end)
|