Make Buffers become implicitly their own TCBs and signals when interlocking is enabled
This commit is contained in:
parent
73c393e223
commit
922e654b7b
|
@ -3,15 +3,15 @@
|
||||||
|
|
||||||
local mrules_wallsignal = advtrains.meseconrules
|
local mrules_wallsignal = advtrains.meseconrules
|
||||||
|
|
||||||
local function can_dig_func(pos)
|
local function can_dig_func(pos, player)
|
||||||
if advtrains.interlocking then
|
if advtrains.interlocking then
|
||||||
return advtrains.interlocking.signal.can_dig(pos)
|
return advtrains.interlocking.signal.can_dig(pos, player)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
local function after_dig_func(pos)
|
local function after_dig_func(pos, oldnode, oldmetadata, digger)
|
||||||
if advtrains.interlocking then
|
if advtrains.interlocking then
|
||||||
return advtrains.interlocking.signal.after_dig(pos)
|
return advtrains.interlocking.signal.after_dig(pos, oldnode, oldmetadata, digger)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -152,12 +152,14 @@ local function check_or_bend_rail(origin, dir, pname, commit)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function track_place_node(pos, node, ndef)
|
local function track_place_node(pos, node, ndef, pname)
|
||||||
--atdebug("track_place_node: ",pos, node)
|
--atdebug("track_place_node: ",pos, node)
|
||||||
advtrains.ndb.swap_node(pos, node)
|
advtrains.ndb.swap_node(pos, node)
|
||||||
local ndef = minetest.registered_nodes[node.name]
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
if ndef and ndef.after_place_node then
|
if ndef and ndef.after_place_node then
|
||||||
ndef.after_place_node(pos)
|
-- resolve player again
|
||||||
|
local player = pname and core.get_player_by_name(pname) or nil
|
||||||
|
ndef.after_place_node(pos, player) -- note: itemstack and pointed_thing are NOT available here anymore (crap!)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -191,16 +193,16 @@ function tp.place_track(pos, tpg, pname, yaw)
|
||||||
for k1, conn1 in ipairs(cand) do
|
for k1, conn1 in ipairs(cand) do
|
||||||
for k2, conn2 in ipairs(cand) do
|
for k2, conn2 in ipairs(cand) do
|
||||||
if k1~=k2 then
|
if k1~=k2 then
|
||||||
-- order of conn1/conn2: prefer conn2 being in the direction of the player facing.
|
-- order of conn1/conn2: prefer conn1 being in the direction of the player facing.
|
||||||
-- the combination the other way round will be run through in a later loop iteration
|
-- the combination the other way round will be run through in a later loop iteration
|
||||||
if advtrains.yawToDirection(yaw, conn1, conn2) == conn2 then
|
if advtrains.yawToDirection(yaw, conn1, conn2) == conn1 then
|
||||||
-- does there exist a suitable double-connection rail?
|
-- does there exist a suitable double-connection rail?
|
||||||
--atdebug("Try double conn: ",conn1, conn2)
|
--atdebug("Try double conn: ",conn1, conn2)
|
||||||
local node = g.double[conn1.."_"..conn2]
|
local node = g.double[conn1.."_"..conn2]
|
||||||
if node then
|
if node then
|
||||||
check_or_bend_rail(pos, conn1, pname, true)
|
check_or_bend_rail(pos, conn1, pname, true)
|
||||||
check_or_bend_rail(pos, conn2, pname, true)
|
check_or_bend_rail(pos, conn2, pname, true)
|
||||||
track_place_node(pos, node) -- calls after_place_node implicitly
|
track_place_node(pos, node, pname) -- calls after_place_node implicitly
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -220,13 +222,13 @@ function tp.place_track(pos, tpg, pname, yaw)
|
||||||
local node = single[conn1]
|
local node = single[conn1]
|
||||||
if node then
|
if node then
|
||||||
check_or_bend_rail(pos, conn1, pname, true)
|
check_or_bend_rail(pos, conn1, pname, true)
|
||||||
track_place_node(pos, node) -- calls after_place_node implicitly
|
track_place_node(pos, node, nil, pname) -- calls after_place_node implicitly
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- 4. if nothing worked, set the default
|
-- 4. if nothing worked, set the default
|
||||||
local node = g.default
|
local node = g.default
|
||||||
track_place_node(pos, node) -- calls after_place_node implicitly
|
track_place_node(pos, node, nil, pname) -- calls after_place_node implicitly
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -253,6 +253,7 @@ end
|
||||||
|
|
||||||
-- Function called when a track is about to be dug or modified by the trackworker
|
-- Function called when a track is about to be dug or modified by the trackworker
|
||||||
-- Returns either true (ok) or false,"translated string describing reason why it isn't allowed"
|
-- Returns either true (ok) or false,"translated string describing reason why it isn't allowed"
|
||||||
|
-- Impl Note: possibly duplicate code in "self contained TCB" - see interlocking/tcb_ts_ui.lua!
|
||||||
function advtrains.can_dig_or_modify_track(pos)
|
function advtrains.can_dig_or_modify_track(pos)
|
||||||
if advtrains.get_train_at_pos(pos) then
|
if advtrains.get_train_at_pos(pos) then
|
||||||
return false, attrans("Position is occupied by a train.")
|
return false, attrans("Position is occupied by a train.")
|
||||||
|
|
|
@ -802,10 +802,18 @@ function ildb.create_tcb_at(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Remove TCB at the position and update/repair the now joined section
|
-- Remove TCB at the position and update/repair the now joined section
|
||||||
function ildb.remove_tcb_at(pos)
|
-- skip_tsrepair: should be set to true when the rail node at the TCB position is already gone.
|
||||||
|
-- Assumes the track sections are now separated and does not attempt the repair process.
|
||||||
|
function ildb.remove_tcb_at(pos, pname, skip_tsrepair)
|
||||||
--atdebug("remove_tcb_at",pos)
|
--atdebug("remove_tcb_at",pos)
|
||||||
local pts = advtrains.encode_pos(pos)
|
local pts = advtrains.encode_pos(pos)
|
||||||
local old_tcb = track_circuit_breaks[pts]
|
local old_tcb = track_circuit_breaks[pts]
|
||||||
|
-- unassign signals if defined
|
||||||
|
for connid=1,2 do
|
||||||
|
if old_tcb[connid].signal then
|
||||||
|
ildb.set_sigd_for_signal(old_tcb[connid].signal, nil)
|
||||||
|
end
|
||||||
|
end
|
||||||
track_circuit_breaks[pts] = nil
|
track_circuit_breaks[pts] = nil
|
||||||
-- purge the track sections adjacent
|
-- purge the track sections adjacent
|
||||||
if old_tcb[1].ts_id then
|
if old_tcb[1].ts_id then
|
||||||
|
@ -823,7 +831,9 @@ function ildb.remove_tcb_at(pos)
|
||||||
end
|
end
|
||||||
advtrains.interlocking.remove_tcb_marker(pos)
|
advtrains.interlocking.remove_tcb_marker(pos)
|
||||||
-- If needed, merge the track sections here
|
-- If needed, merge the track sections here
|
||||||
ildb.check_and_repair_ts_at_pos(pos, nil)
|
if not skip_tsrepair then
|
||||||
|
ildb.check_and_repair_ts_at_pos(pos, pname)
|
||||||
|
end
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -973,11 +983,34 @@ function ildb.get_sigd_for_signal(pos)
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
function ildb.set_sigd_for_signal(pos, sigd)
|
function ildb.set_sigd_for_signal(pos, sigd) -- do not use!
|
||||||
local pts = advtrains.roundfloorpts(pos)
|
local pts = advtrains.roundfloorpts(pos)
|
||||||
signal_assignments[pts] = sigd
|
signal_assignments[pts] = sigd
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Assign the signal at pos to the given TCB side.
|
||||||
|
function ildb.assign_signal_to_tcbs(pos, sigd)
|
||||||
|
local tcbs = ildb.get_tcbs(sigd)
|
||||||
|
assert(tcbs, "assign_signal_to_tcbs invalid sigd!")
|
||||||
|
tcbs.signal = pos
|
||||||
|
if not tcbs.routes then
|
||||||
|
tcbs.routes = {}
|
||||||
|
end
|
||||||
|
ildb.set_sigd_for_signal(pos, sigd)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- unassign the signal from the given sigd (looks in tcbs.signal for the signalpos)
|
||||||
|
function ildb.unassign_signal_for_tcbs(sigd)
|
||||||
|
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||||
|
if not tcbs then return end
|
||||||
|
local pos = tcbs.signal
|
||||||
|
if not pos then return end
|
||||||
|
ildb.set_sigd_for_signal(pos, nil)
|
||||||
|
tcbs.signal = nil
|
||||||
|
tcbs.route_aspect = nil
|
||||||
|
tcbs.route_remote = nil
|
||||||
|
end
|
||||||
|
|
||||||
-- checks if there's any influence point set to this position
|
-- checks if there's any influence point set to this position
|
||||||
-- if purge is true, checks whether the associated signal still exists
|
-- if purge is true, checks whether the associated signal still exists
|
||||||
-- and deletes the ip if not.
|
-- and deletes the ip if not.
|
||||||
|
@ -987,7 +1020,7 @@ function ildb.is_ip_at(pos, purge)
|
||||||
if purge then
|
if purge then
|
||||||
-- is there still a signal assigned to it?
|
-- is there still a signal assigned to it?
|
||||||
for connid, sigpos in pairs(influence_points[pts]) do
|
for connid, sigpos in pairs(influence_points[pts]) do
|
||||||
local asp = advtrains.interlocking.signal_get_aspect(sigpos)
|
local asp = advtrains.interlocking.signal.get_aspect(sigpos)
|
||||||
if not asp then
|
if not asp then
|
||||||
atlog("Clearing orphaned signal influence point", pts, "/", connid)
|
atlog("Clearing orphaned signal influence point", pts, "/", connid)
|
||||||
ildb.clear_ip_signal(pts, connid)
|
ildb.clear_ip_signal(pts, connid)
|
||||||
|
|
|
@ -4,4 +4,4 @@ description=Interlocking system for Advanced Trains
|
||||||
author=orwell96
|
author=orwell96
|
||||||
|
|
||||||
depends=advtrains
|
depends=advtrains
|
||||||
optional_depends=advtrains_train_track
|
#optional_depends=advtrains_train_track
|
||||||
|
|
|
@ -535,9 +535,12 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
||||||
-- show formspec
|
-- show formspec
|
||||||
|
|
||||||
show_routing_form(pname, tcbpos)
|
show_routing_form(pname, tcbpos)
|
||||||
|
|
||||||
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, pname)
|
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, pname)
|
||||||
|
return
|
||||||
|
elseif advtrains.interlocking.database.get_tcb(pos) then
|
||||||
|
-- the punched node itself is a TCB
|
||||||
|
show_routing_form(pname, pos)
|
||||||
|
advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, pname)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if advtrains.is_passive(pos) then
|
if advtrains.is_passive(pos) then
|
||||||
|
|
|
@ -400,7 +400,8 @@ end
|
||||||
-- 0: not a signal at all
|
-- 0: not a signal at all
|
||||||
-- 1: signal has get_aspect_info() but the aspect is not variable (e.g. a sign)
|
-- 1: signal has get_aspect_info() but the aspect is not variable (e.g. a sign)
|
||||||
-- 2: signal has apply_aspect() but does not have main aspects (e.g. a pure distant signal)
|
-- 2: signal has apply_aspect() but does not have main aspects (e.g. a pure distant signal)
|
||||||
-- 3: Full capabilities, signal has main aspects and can be used as main/shunt signal (can be start/endpoint of a route)
|
-- 3: signal has main signal role but can only ever display a halt aspect, such as a bumper (can be endpoint, but not startpoint, of a route)
|
||||||
|
-- 4: Full capabilities, signal has main aspects and can be used as main/shunt signal (can be start/endpoint of a route)
|
||||||
function signal.get_signal_cap_level(pos)
|
function signal.get_signal_cap_level(pos)
|
||||||
local node = advtrains.ndb.get_node_or_nil(pos)
|
local node = advtrains.ndb.get_node_or_nil(pos)
|
||||||
local ndef = node and minetest.registered_nodes[node.name]
|
local ndef = node and minetest.registered_nodes[node.name]
|
||||||
|
@ -408,6 +409,10 @@ function signal.get_signal_cap_level(pos)
|
||||||
if ndefat and ndefat.get_aspect_info then
|
if ndefat and ndefat.get_aspect_info then
|
||||||
if ndefat.apply_aspect then
|
if ndefat.apply_aspect then
|
||||||
if ndefat.main_aspects then
|
if ndefat.main_aspects then
|
||||||
|
-- if the table contains anything, 4, otherwise 3
|
||||||
|
for _,_ in pairs(ndefat.main_aspects) do
|
||||||
|
return 4
|
||||||
|
end
|
||||||
return 3
|
return 3
|
||||||
end
|
end
|
||||||
return 2
|
return 2
|
||||||
|
@ -419,9 +424,17 @@ end
|
||||||
|
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
function signal.can_dig(pos)
|
function signal.can_dig(pos, player)
|
||||||
local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
|
local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
|
||||||
if sigd then
|
if sigd then
|
||||||
|
-- check privileges
|
||||||
|
if not player or not minetest.check_player_privs(player:get_player_name(), "interlocking") then
|
||||||
|
if not player then -- intermediate debug to uncover hard-to-find bugz
|
||||||
|
atdebug("advtrains.interlocking.signal.can_dig(",pos,") called with player==nil!")
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
-- check if route is set
|
||||||
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
||||||
if tcbs.routeset then
|
if tcbs.routeset then
|
||||||
return false
|
return false
|
||||||
|
@ -434,11 +447,7 @@ function signal.after_dig(pos, oldnode, oldmetadata, player)
|
||||||
-- unassign signal if necessary
|
-- unassign signal if necessary
|
||||||
local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
|
local sigd = advtrains.interlocking.db.get_sigd_for_signal(pos)
|
||||||
if sigd then
|
if sigd then
|
||||||
local tcbs = advtrains.interlocking.db.get_tcbs(sigd)
|
advtrains.interlocking.db.unassign_signal_for_tcbs(sigd)
|
||||||
advtrains.interlocking.db.set_sigd_for_signal(pos, nil)
|
|
||||||
tcbs.signal = nil
|
|
||||||
tcbs.route_aspect = nil
|
|
||||||
tcbs.route_remote = nil
|
|
||||||
minetest.chat_send_player(player:get_player_name(), "Signal has been unassigned. Name and routes are kept for reuse.")
|
minetest.chat_send_player(player:get_player_name(), "Signal has been unassigned. Name and routes are kept for reuse.")
|
||||||
end
|
end
|
||||||
-- TODO clear influence point
|
-- TODO clear influence point
|
||||||
|
|
|
@ -156,7 +156,7 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
||||||
local tcbnpos = players_assign_tcb[pname]
|
local tcbnpos = players_assign_tcb[pname]
|
||||||
if tcbnpos then
|
if tcbnpos then
|
||||||
if vector.distance(pos, tcbnpos)<=20 then
|
if vector.distance(pos, tcbnpos)<=20 then
|
||||||
local node_ok, conns, rhe = advtrains.get_rail_info_at(pos, advtrains.all_tracktypes)
|
local node_ok, conns, rhe = advtrains.get_rail_info_at(pos)
|
||||||
if node_ok and #conns == 2 then
|
if node_ok and #conns == 2 then
|
||||||
-- if there is already a tcb here, reassign it
|
-- if there is already a tcb here, reassign it
|
||||||
if ildb.get_tcb(pos) then
|
if ildb.get_tcb(pos) then
|
||||||
|
@ -189,11 +189,7 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
||||||
if ndef and ndef.advtrains and ndef.advtrains.apply_aspect then
|
if ndef and ndef.advtrains and ndef.advtrains.apply_aspect then
|
||||||
local tcbs = ildb.get_tcbs(sigd)
|
local tcbs = ildb.get_tcbs(sigd)
|
||||||
if tcbs then
|
if tcbs then
|
||||||
tcbs.signal = pos
|
ildb.assign_signal_to_tcbs(pos, sigd)
|
||||||
if not tcbs.routes then
|
|
||||||
tcbs.routes = {}
|
|
||||||
end
|
|
||||||
ildb.set_sigd_for_signal(pos, sigd)
|
|
||||||
minetest.chat_send_player(pname, "Configuring TCB: Successfully assigned signal.")
|
minetest.chat_send_player(pname, "Configuring TCB: Successfully assigned signal.")
|
||||||
advtrains.interlocking.show_ip_form(pos, pname, true)
|
advtrains.interlocking.show_ip_form(pos, pname, true)
|
||||||
else
|
else
|
||||||
|
@ -212,6 +208,138 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- "Self-contained TCB"
|
||||||
|
-- 2024-11-25: Buffers should become their own TCB (and signal) automatically to permit setting routes to them
|
||||||
|
-- These are support functions for this kind of node.
|
||||||
|
|
||||||
|
-- Create an after_place_node callback for a self-contained TCB node. The parameters control additional behavior:
|
||||||
|
-- fail_silently_on_noprivs: (boolean) Does not give an error in case the placer does not have the interlocking privilege
|
||||||
|
-- auto_create_self_signal: (boolean) Automatically assign this same node as signal to the A side of the newly-created TCB
|
||||||
|
-- (this is useful for buffers as they serve both as TCB and as an always-halt signal)
|
||||||
|
function advtrains.interlocking.self_tcb_make_after_place_callback(fail_silently_on_noprivs, auto_create_self_signal)
|
||||||
|
return function(pos, player, itemstack, pointed_thing)
|
||||||
|
atdebug("selftcb apn ",pos, player, itemstack, pointed_thing)
|
||||||
|
local pname = player:get_player_name()
|
||||||
|
if not minetest.check_player_privs(pname, "interlocking") then
|
||||||
|
if not fail_silently_on_noprivs then
|
||||||
|
minetest.chat_send_player(pname, "Insufficient privileges to use this!")
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if ildb.get_tcb(pos) then
|
||||||
|
minetest.chat_send_player(pname, "TCB already existed at this position, now linked to this node")
|
||||||
|
else
|
||||||
|
ildb.create_tcb_at(pos, pname)
|
||||||
|
end
|
||||||
|
if auto_create_self_signal then
|
||||||
|
local sigd = { p = pos, s = 1 }
|
||||||
|
local tcbs = ildb.get_tcbs(sigd)
|
||||||
|
-- make sure signal doesn't already exist
|
||||||
|
if tcbs.signal then
|
||||||
|
minetest.chat_send_player(pname, "Signal on B side already assigned!")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
ildb.assign_signal_to_tcbs(pos, sigd)
|
||||||
|
-- assign influence point to itself
|
||||||
|
ildb.set_ip_signal(advtrains.roundfloorpts(pos), 1, pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create an can_dig callback for a self-contained TCB node. The parameters control additional behavior:
|
||||||
|
-- is_signal: (boolean) Whether this node is also a signal (in addition to being a TCB), e.g. when auto_create_self_signal was set.
|
||||||
|
-- Causes also the signal API's can_dig to be called
|
||||||
|
function advtrains.interlocking.self_tcb_make_can_dig_callback(is_signal)
|
||||||
|
return function(pos, player)
|
||||||
|
local pname = player and player:get_player_name() or ""
|
||||||
|
-- need to duplicate logic of the regular "can_dig_or_modify_track()" function in core/tracks.lua
|
||||||
|
if advtrains.get_train_at_pos(pos) then
|
||||||
|
minetest.chat_send_player(pname, "Can't remove track, a train is here!")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
-- end of standard checks
|
||||||
|
local tcb = ildb.get_tcb(pos)
|
||||||
|
if not tcb then
|
||||||
|
-- digging always allowed because the TCB hasn't been created (unless signal callback interjects)
|
||||||
|
if is_signal then
|
||||||
|
return advtrains.interlocking.signal.can_dig(pos, player)
|
||||||
|
else
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
-- TCB exists
|
||||||
|
if not minetest.check_player_privs(pname, "interlocking") then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
-- fine to remove (unless signal callback interjects)
|
||||||
|
if is_signal then
|
||||||
|
return advtrains.interlocking.signal.can_dig(pos, player)
|
||||||
|
else
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create an after_dig_node callback for a self-contained TCB node. The parameters control additional behavior:
|
||||||
|
-- is_signal: (boolean) Whether this node is also a signal (in addition to being a TCB), e.g. when auto_create_self_signal was set.
|
||||||
|
-- Causes also the signal API's after_dig_node to be called
|
||||||
|
function advtrains.interlocking.self_tcb_make_after_dig_callback(is_signal)
|
||||||
|
return function(pos, oldnode, oldmetadata, player)
|
||||||
|
local pname = player:get_player_name()
|
||||||
|
if is_signal then
|
||||||
|
-- "dig" the signal first
|
||||||
|
advtrains.interlocking.signal.after_dig(pos, oldnode, oldmetadata, player)
|
||||||
|
end
|
||||||
|
if ildb.get_tcb(pos) then
|
||||||
|
-- remove the TCB
|
||||||
|
ildb.remove_tcb_at(pos, pname, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Create an on_rightclick callback for a self-contained TCB node. The rightclick callback tries to repeat the TCB assignment
|
||||||
|
-- if necessary and otherwise shows the TCB formspec. The parameters control additional behavior:
|
||||||
|
-- fail_silently_on_noprivs: (boolean) Does not give an error in case the placer does not have the interlocking privilege
|
||||||
|
-- auto_create_self_signal: (boolean) Automatically assign this same node as signal to the B side of the
|
||||||
|
-- newly-created TCB if that has not already happened during place.
|
||||||
|
-- Otherwise, opens the signal dialog instead of the TCB dialog on rightclick
|
||||||
|
function advtrains.interlocking.self_tcb_make_on_rightclick_callback(fail_silently_on_noprivs, auto_create_self_signal)
|
||||||
|
return function(pos, node, player, itemstack, pointed_thing)
|
||||||
|
local pname = player:get_player_name()
|
||||||
|
if not minetest.check_player_privs(pname, "interlocking") then
|
||||||
|
if not fail_silently_on_noprivs then
|
||||||
|
minetest.chat_send_player(pname, "Insufficient privileges to use this!")
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if ildb.get_tcb(pos) then
|
||||||
|
-- TCB already here. go on
|
||||||
|
else
|
||||||
|
-- otherwise create tcb
|
||||||
|
ildb.create_tcb_at(pos, pname)
|
||||||
|
end
|
||||||
|
if auto_create_self_signal then
|
||||||
|
local sigd = { p = pos, s = 1 }
|
||||||
|
local tcbs = ildb.get_tcbs(sigd)
|
||||||
|
-- make sure signal doesn't already exist
|
||||||
|
if not tcbs.signal then
|
||||||
|
-- go ahead and assign signal
|
||||||
|
ildb.assign_signal_to_tcbs(pos, sigd)
|
||||||
|
-- assign influence point to itself
|
||||||
|
ildb.set_ip_signal(advtrains.roundfloorpts(pos), 1, pos)
|
||||||
|
end
|
||||||
|
-- in any case open the signalling form nouw
|
||||||
|
local control = player:get_player_control()
|
||||||
|
advtrains.interlocking.show_signal_form(pos, node, pname, control.aux1)
|
||||||
|
return
|
||||||
|
else
|
||||||
|
-- not an autosignal. Then show the TCB form
|
||||||
|
advtrains.interlocking.show_tcb_form(pos, pname)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- TCB Form
|
-- TCB Form
|
||||||
|
|
||||||
local function mktcbformspec(pos, side, tcbs, offset, pname)
|
local function mktcbformspec(pos, side, tcbs, offset, pname)
|
||||||
|
@ -666,7 +794,7 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte, calle
|
||||||
-- no route is active, and no route is so far defined
|
-- no route is active, and no route is so far defined
|
||||||
if not tcbs.signal then atwarn("signalling form missing signal?!", pos) return end -- safeguard, nothing else in this function checks tcbs.signal
|
if not tcbs.signal then atwarn("signalling form missing signal?!", pos) return end -- safeguard, nothing else in this function checks tcbs.signal
|
||||||
local caps = advtrains.interlocking.signal.get_signal_cap_level(tcbs.signal)
|
local caps = advtrains.interlocking.signal.get_signal_cap_level(tcbs.signal)
|
||||||
if caps >= 3 then
|
if caps >= 4 then
|
||||||
-- offer user the "block signal mode"
|
-- offer user the "block signal mode"
|
||||||
form = form.."label[0.5,2.5;No routes are yet defined.]"
|
form = form.."label[0.5,2.5;No routes are yet defined.]"
|
||||||
if hasprivs then
|
if hasprivs then
|
||||||
|
@ -683,6 +811,10 @@ function advtrains.interlocking.show_signalling_form(sigd, pname, sel_rte, calle
|
||||||
.."Sets a route into the section ahead with auto-working set on\n"
|
.."Sets a route into the section ahead with auto-working set on\n"
|
||||||
.."Short block: This signal becomes distant signal for next signal.]"
|
.."Short block: This signal becomes distant signal for next signal.]"
|
||||||
end
|
end
|
||||||
|
elseif caps >= 3 then
|
||||||
|
-- it's a buffer!
|
||||||
|
form = form.."label[0.5,2.5;This is an always-halt signal (e.g. a buffer)\n"
|
||||||
|
.."No routes can be set from here.]"
|
||||||
else
|
else
|
||||||
-- signal caps say it cannot be route start/end
|
-- signal caps say it cannot be route start/end
|
||||||
form = form.."label[0.5,2.5;This is a Non-Halt signal (e.g. pure distant signal)\n"
|
form = form.."label[0.5,2.5;This is a Non-Halt signal (e.g. pure distant signal)\n"
|
||||||
|
|
|
@ -600,6 +600,35 @@ advtrains.register_tracks("default", {
|
||||||
--bumpers still use the old texture until the models are redone.
|
--bumpers still use the old texture until the models are redone.
|
||||||
description=attrans("Bumper"),
|
description=attrans("Bumper"),
|
||||||
formats={},
|
formats={},
|
||||||
|
get_additional_definiton = function(def, preset, suffix, rotation)
|
||||||
|
-- 2024-11-25: Bumpers get the additional feature of being both a signal and a self-contained TCB, when interlocking is used.
|
||||||
|
if advtrains.interlocking then
|
||||||
|
return {
|
||||||
|
-- use the special callbacks for self_tcb (see tcb_ts_ui.lua)
|
||||||
|
can_dig = advtrains.interlocking.self_tcb_make_can_dig_callback(true),
|
||||||
|
after_dig_node = advtrains.interlocking.self_tcb_make_after_dig_callback(true),
|
||||||
|
after_place_node = advtrains.interlocking.self_tcb_make_after_place_callback(true, true),
|
||||||
|
on_rightclick = advtrains.interlocking.self_tcb_make_on_rightclick_callback(false, true),
|
||||||
|
advtrains = {
|
||||||
|
main_aspects = {
|
||||||
|
-- No main aspects, it always shows Stop.
|
||||||
|
-- But we need to define the table so that signal caplevel is 3
|
||||||
|
},
|
||||||
|
apply_aspect = function(pos, node, main_aspect, rem_aspect, rem_aspinfo)
|
||||||
|
-- is a no-op for bumpers, it always shows Stop
|
||||||
|
end,
|
||||||
|
get_aspect_info = function(pos, main_aspect)
|
||||||
|
-- it always shows Stop
|
||||||
|
return advtrains.interlocking.signal.ASPI_HALT
|
||||||
|
end,
|
||||||
|
distant_support = false, -- not a distant
|
||||||
|
route_role = "end", -- the end is nigh!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return {} -- no additional defs when interlocking is not used
|
||||||
|
end
|
||||||
|
end,
|
||||||
}, advtrains.ap.t_30deg_straightonly)
|
}, advtrains.ap.t_30deg_straightonly)
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = 'advtrains:dtrack_bumper_placer 2',
|
output = 'advtrains:dtrack_bumper_placer 2',
|
||||||
|
|
|
@ -4,4 +4,4 @@ description=Default track set for Advanced Trains
|
||||||
author=orwell96
|
author=orwell96
|
||||||
|
|
||||||
depends=advtrains
|
depends=advtrains
|
||||||
optional_depends=mesecons,digtron
|
optional_depends=mesecons,digtron,advtrains_interlocking
|
||||||
|
|
Loading…
Reference in New Issue