Signal assignment and route programming procedure
|
@ -133,7 +133,9 @@ end
|
|||
|
||||
|
||||
function ndb.swap_node(pos, node, no_inval)
|
||||
minetest.swap_node(pos, node)
|
||||
if minetest.get_node_or_nil(pos) then
|
||||
minetest.swap_node(pos, node)
|
||||
end
|
||||
ndb.update(pos, node)
|
||||
end
|
||||
|
||||
|
@ -294,6 +296,5 @@ minetest.register_chatcommand("at_sync_ndb",
|
|||
return true, text
|
||||
end)
|
||||
end,
|
||||
privs = {train_operator=true}, -- Require the "privs" privilege to run
|
||||
})
|
||||
|
||||
|
|
|
@ -95,6 +95,8 @@ local ildb = {}
|
|||
local track_circuit_breaks = {}
|
||||
local track_sections = {}
|
||||
|
||||
local signal_assignments = {}
|
||||
|
||||
function ildb.load(data)
|
||||
if not data then return end
|
||||
if data.tcbs then
|
||||
|
@ -103,10 +105,13 @@ function ildb.load(data)
|
|||
if data.ts then
|
||||
track_sections = data.ts
|
||||
end
|
||||
if data.signalass then
|
||||
signal_assignments = data.signalass
|
||||
end
|
||||
end
|
||||
|
||||
function ildb.save()
|
||||
return {tcbs = track_circuit_breaks, ts=track_sections}
|
||||
return {tcbs = track_circuit_breaks, ts=track_sections, signalass = signal_assignments}
|
||||
end
|
||||
|
||||
--
|
||||
|
@ -123,6 +128,7 @@ TCB data structure
|
|||
-- 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)
|
||||
},
|
||||
[2] = { -- Variant: end of track-circuited area (initial state of TC)
|
||||
ts_id = nil, -- this is the indication for end_of_interlocking
|
||||
|
@ -145,6 +151,11 @@ Track section
|
|||
|
||||
Signal specifier (sigd) (a pair of TCB/Side):
|
||||
{p = <pos>, s = <1/2>}
|
||||
|
||||
Signal Assignments: reverse lookup of signals assigned to TCBs
|
||||
signal_assignments = {
|
||||
[<signal pts>] = <sigd>
|
||||
}
|
||||
]]
|
||||
|
||||
|
||||
|
@ -406,6 +417,19 @@ function ildb.get_ts_at_pos(pos)
|
|||
return nil
|
||||
end
|
||||
|
||||
|
||||
-- returns the sigd the signal at pos belongs to, if this is known
|
||||
function ildb.get_sigd_for_signal(pos)
|
||||
local pts = advtrains.roundfloorpts(pos)
|
||||
return signal_assignments[pts]
|
||||
end
|
||||
function ildb.set_sigd_for_signal(pos, sigd)
|
||||
local pts = advtrains.roundfloorpts(pos)
|
||||
signal_assignments[pts] = sigd
|
||||
end
|
||||
|
||||
|
||||
|
||||
advtrains.interlocking.db = ildb
|
||||
|
||||
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
-- Demonstration signals
|
||||
-- Those can display the 3 main aspects of Ks signals
|
||||
|
||||
-- Note that the group value of advtrains_signal is 2, which means "step 2 of signal capabilities"
|
||||
-- advtrains_signal=1 is meant for signals that do not implement set_aspect.
|
||||
|
||||
|
||||
minetest.register_node("advtrains_interlocking:ds_danger", {
|
||||
description = "Demo signal at Danger",
|
||||
tiles = {"at_il_signal_asp_danger.png"},
|
||||
groups = {
|
||||
cracky = 3,
|
||||
advtrains_signal = 1,
|
||||
advtrains_signal = 2,
|
||||
save_in_at_nodedb = 1,
|
||||
},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
|
@ -35,7 +38,7 @@ minetest.register_node("advtrains_interlocking:ds_free", {
|
|||
tiles = {"at_il_signal_asp_free.png"},
|
||||
groups = {
|
||||
cracky = 3,
|
||||
advtrains_signal = 1,
|
||||
advtrains_signal = 2,
|
||||
save_in_at_nodedb = 1,
|
||||
},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
|
@ -63,7 +66,7 @@ minetest.register_node("advtrains_interlocking:ds_slow", {
|
|||
tiles = {"at_il_signal_asp_slow.png"},
|
||||
groups = {
|
||||
cracky = 3,
|
||||
advtrains_signal = 1,
|
||||
advtrains_signal = 2,
|
||||
save_in_at_nodedb = 1,
|
||||
},
|
||||
sounds = default.node_sound_stone_defaults(),
|
||||
|
|
|
@ -10,3 +10,4 @@ dofile(modpath.."tcb_ts_ui.lua")
|
|||
dofile(modpath.."signal_api.lua")
|
||||
dofile(modpath.."demosignals.lua")
|
||||
dofile(modpath.."train_related.lua")
|
||||
dofile(modpath.."route_prog.lua")
|
||||
|
|
|
@ -0,0 +1,323 @@
|
|||
-- Route programming system
|
||||
|
||||
--[[
|
||||
Progamming routes:
|
||||
1. Select "program new route" in the signalling dialog
|
||||
-> route_start marker will appear to designate route-program mode
|
||||
2. Do those actions in any order:
|
||||
A. punch a TCB marker node to proceed route along this TCB. This will only work if
|
||||
this is actually a TCB bordering the current TS, and will place a
|
||||
route_set marker and shift to the next TS
|
||||
B. right-click a turnout to switch it (no impact to route programming
|
||||
C. punch a turnout (or some other passive component) to fix its state (toggle)
|
||||
for the route. A sprite telling "Route Fix" will show that fact.
|
||||
3. To complete route setting, use the chat command '/at_program_route <route name>'.
|
||||
The last punched TCB will get a 'route end' marker
|
||||
The end of a route should be at another signal facing the same direction as the entrance signal,
|
||||
however this is not enforced and left up to the signal engineer (the programmer)
|
||||
|
||||
The route visualization will also be used to visualize routes after they have been programmed.
|
||||
]]--
|
||||
|
||||
|
||||
-- table with objectRefs
|
||||
local markerent = {}
|
||||
|
||||
minetest.register_entity("advtrains_interlocking:routemarker", {
|
||||
visual = "mesh",
|
||||
mesh = "trackplane.b3d",
|
||||
textures = {"at_il_route_set.png"},
|
||||
collisionbox = {-1,-0.5,-1, 1,-0.4,1},
|
||||
visual_size = {x=10, y=10},
|
||||
on_punch = function(self)
|
||||
self.object:remove()
|
||||
end,
|
||||
get_staticdata = function() return "STATIC" end,
|
||||
on_activate = function(self, sdata) if sdata=="STATIC" then self.object:remove() end end,
|
||||
static_save = false,
|
||||
})
|
||||
|
||||
|
||||
-- Spawn or update a route marker entity
|
||||
-- pos: position where this is going to be
|
||||
-- key: something unique to determine which entity to remove if this was set before
|
||||
-- img: texture
|
||||
local function routemarker(context, pos, key, img, yaw, itex)
|
||||
if not markerent[context] then
|
||||
markerent[context] = {}
|
||||
end
|
||||
if markerent[context][key] then
|
||||
markerent[context][key]:remove()
|
||||
end
|
||||
|
||||
local obj = minetest.add_entity(vector.add(pos, {x=0, y=0.3, z=0}), "advtrains_interlocking:routemarker")
|
||||
if not obj then return end
|
||||
obj:set_yaw(yaw)
|
||||
obj:set_properties({
|
||||
infotext = itex,
|
||||
textures = {img},
|
||||
})
|
||||
|
||||
markerent[context][key] = obj
|
||||
end
|
||||
|
||||
minetest.register_entity("advtrains_interlocking:routesprite", {
|
||||
visual = "sprite",
|
||||
textures = {"at_il_turnout_free.png"},
|
||||
collisionbox = {-0.2,-0.2,-0.2, 0.2,0.2,0.2},
|
||||
visual_size = {x=1, y=1},
|
||||
on_punch = function(self)
|
||||
self.object:remove()
|
||||
end,
|
||||
get_staticdata = function() return "STATIC" end,
|
||||
on_activate = function(self, sdata) if sdata=="STATIC" then self.object:remove() end end,
|
||||
static_save = false,
|
||||
})
|
||||
|
||||
|
||||
-- Spawn or update a route sprite entity
|
||||
-- pos: position where this is going to be
|
||||
-- key: something unique to determine which entity to remove if this was set before
|
||||
-- img: texture
|
||||
local function routesprite(context, pos, key, img, itex)
|
||||
if not markerent[context] then
|
||||
markerent[context] = {}
|
||||
end
|
||||
if markerent[context][key] then
|
||||
markerent[context][key]:remove()
|
||||
end
|
||||
|
||||
local obj = minetest.add_entity(vector.add(pos, {x=0, y=0, z=0}), "advtrains_interlocking:routesprite")
|
||||
if not obj then return end
|
||||
obj:set_properties({
|
||||
infotext = itex,
|
||||
textures = {img},
|
||||
})
|
||||
|
||||
markerent[context][key] = obj
|
||||
end
|
||||
|
||||
--[[
|
||||
Route definition:
|
||||
route = {
|
||||
name = <string>
|
||||
tcbpath = {
|
||||
[n] = <sigd>
|
||||
}
|
||||
pcfix = {
|
||||
[<pts>] = "state"
|
||||
}
|
||||
}
|
||||
The first item in the TCB path is always the start signal of this route,
|
||||
so this is left out.
|
||||
|
||||
|
||||
]]--
|
||||
|
||||
function advtrains.interlocking.clear_visu_context(context)
|
||||
if not markerent[context] then return end
|
||||
for key, obj in pairs(markerent[context]) do
|
||||
obj:remove()
|
||||
end
|
||||
markerent[context] = nil
|
||||
end
|
||||
|
||||
-- visualize route. 'context' is a string that identifies the context of this visualization
|
||||
-- e.g. prog_<player> or vis<pts> for later visualizations
|
||||
function advtrains.interlocking.visualize_route(origin, route, context)
|
||||
advtrains.interlocking.clear_visu_context(context)
|
||||
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)
|
||||
if node_ok then
|
||||
yaw = advtrains.dir_to_angle(conns[sigd.s].c)
|
||||
end
|
||||
local img = "at_il_route_set.png"
|
||||
if k == #route.tcbpath then img = "at_il_route_end.png" end
|
||||
routemarker(context, sigd.p, "rte"..k, img, yaw, route.name.." #"..k)
|
||||
end
|
||||
for pts, state in pairs(route.pcfix) do
|
||||
local pos = minetest.string_to_pos(pts)
|
||||
routesprite(context, pos, "fix"..pts, "at_il_route_lock.png", "Fixed in state '"..state.."' by route "..route.name)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local player_rte_prog = {}
|
||||
|
||||
function advtrains.interlocking.init_route_prog(pname, sigd)
|
||||
player_rte_prog[pname] = {
|
||||
origin = sigd,
|
||||
route = {
|
||||
name = "PROG["..pname.."]",
|
||||
tcbpath = {},
|
||||
pcfix = {},
|
||||
}
|
||||
}
|
||||
minetest.chat_send_player(pname, "Route programming mode active. Punch TCBs to add route segments, punch turnouts to lock them.")
|
||||
end
|
||||
|
||||
local function get_last_route_item(origin, route)
|
||||
if #route.tcbpath == 0 then
|
||||
return origin
|
||||
end
|
||||
return route.tcbpath[#route.tcbpath]
|
||||
end
|
||||
|
||||
local function chat(pname, message)
|
||||
minetest.chat_send_player(pname, "[Route programming] "..message)
|
||||
end
|
||||
local function otherside(s)
|
||||
if s==1 then return 2 else return 1 end
|
||||
end
|
||||
|
||||
-- Central route programming punch callback
|
||||
minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
||||
local pname = player:get_player_name()
|
||||
local rp = player_rte_prog[pname]
|
||||
if rp then
|
||||
-- determine what the punched node is
|
||||
if minetest.get_item_group(node.name, "at_il_track_circuit_break") >= 1 then
|
||||
-- get position of the assigned tcb
|
||||
local meta = minetest.get_meta(pos)
|
||||
local tcbpts = meta:get_string("tcb_pos")
|
||||
if tcbpts == "" then
|
||||
chat(pname, "This TCB is unconfigured, you first need to assign it to a rail")
|
||||
return
|
||||
end
|
||||
local tcbpos = minetest.string_to_pos(tcbpts)
|
||||
|
||||
-- track circuit break, try to advance route over it
|
||||
local lri = get_last_route_item(rp.origin, rp.route)
|
||||
if vector.equals(lri.p, tcbpos) then
|
||||
chat(pname, "You cannot continue the route to where you came from!")
|
||||
return
|
||||
end
|
||||
|
||||
local start_tcbs = advtrains.interlocking.db.get_tcbs(lri)
|
||||
if not start_tcbs.ts_id then
|
||||
chat(pname, "The previous TCB was End of Interlocking. Please complete route programming using '/at_rp_set <name>'")
|
||||
return
|
||||
end
|
||||
|
||||
local ts = advtrains.interlocking.db.get_ts(start_tcbs.ts_id)
|
||||
if not ts then atwarn("Internal error, ts inexistant for id!") return end
|
||||
local found = nil
|
||||
for _,sigd in ipairs(ts.tc_breaks) do
|
||||
if vector.equals(sigd.p, tcbpos) then
|
||||
found = otherside(sigd.s)
|
||||
end
|
||||
end
|
||||
if not found then
|
||||
chat(pname, "Previous and this TCB belong to different track sections!")
|
||||
return
|
||||
end
|
||||
-- everything worked, just add the other side to the list
|
||||
table.insert(rp.route.tcbpath, {p = tcbpos, s = found})
|
||||
chat(pname, "Added track section '"..ts.name.."' to the route (revert with /at_rp_back)")
|
||||
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname)
|
||||
return
|
||||
end
|
||||
local ndef = minetest.registered_nodes[node.name]
|
||||
if ndef and ndef.luaautomation and ndef.luaautomation.getstate then
|
||||
local pts = advtrains.roundfloorpts(pos)
|
||||
if rp.route.pcfix[pts] then
|
||||
rp.route.pcfix[pts] = nil
|
||||
chat(pname, pts.." is no longer affected when this route is set.")
|
||||
else
|
||||
local state = ndef.luaautomation.getstate
|
||||
if type(state)=="function" then
|
||||
state = state(pos, node)
|
||||
end
|
||||
rp.route.pcfix[pts] = state
|
||||
chat(pname, pts.." is held in "..state.." position when this route is set.")
|
||||
end
|
||||
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname)
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_chatcommand("at_rp_set",
|
||||
{
|
||||
params = "<name>", -- Short parameter description
|
||||
description = "Completes route programming procedure", -- Full description
|
||||
privs = {}, -- TODO
|
||||
func = function(pname, param)
|
||||
return advtrains.pcall(function()
|
||||
if param=="" then
|
||||
return false, "Missing name parameter!"
|
||||
end
|
||||
local rp = player_rte_prog[pname]
|
||||
if rp then
|
||||
if #rp.route.tcbpath <= 0 then
|
||||
return false, "Cannot program route without a target"
|
||||
end
|
||||
rp.route.name = param
|
||||
-- TODO save that route somewhere in origin
|
||||
atdebug("ROUTE RESULT:",rp)
|
||||
advtrains.interlocking.clear_visu_context("prog_"..pname)
|
||||
return true, "Successfully programmed route"
|
||||
end
|
||||
return false, "You were not programming a route!"
|
||||
end)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_chatcommand("at_rp_back",
|
||||
{
|
||||
params = "", -- Short parameter description
|
||||
description = "Remove last route segment", -- Full description
|
||||
privs = {}, -- Require the "privs" privilege to run
|
||||
func = function(pname, param)
|
||||
return advtrains.pcall(function()
|
||||
local rp = player_rte_prog[pname]
|
||||
if rp then
|
||||
if #rp.route.tcbpath <= 0 then
|
||||
return false, "Cannot backtrack when there are no route elements"
|
||||
end
|
||||
rp.route.tcbpath[#rp.route.tcbpath] = nil
|
||||
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname)
|
||||
return true, "Route section "..(#rp.route.tcbpath+1).." removed."
|
||||
end
|
||||
return false, "You were not programming a route!"
|
||||
end)
|
||||
end,
|
||||
})
|
||||
minetest.register_chatcommand("at_rp_mark",
|
||||
{
|
||||
params = "", -- Short parameter description
|
||||
description = "Re-set route programming markers", -- Full description
|
||||
privs = {}, -- TODO
|
||||
func = function(pname, param)
|
||||
return advtrains.pcall(function()
|
||||
local rp = player_rte_prog[pname]
|
||||
if rp then
|
||||
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname)
|
||||
return true, "Redrawn route markers"
|
||||
end
|
||||
return false, "You were not programming a route!"
|
||||
end)
|
||||
end,
|
||||
})
|
||||
minetest.register_chatcommand("at_rp_discard",
|
||||
{
|
||||
params = "", -- Short parameter description
|
||||
description = "Discards the currently programmed route", -- Full description
|
||||
privs = {}, -- Require the "privs" privilege to run
|
||||
func = function(pname, param)
|
||||
return advtrains.pcall(function()
|
||||
player_rte_prog[pname] = nil
|
||||
advtrains.interlocking.clear_visu_context("prog_"..pname)
|
||||
return true, "Route discarded"
|
||||
end)
|
||||
end,
|
||||
})
|
||||
|
||||
|
||||
--TODO on route setting
|
||||
-- locked turnouts need to somehow know the TS they're associated to, which isn't possible with the current route programming and saving method
|
||||
-- unify luaautomation get/setstate interface to the core
|
||||
-- privileges for route programming
|
||||
-- for now, that locking aspect will be ignored and turnouts just set when route gets commited.
|
|
@ -33,6 +33,21 @@ on_rightclick = advtrains.interlocking.signal_rc_handler
|
|||
|
||||
]]--
|
||||
|
||||
local DANGER = {
|
||||
main = {
|
||||
free = false,
|
||||
speed = 0,
|
||||
},
|
||||
shunt = {
|
||||
free = false,
|
||||
},
|
||||
dst = {
|
||||
free = false,
|
||||
speed = 0,
|
||||
},
|
||||
info = {}
|
||||
}
|
||||
|
||||
function advtrains.interlocking.signal_set_aspect(pos, asp)
|
||||
local node=advtrains.ndb.get_node(pos)
|
||||
local ndef=minetest.registered_nodes[node.name]
|
||||
|
@ -43,7 +58,13 @@ end
|
|||
|
||||
function advtrains.interlocking.signal_rc_handler(pos, node, player, itemstack, pointed_thing)
|
||||
local pname = player:get_player_name()
|
||||
minetest.show_formspec(pname, "at_il_sigasp_"..minetest.pos_to_string(pos), "field[aspect;Set Aspect (F/D)Speed(F/D)Speed(F/D);D0D0D]")
|
||||
local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
|
||||
if sigd then
|
||||
advtrains.interlocking.show_signalling_form(sigd, pname)
|
||||
else
|
||||
-- permit to set aspect manually
|
||||
minetest.show_formspec(pname, "at_il_sigasp_"..minetest.pos_to_string(pos), "field[aspect;Set Aspect (F/D)Speed(F/D)Speed(F/D);D0D0D]")
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
|
@ -73,3 +94,15 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
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_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
|
||||
end
|
||||
end
|
||||
return DANGER;
|
||||
end
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
-- Track Circuit Breaks and Track Sections - Player interaction
|
||||
|
||||
local players_assign_tcb = {}
|
||||
local players_assign_signal = {}
|
||||
local players_link_ts = {}
|
||||
|
||||
local lntrans = { "A", "B" }
|
||||
|
@ -26,6 +27,7 @@ minetest.register_node("advtrains_interlocking:tcb_node", {
|
|||
cracky=3,
|
||||
not_blocking_trains=1,
|
||||
--save_in_at_nodedb=2,
|
||||
at_il_track_circuit_break = 1,
|
||||
},
|
||||
after_place_node = function(pos, node, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
|
@ -46,14 +48,14 @@ minetest.register_node("advtrains_interlocking:tcb_node", {
|
|||
players_assign_tcb[pname] = pos
|
||||
end
|
||||
end,
|
||||
on_punch = function(pos, node, player)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local tcbpts = meta:get_string("tcb_pos")
|
||||
if tcbpts ~= "" then
|
||||
local tcbpos = minetest.string_to_pos(tcbpts)
|
||||
advtrains.interlocking.show_tcb_marker(tcbpos)
|
||||
end
|
||||
end,
|
||||
--on_punch = function(pos, node, player)
|
||||
-- local meta = minetest.get_meta(pos)
|
||||
-- local tcbpts = meta:get_string("tcb_pos")
|
||||
-- if tcbpts ~= "" then
|
||||
-- local tcbpos = minetest.string_to_pos(tcbpts)
|
||||
-- advtrains.interlocking.show_tcb_marker(tcbpos)
|
||||
-- end
|
||||
--end,
|
||||
can_dig = function(pos, player)
|
||||
-- Those markers can only be dug when all adjacent TS's are set
|
||||
-- as EOI.
|
||||
|
@ -83,6 +85,7 @@ minetest.register_node("advtrains_interlocking:tcb_node", {
|
|||
|
||||
minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
||||
local pname = player:get_player_name()
|
||||
-- TCB assignment
|
||||
local tcbnpos = players_assign_tcb[pname]
|
||||
if tcbnpos then
|
||||
if vector.distance(pos, tcbnpos)<=20 then
|
||||
|
@ -109,6 +112,29 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
|||
end
|
||||
players_assign_tcb[pname] = nil
|
||||
end
|
||||
|
||||
-- Signal assignment
|
||||
local sigd = players_assign_signal[pname]
|
||||
if sigd then
|
||||
if vector.distance(pos, sigd.p)<=50 then
|
||||
local is_signal = minetest.get_item_group(node.name, "advtrains_signal") >= 2
|
||||
if is_signal then
|
||||
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||
if tcbs then
|
||||
tcbs.signal = pos
|
||||
advtrains.interlocking.db.set_sigd_for_signal(pos, sigd)
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Successfully assigned signal.")
|
||||
else
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Internal error, TCBS doesn't exist. Aborted.")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Not a compatible signal. Aborted.")
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Node is too far away. Aborted.")
|
||||
end
|
||||
players_assign_tcb[pname] = nil
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
|
@ -135,6 +161,11 @@ local function mktcbformspec(tcbs, btnpref, offset, pname)
|
|||
form = form.."button[0.5,"..(offset+1.5)..";5,1;"..btnpref.."_setfree;Section is blocked]"
|
||||
end
|
||||
end
|
||||
if tcbs.signal then
|
||||
form = form.."button[0.5,"..(offset+2.5)..";5,1;"..btnpref.."_sigdia;Signalling]"
|
||||
else
|
||||
form = form.."button[0.5,"..(offset+2.5)..";5,1;"..btnpref.."_asnsig;Assign a signal]"
|
||||
end
|
||||
return form
|
||||
end
|
||||
|
||||
|
@ -143,9 +174,9 @@ function advtrains.interlocking.show_tcb_form(pos, pname)
|
|||
local tcb = advtrains.interlocking.db.get_tcb(pos)
|
||||
if not tcb then return end
|
||||
|
||||
local form = "size[6,7] label[0.5,0.5;Track Circuit Break Configuration]"
|
||||
local form = "size[6,9] label[0.5,0.5;Track Circuit Break Configuration]"
|
||||
form = form .. mktcbformspec(tcb[1], "A", 1, pname)
|
||||
form = form .. mktcbformspec(tcb[2], "B", 4, pname)
|
||||
form = form .. mktcbformspec(tcb[2], "B", 5, pname)
|
||||
|
||||
minetest.show_formspec(pname, "at_il_tcbconfig_"..minetest.pos_to_string(pos), form)
|
||||
advtrains.interlocking.show_tcb_marker(pos)
|
||||
|
@ -174,6 +205,8 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
local f_makeil = {fields.A_makeil, fields.B_makeil}
|
||||
local f_setlocked = {fields.A_setlocked, fields.B_setlocked}
|
||||
local f_setfree = {fields.A_setfree, fields.B_setfree}
|
||||
local f_asnsig = {fields.A_asnsig, fields.B_asnsig}
|
||||
local f_sigdia = {fields.A_sigdia, fields.B_sigdia}
|
||||
|
||||
for connid=1,2 do
|
||||
local tcbs = tcb[connid]
|
||||
|
@ -201,6 +234,17 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||
tcbs.section_free = nil
|
||||
end
|
||||
end
|
||||
if f_asnsig[connid] and not tcbs.signal then
|
||||
minetest.chat_send_player(pname, "Configuring TCB: Please punch the signal to assign.")
|
||||
players_assign_signal[pname] = {p=pos, s=connid}
|
||||
minetest.close_formspec(pname, formname)
|
||||
return
|
||||
end
|
||||
if f_sigdia[connid] and tcbs.signal then
|
||||
advtrains.interlocking.show_signalling_form({p=pos, s=connid}, pname)
|
||||
return
|
||||
end
|
||||
|
||||
end
|
||||
advtrains.interlocking.show_tcb_form(pos, pname)
|
||||
end
|
||||
|
@ -373,3 +417,33 @@ function advtrains.interlocking.show_tcb_marker(pos)
|
|||
|
||||
markerent[pts] = obj
|
||||
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]"
|
||||
|
||||
--minetest.show_formspec(pname, "at_il_signalling_"..sigd.p.."_"..sigd.s, form)
|
||||
--TODO this is temporary
|
||||
advtrains.interlocking.init_route_prog(pname, sigd)
|
||||
end
|
||||
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
local pname = player:get_player_name()
|
||||
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)
|
||||
connid = tonumber(connids)
|
||||
if not connid or connid<1 or connid>2 then return end
|
||||
end
|
||||
if pos and connid and not fields.quit then
|
||||
|
||||
advtrains.interlocking.show_signalling_form(ts_id, pname, sel_tcb)
|
||||
end
|
||||
|
||||
end)
|
||||
|
|
After Width: | Height: | Size: 451 B |
After Width: | Height: | Size: 382 B |
After Width: | Height: | Size: 398 B |
After Width: | Height: | Size: 380 B |
After Width: | Height: | Size: 314 B |
After Width: | Height: | Size: 298 B |
After Width: | Height: | Size: 367 B |
After Width: | Height: | Size: 229 B |