aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorY. Wang <yw05@forksworld.de>2022-04-13 12:54:58 +0200
committerY. Wang <yw05@forksworld.de>2022-04-13 15:50:05 +0200
commitd794e382b59bb42888f3fb9b1d61f6ac6f7e2bdb (patch)
treef6515492f8fb4c614acd29e7c733b7058b33a02a
parent2f1be2b03e98713ee496da336b8264cdbc8c19b4 (diff)
downloadadvtrains-d794e382b59bb42888f3fb9b1d61f6ac6f7e2bdb.tar.gz
advtrains-d794e382b59bb42888f3fb9b1d61f6ac6f7e2bdb.tar.bz2
advtrains-d794e382b59bb42888f3fb9b1d61f6ac6f7e2bdb.zip
Primitive (not fully tested) support for route signaling
-rw-r--r--advtrains_interlocking/init.lua2
-rw-r--r--advtrains_interlocking/signal_api.lua13
-rw-r--r--advtrains_interlocking/signal_aspect_ui.lua51
-rw-r--r--advtrains_interlocking/signal_aspects.lua102
-rw-r--r--advtrains_signals_japan/init.lua49
5 files changed, 198 insertions, 19 deletions
diff --git a/advtrains_interlocking/init.lua b/advtrains_interlocking/init.lua
index a5bf41e..d0b75a8 100644
--- a/advtrains_interlocking/init.lua
+++ b/advtrains_interlocking/init.lua
@@ -12,6 +12,8 @@ end
local modpath = minetest.get_modpath(minetest.get_current_modname()) .. DIR_DELIM
+advtrains.interlocking.aspects = dofile(modpath.."signal_aspects.lua")
+
dofile(modpath.."database.lua")
dofile(modpath.."signal_api.lua")
dofile(modpath.."signal_aspect_ui.lua")
diff --git a/advtrains_interlocking/signal_api.lua b/advtrains_interlocking/signal_api.lua
index 78acc0a..e4b2993 100644
--- a/advtrains_interlocking/signal_api.lua
+++ b/advtrains_interlocking/signal_api.lua
@@ -220,6 +220,10 @@ function advtrains.interlocking.signal_set_aspect(pos, asp)
local node=advtrains.ndb.get_node(pos)
local ndef=minetest.registered_nodes[node.name]
if ndef and ndef.advtrains and ndef.advtrains.set_aspect then
+ local suppasp = advtrains.interlocking.signal_get_supported_aspects(pos)
+ if suppasp.type == 2 then
+ asp = advtrains.interlocking.aspects.type1_to_type2main(asp, suppasp.group)
+ end
ndef.advtrains.set_aspect(pos, node, asp)
advtrains.interlocking.signal_on_aspect_changed(pos)
end
@@ -252,7 +256,7 @@ function advtrains.interlocking.signal_rc_handler(pos, node, player, itemstack,
local function callback(pname, aspect)
advtrains.interlocking.signal_set_aspect(pos, aspect)
end
- local isasp = ndef.advtrains.get_aspect(pos, node)
+ local isasp = advtrains.interlocking.signal_get_aspect(pos, node)
advtrains.interlocking.show_signal_aspect_selector(
pname,
@@ -285,8 +289,13 @@ function advtrains.interlocking.signal_get_aspect(pos)
local ndef=minetest.registered_nodes[node.name]
if ndef and ndef.advtrains and ndef.advtrains.get_aspect then
local asp = ndef.advtrains.get_aspect(pos, node)
+ local suppasp = advtrains.interlocking.signal_get_supported_aspects(pos)
+ if suppasp.type == 2 then
+ asp = advtrains.interlocking.aspects.type2main_to_type1(suppasp.group, asp)
+ end
if not asp then asp = DANGER end
- return convert_aspect_if_necessary(asp)
+ asp = convert_aspect_if_necessary(asp)
+ return asp
end
return nil
end
diff --git a/advtrains_interlocking/signal_aspect_ui.lua b/advtrains_interlocking/signal_aspect_ui.lua
index d5a7543..472155a 100644
--- a/advtrains_interlocking/signal_aspect_ui.lua
+++ b/advtrains_interlocking/signal_aspect_ui.lua
@@ -2,7 +2,7 @@ local F = advtrains.formspec
local players_aspsel = {}
local function make_signal_aspect_selector_t1(suppasp, purpose, isasp)
- local form = {"size[7,7]"}
+ local form = {"size[7,7.5]"}
form[#form+1] = F.S_label(0.5, 0.5, "Select signal aspect")
form[#form+1] = F.label(0.5, 1, purpose)
@@ -59,7 +59,29 @@ local function make_signal_aspect_selector_t1(suppasp, purpose, isasp)
end
form[#form+1] = F.dropdown(0.5, 5, 6, "dst", entries, selid, true)
- form[#form+1] = F.S_button_exit(0.5, 6, 5, 1, "save", "Save signal aspect")
+ form[#form+1] = F.S_button_exit(0.5, 6, 6, 1, "save", "Save signal aspect")
+ return table.concat(form)
+end
+
+local function make_signal_aspect_selector_t2(suppasp, purpose, isasp)
+ local form = {"size[7,4]"}
+ local def = advtrains.interlocking.aspects.get_type2_definition(suppasp.group)
+ if not def then
+ return nil
+ end
+ form[#form+1] = F.S_label(0.5, 0.5, "Select signal aspect")
+ form[#form+1] = F.label(0.5, 1, purpose)
+
+ local entries = {}
+ local selid = 1
+ for idx, spv in ipairs(def.main) do
+ if isasp and isasp.type2name == spv.name then
+ selid = idx
+ end
+ entries[idx] = spv.label
+ end
+ form[#form+1] = F.dropdown(0.5, 1.5, 6, "asp", entries, selid, true)
+ form[#form+1] = F.S_button_exit(0.5, 2.5, 6, 1, "save", "Save signal aspect")
return table.concat(form)
end
@@ -73,9 +95,14 @@ function advtrains.interlocking.show_signal_aspect_selector(pname, p_suppasp, p_
local purpose = p_purpose or ""
local form
- if true then
+ if suppasp.type == 2 then
+ form = make_signal_aspect_selector_t2(suppasp, purpose, isasp)
+ else
form = make_signal_aspect_selector_t1(suppasp, purpose, isasp)
end
+ if not form then
+ return
+ end
local token = advtrains.random_id()
minetest.show_formspec(pname, "at_il_sigaspdia_"..token, form)
@@ -107,18 +134,26 @@ local function get_aspect_from_formspec_t1(suppasp, fields)
}
end
+local function get_aspect_from_formspec_t2(suppasp, fields)
+ local asp = advtrains.interlocking.aspects.type2main_to_type1(suppasp.group, tonumber(fields.asp))
+ return asp
+end
+
minetest.register_on_player_receive_fields(function(player, formname, fields)
local pname = player:get_player_name()
local psl = players_aspsel[pname]
if psl then
if formname == "at_il_sigaspdia_"..psl.token then
+ local suppasp = psl.suppasp
if fields.save then
local asp
- if true then
- asp = get_aspect_from_formspec_t1(psl.suppasp, fields)
- if asp then
- psl.callback(pname, asp)
- end
+ if suppasp.type == 2 then
+ asp = get_aspect_from_formspec_t2(suppasp, fields)
+ else
+ asp = get_aspect_from_formspec_t1(suppasp, fields)
+ end
+ if asp then
+ psl.callback(pname, asp)
end
end
else
diff --git a/advtrains_interlocking/signal_aspects.lua b/advtrains_interlocking/signal_aspects.lua
new file mode 100644
index 0000000..e604f9b
--- /dev/null
+++ b/advtrains_interlocking/signal_aspects.lua
@@ -0,0 +1,102 @@
+type2defs = {}
+
+local function register_type2(def)
+ local t = {type = 2}
+ local name = def.name
+ if type2defs[name] then
+ return error("Name " .. name .. " already used")
+ elseif type(name) ~= "string" then
+ return error("Name is not a string")
+ end
+ t.name = name
+
+ local label = def.label or name
+ if type(label) ~= "string" then
+ return error("Label is not a string")
+ end
+ t.label = label
+
+ local mainasps = {}
+ for idx, asp in ipairs(def.main) do
+ local t = {}
+ local name = asp.name
+ if type(name) ~= "string" then
+ return error("Aspect name is not a string")
+ end
+ t.name = name
+
+ local label = asp.label or name
+ if type(label) ~= "string" then
+ return error("Aspect label is not a string")
+ end
+ t.label = label
+
+ t.main = asp.main
+ mainasps[idx] = t
+ mainasps[name] = idx
+ end
+ t.main = mainasps
+
+ type2defs[name] = t
+end
+
+local function get_type2_definition(name)
+ return type2defs[name]
+end
+
+local function type2main_to_type1(name, asp)
+ local def = type2defs[name]
+ if not def then
+ return nil
+ end
+ local aspidx
+ if type(asp) == "number" then
+ aspidx = asp
+ else
+ aspidx = def.main[asp]
+ end
+ local asptbl = def.main[aspidx]
+ if not asptbl then
+ return nil
+ end
+ if type(asp) == "number" then
+ asp = asptbl.name
+ end
+
+ local t = {
+ main = asptbl.main,
+ type2name = asp,
+ type2group = name,
+ }
+ if aspidx ~= 1 and aspidx ~= #asptbl then
+ t.dst = def.main[aspidx+1].main
+ end
+ return t
+end
+
+local function type1_to_type2main(asp, group)
+ local def = type2defs[group]
+ if not def then
+ return nil
+ end
+ if group == asp.type2group and def.main[asp.type2name] then
+ return asp.type2name
+ end
+ local t_main = def.main
+ local idx
+ if not asp.main or asp.main == -1 then
+ idx = 1
+ elseif asp.main == 0 then
+ idx = #t_main
+ else
+ idx = math.max(#t_main-1, 1)
+ end
+ return t_main[idx].name
+end
+
+return {
+ register_type2 = register_type2,
+ get_type2_definition = get_type2_definition,
+ type2main_to_type1 = type2main_to_type1,
+ type1_to_type2main = type1_to_type2main,
+}
diff --git a/advtrains_signals_japan/init.lua b/advtrains_signals_japan/init.lua
index a546847..7b11d85 100644
--- a/advtrains_signals_japan/init.lua
+++ b/advtrains_signals_japan/init.lua
@@ -278,14 +278,26 @@ minetest.register_node("advtrains_signals_japan:pole_0", {
local sigdefs = {}
local lightcolors = {
red = "red",
- green = "green",
+ green = "lime",
yellow = "orange",
distant = "purple",
}
-local function process_signal(sigdata, isrpt)
+local aspnames = {
+ danger = "Danger (halt)",
+ restrictedspeed = "Restricted speed",
+ caution = "Caution",
+ reducedspeed = "Reduced speed",
+ clear = "Clear (proceed)",
+}
+local function process_signal(name, sigdata, isrpt)
+ local typename = "advtrains_signals_japan:" .. name
+ local type2def = {}
+ type2def.name = typename
+ type2def.main = {}
local def = {}
local tx = {}
local invimg = {}
+ def.typename = typename
def.textures = tx
def.inventory_images = invimg
def.desc = sigdata.desc
@@ -296,7 +308,7 @@ local function process_signal(sigdata, isrpt)
lightcount = lightcount+1
end
def.lightcount = lightcount
- for _, asp in pairs(sigdata.aspects) do
+ for idx, asp in ipairs(sigdata.aspects) do
local aspname = asp.name
local tt = {
string.format("[combine:1x%d", lightcount),
@@ -318,6 +330,10 @@ local function process_signal(sigdata, isrpt)
end
tx[aspname] = table.concat(tt, ":")
invimg[aspname] = table.concat(it, ":")
+ type2def.main[idx] = {name = asp.name, label = S(aspnames[asp.name]), main = asp.main or false}
+ end
+ if not isrpt then
+ advtrains.interlocking.aspects.register_type2(type2def)
end
return def
end
@@ -326,16 +342,16 @@ for sigtype, sigdata in pairs {
desc = "5A",
lights = {"yellow", "yellow", "red", "yellow", "green"},
aspects = {
- {name = "danger", lights = {3}},
+ {name = "danger", lights = {3}, main = 0},
{name = "restrictedspeed", lights = {1, 3}},
{name = "caution", lights = {4}},
{name = "reducedspeed", lights = {2, 5}},
- {name = "clear", lights = {5}},
+ {name = "clear", lights = {5}, main = -1},
}
}
} do
- sigdefs["main_"..sigtype] = process_signal(sigdata)
- sigdefs["rpt_"..sigtype] = process_signal(sigdata, true)
+ sigdefs["main_"..sigtype] = process_signal(sigtype, sigdata)
+ sigdefs["rpt_"..sigtype] = process_signal(sigtype, sigdata, true)
end
for k in pairs(sigdefs) do
@@ -371,13 +387,28 @@ for _, rtab in ipairs {
},
groups = {
cracky = 2,
- --advtrains_signal = 1,
+ advtrains_signal = 1,
not_blocking_trains = 1,
- --save_in_at_nodedb = 1,
+ save_in_at_nodedb = 1,
not_in_creative_inventory = rtab.ici and 0 or 1,
},
inventory_image = siginfo.inventory_images[asp],
drop = "advtrains_signals_japan:"..sigtype.."_danger_0",
+ advtrains = {
+ supported_aspects = {
+ type = 2,
+ group = siginfo.typename,
+ },
+ get_aspect = function()
+ return asp
+ end,
+ set_aspect = function(pos, node, asp)
+ advtrains.ndb.swap_node(pos, {name = "advtrains_signals_japan:"..sigtype.."_"..asp.."_"..rot, param2 = node.param2})
+ end,
+ },
+ on_rightclick = advtrains.interlocking.signal_rc_handler,
+ can_dig = advtrains.interlocking.signal_can_dig,
+ after_dig_node = advtrains.interlocking.signal_after_dig,
})
advtrains.trackplacer.add_worked("advtrains_signals_japan:"..sigtype, asp, "_"..rot)
end