Basic route management from signalling formspec
parent
031aab4633
commit
e3667b630c
|
@ -122,13 +122,15 @@ TCB data structure
|
|||
ts_id = <id> -- ID of the assigned track section
|
||||
signal = <pos> -- optional: when set, routes can be set from this tcb/direction and signal
|
||||
-- aspect will be set accordingly.
|
||||
routetar = <signal> -- Route set from this signal. This is the entry that is cleared once
|
||||
routeset = <index in routes> -- Route set from this signal. This is the entry that is cleared once
|
||||
-- train has passed the signal. (which will set the aspect to "danger" again)
|
||||
route_committed = <boolean> -- When setting/requesting a route, routetar will be set accordingly,
|
||||
-- while the signal still displays danger and nothing is written to the TCs
|
||||
-- As soon as the route can actually be set, all relevant TCs and turnouts are set and this field
|
||||
-- is set true, clearing the signal
|
||||
aspect = <asp> -- The aspect the signal should show. If this is nil, should show the most restrictive aspect (red)
|
||||
signal_name = <string> -- The human-readable name of the signal, only for documenting purposes
|
||||
routes = { <route definition> } -- a collection of routes from this signal
|
||||
},
|
||||
[2] = { -- Variant: end of track-circuited area (initial state of TC)
|
||||
ts_id = nil, -- this is the indication for end_of_interlocking
|
||||
|
@ -263,6 +265,8 @@ end
|
|||
local function merge_ts(root_id, merge_id)
|
||||
local rts = ildb.get_ts(root_id)
|
||||
local mts = ildb.get_ts(merge_id)
|
||||
if not mts then return end -- This may be the case when sync_tcb_neighbors
|
||||
-- inserts the same id twice. do nothing.
|
||||
|
||||
-- cobble together the list of TCBs
|
||||
for _, msigd in ipairs(mts.tc_breaks) do
|
||||
|
@ -292,7 +296,7 @@ function ildb.sync_tcb_neighbors(pos, connid)
|
|||
end
|
||||
|
||||
atdebug("Traversing from ",pos, connid)
|
||||
local counter_hit = traverser(found_tcbs, pos, conns, connid, 0, hit_counter)
|
||||
local counter_hit = traverser(found_tcbs, pos, conns, connid, 0)
|
||||
|
||||
local ts_id
|
||||
local list_eoi = {}
|
||||
|
|
|
@ -126,6 +126,14 @@ end
|
|||
-- e.g. prog_<player> or vis<pts> for later visualizations
|
||||
function advtrains.interlocking.visualize_route(origin, route, context)
|
||||
advtrains.interlocking.clear_visu_context(context)
|
||||
|
||||
local oyaw = 0
|
||||
local onode_ok, oconns, orhe = advtrains.get_rail_info_at(origin.p, advtrains.all_tracktypes)
|
||||
if onode_ok then
|
||||
oyaw = advtrains.dir_to_angle(oconns[origin.s].c)
|
||||
end
|
||||
routemarker(context, origin.p, "rte_origin", "at_il_route_start.png", oyaw, route.name)
|
||||
|
||||
for k,sigd in ipairs(route.tcbpath) do
|
||||
local yaw = 0
|
||||
local node_ok, conns, rhe = advtrains.get_rail_info_at(sigd.p, advtrains.all_tracktypes)
|
||||
|
@ -154,7 +162,9 @@ function advtrains.interlocking.init_route_prog(pname, sigd)
|
|||
pcfix = {},
|
||||
}
|
||||
}
|
||||
advtrains.interlocking.visualize_route(sigd, player_rte_prog[pname].route, "prog_"..pname)
|
||||
minetest.chat_send_player(pname, "Route programming mode active. Punch TCBs to add route segments, punch turnouts to lock them.")
|
||||
minetest.chat_send_player(pname, "Type /at_rp_set <name> when you are done, /at_rp_discard to cancel route programming")
|
||||
end
|
||||
|
||||
local function get_last_route_item(origin, route)
|
||||
|
@ -255,9 +265,16 @@ minetest.register_chatcommand("at_rp_set",
|
|||
return false, "Cannot program route without a target"
|
||||
end
|
||||
rp.route.name = param
|
||||
-- TODO save that route somewhere in origin
|
||||
atdebug("ROUTE RESULT:",rp)
|
||||
|
||||
local tcbs = advtrains.interlocking.db.get_tcbs(rp.origin)
|
||||
if not tcbs then
|
||||
return false, "The origin TCB of this route doesn't exist!"
|
||||
end
|
||||
|
||||
table.insert(tcbs.routes, rp.route)
|
||||
|
||||
advtrains.interlocking.clear_visu_context("prog_"..pname)
|
||||
player_rte_prog[pname] = nil
|
||||
return true, "Successfully programmed route"
|
||||
end
|
||||
return false, "You were not programming a route!"
|
||||
|
|
|
@ -122,6 +122,8 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
|||
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||
if tcbs then
|
||||
tcbs.signal = pos
|
||||
tcbs.signal_name = "Signal at "..minetest.pos_to_string(sigd.p)
|
||||
tcbs.routes = {}
|
||||
advtrains.interlocking.db.set_sigd_for_signal(pos, sigd)
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Successfully assigned signal.")
|
||||
else
|
||||
|
@ -133,7 +135,7 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
|||
else
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Node is too far away. Aborted.")
|
||||
end
|
||||
players_assign_tcb[pname] = nil
|
||||
players_assign_signal[pname] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
|
@ -223,8 +225,13 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
end
|
||||
else
|
||||
if f_makeil[connid] then
|
||||
advtrains.interlocking.db.create_ts({p=pos, s=connid})
|
||||
-- try sinc_tcb_neighbors first
|
||||
advtrains.interlocking.db.sync_tcb_neighbors(pos, connid)
|
||||
-- if that didn't work, create new section
|
||||
if not tcbs.ts_id then
|
||||
advtrains.interlocking.db.create_ts({p=pos, s=connid})
|
||||
advtrains.interlocking.db.sync_tcb_neighbors(pos, connid)
|
||||
end
|
||||
end
|
||||
-- non-interlocked
|
||||
if f_setfree[connid] then
|
||||
|
@ -255,6 +262,9 @@ end)
|
|||
|
||||
-- TS Formspec
|
||||
|
||||
-- textlist selection temporary storage
|
||||
local ts_pselidx = {}
|
||||
|
||||
function advtrains.interlocking.show_ts_form(ts_id, pname, sel_tcb)
|
||||
local ts = advtrains.interlocking.db.get_ts(ts_id)
|
||||
if not ts_id then return end
|
||||
|
@ -304,6 +314,7 @@ function advtrains.interlocking.show_ts_form(ts_id, pname, sel_tcb)
|
|||
--form = form.."label[0.5,1;Trying to unlink a TCB directly connected to this track will not work.]"
|
||||
end
|
||||
|
||||
ts_pselidx[pname]=sel_tcb
|
||||
minetest.show_formspec(pname, "at_il_tsconfig_"..ts_id, form)
|
||||
|
||||
end
|
||||
|
@ -311,6 +322,10 @@ end
|
|||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
local pname = player:get_player_name()
|
||||
-- independent of the formspec, clear this whenever some formspec event happens
|
||||
local tpsi = ts_pselidx[pname]
|
||||
ts_pselidx[pname] = nil
|
||||
|
||||
local ts_id = string.match(formname, "^at_il_tsconfig_(.+)$")
|
||||
if ts_id and not fields.quit then
|
||||
local ts = advtrains.interlocking.db.get_ts(ts_id)
|
||||
|
@ -320,6 +335,9 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
if fields.tcblist then
|
||||
local tev = minetest.explode_textlist_event(fields.tcblist)
|
||||
sel_tcb = tev.index
|
||||
ts_pselidx[pname] = sel_tcb
|
||||
elseif tpsi then
|
||||
sel_tcb = tpsi
|
||||
end
|
||||
|
||||
if players_link_ts[pname] then
|
||||
|
@ -333,6 +351,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
|
||||
if fields.del_tcb and sel_tcb and sel_tcb > 0 and sel_tcb <= #ts.tc_breaks then
|
||||
advtrains.interlocking.db.remove_from_interlocking(ts.tc_breaks[sel_tcb])
|
||||
sel_tcb = nil
|
||||
end
|
||||
|
||||
if fields.link then
|
||||
|
@ -352,7 +371,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
end
|
||||
advtrains.interlocking.show_ts_form(ts_id, pname, sel_tcb)
|
||||
end
|
||||
|
||||
end)
|
||||
|
||||
-- TCB marker entities
|
||||
|
@ -420,21 +438,61 @@ end
|
|||
|
||||
-- Signalling formspec - set routes a.s.o
|
||||
|
||||
function advtrains.interlocking.show_signalling_form(sigd, pname)
|
||||
local form = "size[10,10]label[0.5,0.5;Track Section Detail - ]"
|
||||
form = form.."field[0.8,2;5.2,1;name;Section name;]"
|
||||
form = form.."button[5.5,1.7;1,1;setname;Set]"
|
||||
-- textlist selection temporary storage
|
||||
local sig_pselidx = {}
|
||||
|
||||
function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte)
|
||||
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||
|
||||
--minetest.show_formspec(pname, "at_il_signalling_"..sigd.p.."_"..sigd.s, form)
|
||||
--TODO this is temporary
|
||||
advtrains.interlocking.init_route_prog(pname, sigd)
|
||||
if not tcbs.signal then return end
|
||||
if not tcbs.signal_name then tcbs.signal_name = "Signal at "..minetest.pos_to_string(sigd.p) end
|
||||
if not tcbs.routes then tcbs.routes = {} end
|
||||
|
||||
local form = "size[7,9]label[0.5,0.5;Signal at "..minetest.pos_to_string(sigd.p).."]"
|
||||
form = form.."field[0.8,1.5;5.2,1;name;Signal name;"..tcbs.signal_name.."]"
|
||||
form = form.."button[5.5,1.2;1,1;setname;Set]"
|
||||
|
||||
if tcbs.routeset then
|
||||
local rte = tcbs.routes[tcbs.routeset]
|
||||
form = form.."label[0.5,2.5;A route is requested from this signal:]"
|
||||
form = form.."label[0.5,3.0;"..rte.name.."]"
|
||||
if tcbs.route_committed then
|
||||
form = form.."label[0.5,2.5;Route has been set.]"
|
||||
else
|
||||
form = form.."label[0.5,2.5;Waiting for route to be set...]"
|
||||
end
|
||||
|
||||
form = form.."button[0.5,6.5;1,6;cancelroute;Cancel Route]"
|
||||
else
|
||||
local strtab = {}
|
||||
for idx, route in ipairs(tcbs.routes) do
|
||||
strtab[#strtab+1] = minetest.formspec_escape(route.name)
|
||||
end
|
||||
form = form.."label[0.5,2.5;Routes:]"
|
||||
form = form.."textlist[0.5,3;5,3;rtelist;"..table.concat(strtab, ",").."]"
|
||||
if sel_rte then
|
||||
form = form.."button[0.5,6; 5,1;setroute;Set Route]"
|
||||
form = form.."button[0.5,7;2,1;dsproute;Show]"
|
||||
form = form.."button[2.5,7;1,1;delroute;Delete]"
|
||||
form = form.."button[3.5,7;2,1;renroute;Rename]"
|
||||
end
|
||||
form = form.."button[0.5,8;2.5,1;newroute;New Route]"
|
||||
form = form.."button[ 3,8;2.5,1;unassign;Unassign Signal]"
|
||||
|
||||
end
|
||||
sig_pselidx[pname] = sel_rte
|
||||
minetest.show_formspec(pname, "at_il_signalling_"..minetest.pos_to_string(sigd.p).."_"..sigd.s, form)
|
||||
end
|
||||
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
local pname = player:get_player_name()
|
||||
|
||||
-- independent of the formspec, clear this whenever some formspec event happens
|
||||
local tpsi = sig_pselidx[pname]
|
||||
sig_pselidx[pname] = nil
|
||||
|
||||
local pts, connids = string.match(formname, "^at_il_signalling_([^_]+)_(%d)$")
|
||||
local pts = string.match(formname, "^at_il_tcbconfig_(.+)$")
|
||||
local pos, connid
|
||||
if pts then
|
||||
pos = minetest.string_to_pos(pts)
|
||||
|
@ -442,8 +500,69 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
if not connid or connid<1 or connid>2 then return end
|
||||
end
|
||||
if pos and connid and not fields.quit then
|
||||
local sigd = {p=pos, s=connid}
|
||||
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||
if not tcbs then return end
|
||||
|
||||
advtrains.interlocking.show_signalling_form(ts_id, pname, sel_tcb)
|
||||
local sel_rte
|
||||
if fields.rtelist then
|
||||
local tev = minetest.explode_textlist_event(fields.rtelist)
|
||||
sel_rte = tev.index
|
||||
elseif tpsi then
|
||||
sel_rte = tpsi
|
||||
end
|
||||
if fields.setname and fields.name then
|
||||
tcbs.signal_name = fields.name
|
||||
end
|
||||
if tcbs.routeset and fields.cancelroute then
|
||||
--TODO
|
||||
end
|
||||
if not tcbs.routeset then
|
||||
if fields.newroute then
|
||||
advtrains.interlocking.init_route_prog(pname, sigd)
|
||||
minetest.close_formspec(pname, formname)
|
||||
return
|
||||
end
|
||||
if sel_rte and tcbs.routes[sel_rte] then
|
||||
if fields.setroute then
|
||||
--TODO
|
||||
end
|
||||
if fields.dsproute then
|
||||
local t = os.clock()
|
||||
advtrains.interlocking.visualize_route(sigd, tcbs.routes[sel_rte], "disp_"..t)
|
||||
minetest.after(10, function() advtrains.interlocking.clear_visu_context("disp_"..t) end)
|
||||
end
|
||||
if fields.renroute then
|
||||
local rte = tcbs.routes[sel_rte]
|
||||
minetest.show_formspec(pname, formname.."_renroute_"..sel_rte, "field[name;Enter new route name;"..rte.name.."]")
|
||||
return
|
||||
end
|
||||
if fields.delroute then
|
||||
table.remove(tcbs.routes, sel_rte)
|
||||
sel_rte = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte)
|
||||
return
|
||||
end
|
||||
|
||||
-- rename route
|
||||
local rind, rte_id
|
||||
pts, connids, rind = string.match(formname, "^at_il_signalling_([^_]+)_(%d)_renroute_(%d+)$")
|
||||
if pts then
|
||||
pos = minetest.string_to_pos(pts)
|
||||
connid = tonumber(connids)
|
||||
rte_id = tonumber(rind)
|
||||
if not connid or connid<1 or connid>2 then return end
|
||||
end
|
||||
if pos and connid and rind and fields.name then
|
||||
local sigd = {p=pos, s=connid}
|
||||
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||
if tcbs.routes[rte_id] then
|
||||
tcbs.routes[rte_id].name = fields.name
|
||||
advtrains.interlocking.show_signalling_form(sigd, pname)
|
||||
end
|
||||
end
|
||||
|
||||
end)
|
||||
|
|
Loading…
Reference in New Issue