From aee7f0d4198c441c3dd4cb5d33f488607a1a81a5 Mon Sep 17 00:00:00 2001 From: orwell96 Date: Thu, 30 Jan 2020 13:59:46 +0100 Subject: Fix things, rework signal aspect select dialog, transform old aspects on-the-fly --- advtrains/signals.lua | 6 +- advtrains/trainlogic.lua | 2 +- advtrains_interlocking/approach.lua | 5 +- advtrains_interlocking/database.lua | 33 ++++++ advtrains_interlocking/demosignals.lua | 2 +- advtrains_interlocking/route_prog.lua | 3 +- advtrains_interlocking/route_ui.lua | 2 +- advtrains_interlocking/routesetting.lua | 9 +- advtrains_interlocking/signal_api.lua | 188 +++++++++++++++----------------- advtrains_luaautomation/README.txt | 20 ++-- advtrains_signals_ks/init.lua | 2 +- 11 files changed, 142 insertions(+), 130 deletions(-) diff --git a/advtrains/signals.lua b/advtrains/signals.lua index 1940518..68cbc70 100644 --- a/advtrains/signals.lua +++ b/advtrains/signals.lua @@ -73,7 +73,7 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red", -- new signal API advtrains = { set_aspect = function(pos, node, asp) - if asp.main != 0 then + if asp.main ~= 0 then advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_on"..rotation, param2 = node.param2}, true) else advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_off"..rotation, param2 = node.param2}, true) @@ -132,7 +132,7 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red", -- new signal API advtrains = { set_aspect = function(pos, node, asp) - if asp.main != 0 then + if asp.main ~= 0 then advtrains.ndb.swap_node(pos, {name = "advtrains:signal_on"..rotation, param2 = node.param2}, true) else advtrains.ndb.swap_node(pos, {name = "advtrains:signal_off"..rotation, param2 = node.param2}, true) @@ -200,7 +200,7 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red", -- new signal API advtrains = { set_aspect = function(pos, node, asp) - if asp.main != 0 then + if asp.main ~= 0 then advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_on", param2 = node.param2}, true) else advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_off", param2 = node.param2}, true) diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua index fa7a40e..be0d60e 100644 --- a/advtrains/trainlogic.lua +++ b/advtrains/trainlogic.lua @@ -417,7 +417,7 @@ function advtrains.train_step_b(id, train, dtime) if emerg then v_target_apply(v_targets, VLEVER_EMERG, 0) else - v_target_apply(v_targets, VLEVER_EMERG, braketar) + v_target_apply(v_targets, VLEVER_BRAKE, braketar) end else v_target_apply(v_targets, VLEVER_ROLL, train.tarvelocity) diff --git a/advtrains_interlocking/approach.lua b/advtrains_interlocking/approach.lua index 151f15a..14a31ce 100644 --- a/advtrains_interlocking/approach.lua +++ b/advtrains_interlocking/approach.lua @@ -75,13 +75,13 @@ advtrains.tnc_register_on_approach(function(pos, id, train, index, has_entered, --shunt move if asp.shunt then nspd = SHUNT_SPEED_MAX - elseif asp.shunt.proceed_as_main and asp.main != 0 then + elseif asp.proceed_as_main and asp.main ~= 0 then nspd = asp.main travsht = false end else --train move - if asp.main != 0 then + if asp.main ~= 0 then nspd = asp.main elseif asp.shunt then nspd = SHUNT_SPEED_MAX @@ -98,6 +98,7 @@ advtrains.tnc_register_on_approach(function(pos, id, train, index, has_entered, end --atdebug("ns,ts", nspd, travspd) + lspd = travspd local udata = {signal_pos = spos} diff --git a/advtrains_interlocking/database.lua b/advtrains_interlocking/database.lua index 82c7e25..68d4138 100644 --- a/advtrains_interlocking/database.lua +++ b/advtrains_interlocking/database.lua @@ -131,6 +131,37 @@ function ildb.load(data) if data.npr_rails then advtrains.interlocking.npr_rails = data.npr_rails end + + --COMPATIBILITY to Signal aspect format + -- TODO remove in time... + for pts,tcb in pairs(track_circuit_breaks) do + for connid, tcbs in ipairs(tcb) do + if tcbs.routes then + for _,route in ipairs(tcbs.routes) do + if route.aspect then + -- transform the signal aspect format + local asp = route.aspect + if type(asp.main) == "table" then + atwarn("Transforming route aspect of signal",pts,"/",connid,"") + if asp.main.free then + asp.main = asp.main.speed + else + asp.main = 0 + end + if asp.dst.free then + asp.dst = asp.dst.speed + else + asp.dst = 0 + end + asp.proceed_as_main = asp.shunt.proceed_as_main + asp.shunt = asp.shunt.free + -- Note: info table not transferred, it's not used right now + end + end + end + end + end + end end function ildb.save() @@ -149,6 +180,7 @@ end --[[ TCB data structure { +-- This is the "A" side of the TCB [1] = { -- Variant: with adjacent TCs. ts_id = -- ID of the assigned track section signal = -- optional: when set, routes can be set from this tcb/direction and signal @@ -164,6 +196,7 @@ TCB data structure routes = { } -- a collection of routes from this signal route_auto = -- When set, we will automatically re-set the route (designated by routeset) }, +-- This is the "B" side of the TCB [2] = { -- Variant: end of track-circuited area (initial state of TC) ts_id = nil, -- this is the indication for end_of_interlocking section_free = , --this can be set by an exit node via mesecons or atlatc, diff --git a/advtrains_interlocking/demosignals.lua b/advtrains_interlocking/demosignals.lua index d5e1065..fe60a73 100644 --- a/advtrains_interlocking/demosignals.lua +++ b/advtrains_interlocking/demosignals.lua @@ -9,7 +9,7 @@ local setaspect = function(pos, node, asp) if asp.main == 0 then advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_danger"}) else - if asp.dst != 0 and asp.main == -1 then + if asp.dst ~= 0 and asp.main == -1 then advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_free"}) else advtrains.ndb.swap_node(pos, {name="advtrains_interlocking:ds_slow"}) diff --git a/advtrains_interlocking/route_prog.lua b/advtrains_interlocking/route_prog.lua index eadfd93..6abe431 100644 --- a/advtrains_interlocking/route_prog.lua +++ b/advtrains_interlocking/route_prog.lua @@ -112,7 +112,8 @@ route = { next = , -- of the next (note: next) TCB on the route locks = { = "state"} -- route locks of this route segment } - terminal = + terminal = , + aspect = ,--note, might change in future } The first item in the TCB path (namely i=0) is always the start signal of this route, so this is left out. diff --git a/advtrains_interlocking/route_ui.lua b/advtrains_interlocking/route_ui.lua index 71fed09..64e45ee 100644 --- a/advtrains_interlocking/route_ui.lua +++ b/advtrains_interlocking/route_ui.lua @@ -129,7 +129,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) advtrains.interlocking.show_route_edit_form(pname, sigd, routeid) end - advtrains.interlocking.show_signal_aspect_selector(pname, suppasp, route.name, callback, route.aspect) + advtrains.interlocking.show_signal_aspect_selector(pname, suppasp, route.name, callback, route.aspect or advtrains.interlocking.GENERIC_FREE) return end if fields.delete then diff --git a/advtrains_interlocking/routesetting.lua b/advtrains_interlocking/routesetting.lua index f235ce6..67efaea 100644 --- a/advtrains_interlocking/routesetting.lua +++ b/advtrains_interlocking/routesetting.lua @@ -6,13 +6,6 @@ local function sigd_to_string(sigd) return minetest.pos_to_string(sigd.p).." / "..lntrans[sigd.s] end -local asp_generic_free = { - main = -1, - shunt = false, - dst = false, - info = {} -} - local ildb = advtrains.interlocking.db local ilrs = {} @@ -119,7 +112,7 @@ function ilrs.set_route(signal, route, try) } if c_tcbs.signal then c_tcbs.route_committed = true - c_tcbs.aspect = route.aspect or asp_generic_free + c_tcbs.aspect = route.aspect or advtrains.interlocking.GENERIC_FREE c_tcbs.route_origin = signal advtrains.interlocking.update_signal_aspect(c_tcbs) end diff --git a/advtrains_interlocking/signal_api.lua b/advtrains_interlocking/signal_api.lua index c419e72..7e280ad 100644 --- a/advtrains_interlocking/signal_api.lua +++ b/advtrains_interlocking/signal_api.lua @@ -31,16 +31,15 @@ asp = { -- -1 = section is free, maximum speed permitted -- false = Signal doesn't provide distant signal information. - info = { - -- the character of call_on and dead_end is purely informative - call_on = , -- Call-on route, expect train in track ahead (not implemented yet) - dead_end = , -- Route ends on a dead end (e.g. bumper) (not implemented yet) - - w_speed = , - -- "Warning speed restriction". Supposed for short-term speed - -- restrictions which always override any other restrictions - -- imposed by "speed" fields, until lifted by a value of -1 - -- (Example: german Langsamfahrstellen-Signale) + -- the character of call_on and dead_end is purely informative + call_on = , -- Call-on route, expect train in track ahead (not implemented yet) + dead_end = , -- Route ends on a dead end (e.g. bumper) (not implemented yet) + + w_speed = , + -- "Warning speed restriction". Supposed for short-term speed + -- restrictions which always override any other restrictions + -- imposed by "speed" fields, until lifted by a value of -1 + -- (Example: german Langsamfahrstellen-Signale) } } @@ -103,11 +102,9 @@ advtrains = { dst = {, ..., } or nil, shunt = , - info = { - call_on = , - dead_end = , - w_speed = {, ..., } or nil, - } + call_on = , + dead_end = , + w_speed = {, ..., } or nil, }, Example for supported_aspects: @@ -116,11 +113,10 @@ advtrains = { dst = {0, false}, -- can show only if next signal shows "blocked", no other information. shunt = false, -- shunting by this signal is never allowed. - info = { - call_on = false, - dead_end = false, - w_speed = nil, - } -- none of the information can be shown by the signal + call_on = false, + dead_end = false, + w_speed = nil, + -- none of the information can be shown by the signal }, @@ -166,14 +162,34 @@ local DANGER = { main = 0, dst = false, shunt = false, - info = {} } advtrains.interlocking.DANGER = DANGER -local function fillout_aspect(asp) - if not asp.info then - asp.info = {} +advtrains.interlocking.GENERIC_FREE = { + main = -1, + shunt = false, + dst = false, +} + +local function convert_aspect_if_necessary(asp) + if type(asp.main) == "table" then + local newasp = {} + if asp.main.free then + newasp.main = asp.main.speed + else + newasp.main = 0 + end + if asp.dst.free then + newasp.dst = asp.dst.speed + else + newasp.dst = 0 + end + newasp.proceed_as_main = asp.shunt.proceed_as_main + newasp.shunt = asp.shunt.free + -- Note: info table not transferred, it's not used right now + return newasp end + return asp end function advtrains.interlocking.update_signal_aspect(tcbs) @@ -193,7 +209,7 @@ function advtrains.interlocking.signal_after_dig(pos) end function advtrains.interlocking.signal_set_aspect(pos, asp) - fillout_aspect(asp) + asp = convert_aspect_if_necessary(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 @@ -226,7 +242,16 @@ function advtrains.interlocking.signal_rc_handler(pos, node, player, itemstack, local ndef = minetest.registered_nodes[node.name] if ndef.advtrains and ndef.advtrains.set_aspect then -- permit to set aspect manually - minetest.show_formspec(pname, "at_il_sigasp_"..minetest.pos_to_string(pos), "field[aspect;Set Aspect ('A' to assign IP);D0D0D]") + local function callback(pname, aspect) + ndef.advtrains.set_aspect(pos, node, aspect) + end + local isasp = ndef.advtrains.get_aspect(pos, node) + + advtrains.interlocking.show_signal_aspect_selector( + pname, + ndef.advtrains.supported_aspects, + "Set aspect manually", callback, + isasp) else --static signal - only IP advtrains.interlocking.show_ip_form(pos, pname) @@ -234,45 +259,13 @@ function advtrains.interlocking.signal_rc_handler(pos, node, player, itemstack, end end -minetest.register_on_player_receive_fields(function(player, formname, fields) - local pname = player:get_player_name() - local pts = string.match(formname, "^at_il_sigasp_(.+)$") - local pos - if pts then pos = minetest.string_to_pos(pts) end - if pos and fields.aspect then - if fields.aspect == "A" then - advtrains.interlocking.show_ip_form(pos, pname) - return - end - local mfs, msps, dfs, dsps, shs = string.match(fields.aspect, "^([FD])([-0-9]+)([FD])([-0-9]+)([FD])$") - local asp = { - main = { - free = mfs=="F", - speed = tonumber(msps), - }, - shunt = { - free = shs=="F", - }, - dst = { - free = dfs=="F", - speed = tonumber(dsps), - }, - info = { - call_on = false, -- Call-on route, expect train in track ahead - dead_end = false, -- Route ends on a dead end (e.g. bumper) - } - } - advtrains.interlocking.signal_set_aspect(pos, asp) - end -end) - -- Returns the aspect the signal at pos is supposed to show function advtrains.interlocking.signal_get_supposed_aspect(pos) local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos) if sigd then local tcbs = advtrains.interlocking.db.get_tcbs(sigd) if tcbs.aspect then - return tcbs.aspect + return convert_aspect_if_necessary(tcbs.aspect) end end return DANGER; @@ -286,8 +279,7 @@ function advtrains.interlocking.signal_get_aspect(pos) if ndef and ndef.advtrains and ndef.advtrains.get_aspect then local asp = ndef.advtrains.get_aspect(pos, node) if not asp then asp = DANGER end - fillout_aspect(asp) - return asp + return convert_aspect_if_necessary(asp) end return nil end @@ -421,44 +413,45 @@ local players_aspsel = {} suppasp: "supported_aspects" table purpose: form title string callback: func(pname, aspect) called on form submit +isasp: aspect currently set ]] -function advtrains.interlocking.show_signal_aspect_selector(pname, p_suppasp, p_purpose, callback, p_isasp) +function advtrains.interlocking.show_signal_aspect_selector(pname, p_suppasp, p_purpose, callback, isasp) local suppasp = p_suppasp or { - main = {}, dst = {}, shunt = {}, info = {}, + main = {0, -1}, dst = {false}, shunt = false, info = {}, } local purpose = p_purpose or "" - local isasp = p_isasp and fillout_aspect(p_isasp) local form = "size[7,5]label[0.5,0.5;Select Signal Aspect:]" form = form.."label[0.5,1;"..purpose.."]" - - --TODO form = form.."label[0.5,1.5;== Main Signal ==]" - if suppasp.main == 0 then - local st = 2 - if isasp and not isasp.main.free then st=1 end - form = form.."dropdown[0.5,2;2;main_free;danger,free;"..st.."]" - end - if suppasp.main.speed then - local selid = 1 - if isasp and isasp.main.speed then - for idx, spv in ipairs(suppasp.main.speed) do - if spv == isasp.main.speed then - selid = idx - break - end - end + local selid = 1 + local entries = {} + for idx, spv in ipairs(suppasp.main) do + local entry + if spv == 0 then + entry = "Halt" + elseif spv == -1 then + entry = "Continue at maximum speed" + elseif not spv then + entry = "Continue\\, speed limit unchanged (no info)" + else + entry = "Continue at speed of "..spv + end + -- hack: the crappy formspec system returns the label, not the index. save the index in it. + entries[idx] = idx.."| "..entry + if isasp and spv == (isasp.main or false) then + selid = idx end - form = form.."label[2.3,1;Speed:]" - form = form.."dropdown[3,2;2;main_speed;"..table.concat(suppasp.main.speed, ",")..";"..selid.."]" end + form = form.."dropdown[0.5,2;6;main;"..table.concat(entries, ",")..";"..selid.."]" + form = form.."label[0.5,3;== Shunting ==]" - if suppasp.shunt.free == nil then + if suppasp.shunt == nil then local st = 1 - if isasp and isasp.shunt.free then st=2 end - form = form.."dropdown[0.5,3.5;2;shunt_free;---,allowed;"..st.."]" + if isasp and isasp.shunt then st=2 end + form = form.."dropdown[0.5,3.5;6;shunt_free;---,allowed;"..st.."]" end form = form.."button_exit[0.5,4.5; 5,1;save;OK]" @@ -483,12 +476,10 @@ local function usebool(sup, val, free) return sup end end -local function usespeed(sup, val) - if sup then - return tonumber(val) - else - return nil - end + +-- other side of hack: extract the index +local function ddindex(val) + return tonumber(string.match(val, "^(%d+)|")) end -- TODO use non-hacky way to parse outputs @@ -499,17 +490,12 @@ minetest.register_on_player_receive_fields(function(player, formname, fields) if psl then if formname == "at_il_sigaspdia_"..psl.token then if fields.save then + local maini = ddindex(fields.main) + if not maini then return end local asp = { - main = { - free = usebool(psl.suppasp.main.free, fields.main_free, "free"), - speed = usespeed(psl.suppasp.main.speed, fields.main_speed), - }, - dst = { - free = true, speed = -1, - }, - shunt = { - free = usebool(psl.suppasp.shunt.free, fields.shunt_free, "allowed"), - }, + main = psl.suppasp.main[maini], + dst = false, + shunt = usebool(psl.suppasp.shunt, fields.shunt_free, "allowed"), info = {} } psl.callback(pname, asp) diff --git a/advtrains_luaautomation/README.txt b/advtrains_luaautomation/README.txt index 952efad..177bbc9 100644 --- a/advtrains_luaautomation/README.txt +++ b/advtrains_luaautomation/README.txt @@ -123,17 +123,15 @@ asp = { -- -1 = section is free, maximum speed permitted -- false = Signal doesn't provide distant signal information. - info = { - -- the character of call_on and dead_end is purely informative - call_on = , -- Call-on route, expect train in track ahead (not implemented yet) - dead_end = , -- Route ends on a dead end (e.g. bumper) (not implemented yet) - - w_speed = , - -- "Warning speed restriction". Supposed for short-term speed - -- restrictions which always override any other restrictions - -- imposed by "speed" fields, until lifted by a value of -1 - -- (Example: german Langsamfahrstellen-Signale) - } + -- the character of call_on and dead_end is purely informative + call_on = , -- Call-on route, expect train in track ahead (not implemented yet) + dead_end = , -- Route ends on a dead end (e.g. bumper) (not implemented yet) + + w_speed = , + -- "Warning speed restriction". Supposed for short-term speed + -- restrictions which always override any other restrictions + -- imposed by "speed" fields, until lifted by a value of -1 + -- (Example: german Langsamfahrstellen-Signale) } As of January 2020, the 'dst', 'call_on' and 'dead_end' fields are not used. diff --git a/advtrains_signals_ks/init.lua b/advtrains_signals_ks/init.lua index deceb33..3559d51 100644 --- a/advtrains_signals_ks/init.lua +++ b/advtrains_signals_ks/init.lua @@ -13,7 +13,7 @@ local setaspectf = function(rot) advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_danger_"..rot, param2 = node.param2}) end else - if asp.dst != 0 and asp.main == -1 then + if asp.dst ~= 0 and asp.main == -1 then advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_free_"..rot, param2 = node.param2}) else advtrains.ndb.swap_node(pos, {name="advtrains_signals_ks:hs_slow_"..rot, param2 = node.param2}) -- cgit v1.2.3