From 3256c2778d626548541bcdfabf3026f781a2287c Mon Sep 17 00:00:00 2001 From: orwell96 Date: Wed, 7 Oct 2020 17:20:47 +0200 Subject: Forbid track modification when train, IP or TCB is on it, better handle removing of TCBs (H#149) --- advtrains/locale/advtrains.de.tr | 5 ++++ advtrains/trackplacer.lua | 50 ++++++++++++++++++++++++++++++------ advtrains/tracks.lua | 24 ++++++++++++++--- advtrains_interlocking/database.lua | 8 ++++++ advtrains_interlocking/tcb_ts_ui.lua | 28 +++++++++++++++----- 5 files changed, 97 insertions(+), 18 deletions(-) diff --git a/advtrains/locale/advtrains.de.tr b/advtrains/locale/advtrains.de.tr index 520b200..f0d797f 100644 --- a/advtrains/locale/advtrains.de.tr +++ b/advtrains/locale/advtrains.de.tr @@ -64,3 +64,8 @@ Passenger Wagon=Passagierwaggon Box wagon=Güterwaggon Subway Passenger Wagon=U-Bahn-Waggon The wagon's inventory is not empty!=Das Inventar dieses Waggons ist nicht leer! +This track can not be changed!=Diese Schiene kann nicht geändert werden! +This track can not be rotated!=Diese Schiene kann nicht gedreht werden! +Position is occupied by a train.=Ein Zug steht an dieser Position. +There's a Track Circuit Break here.=Hier ist eine Gleisabschnittsgrenze (TCB). +There's a Signal Influence Point here.=Hier ist ein Signal-Beeinflussungspunkt. diff --git a/advtrains/trackplacer.lua b/advtrains/trackplacer.lua index db65cd9..904d851 100644 --- a/advtrains/trackplacer.lua +++ b/advtrains/trackplacer.lua @@ -120,6 +120,11 @@ function tp.rail_and_can_be_bent(originpos, conn) return advtrains.conn_matches_to(conn, cconns) end end + -- If the rail is not allowed to be modified, also only use if already in desired direction + if not advtrains.can_dig_or_modify_track(pos) then + local cconns=advtrains.get_track_connections(node.name, node.param2) + return advtrains.conn_matches_to(conn, cconns) + end --rail at other end? local adj1, adj2=tp.find_already_connected(pos) if adj1 and adj2 then @@ -326,15 +331,7 @@ minetest.register_craftitem("advtrains:trackworker",{ local node=minetest.get_node(pos) --if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end - if advtrains.get_train_at_pos(pos) then return end - if has_aux1_down then - --feature: flip the node by 180° - --i've always wanted this! - advtrains.ndb.swap_node(pos, {name=node.name, param2=(node.param2+2)%4}) - return - end - local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$") --atdebug(node.name.."\npattern recognizes:"..nnprefix.." / "..suffix.." / "..rotation) --atdebug("nntab: ",tp.tracks[nnprefix]) @@ -346,6 +343,28 @@ minetest.register_craftitem("advtrains:trackworker",{ return end end + + -- check if the node is modify-protected + if advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then + -- is a track, we can query + local can_modify, reason = advtrains.can_dig_or_modify_track(pos) + if not can_modify then + local str = attrans("This track can not be rotated!") + if reason then + str = str .. " " .. reason + end + minetest.chat_send_player(placer:get_player_name(), str) + return + end + end + + if has_aux1_down then + --feature: flip the node by 180° + --i've always wanted this! + advtrains.ndb.swap_node(pos, {name=node.name, param2=(node.param2+2)%4}) + return + end + local modext=tp.tracks[nnprefix].twrotate[suffix] if rotation==modext[#modext] then --increase param2 @@ -390,6 +409,21 @@ minetest.register_craftitem("advtrains:trackworker",{ return end end + + -- check if the node is modify-protected + if advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then + -- is a track, we can query + local can_modify, reason = advtrains.can_dig_or_modify_track(pos) + if not can_modify then + local str = attrans("This track can not be changed!") + if reason then + str = str .. " " .. reason + end + minetest.chat_send_player(user:get_player_name(), str) + return + end + end + local nextsuffix=tp.tracks[nnprefix].twcycle[suffix] advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..nextsuffix..rotation, param2=node.param2}) diff --git a/advtrains/tracks.lua b/advtrains/tracks.lua index 45d45ff..6799c40 100644 --- a/advtrains/tracks.lua +++ b/advtrains/tracks.lua @@ -478,9 +478,7 @@ function advtrains.register_tracks(tracktype, def, preset) not_blocking_trains=1, }, - can_dig=function(pos) - return not advtrains.get_train_at_pos(pos) - end, + can_dig = advtrains.can_dig_or_modify_track, after_dig_node=function(pos) advtrains.ndb.update(pos) end, @@ -602,6 +600,26 @@ function advtrains.get_track_connections(name, param2) return advtrains.rotate_conn_by(nodedef.at_conns, noderot*AT_CMAX/4), (nodedef.at_rail_y or 0), tracktype end +-- 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" +function advtrains.can_dig_or_modify_track(pos) + if advtrains.get_train_at_pos(pos) then + return false, attrans("Position is occupied by a train.") + end + -- interlocking: tcb, signal IP a.s.o. + if advtrains.interlocking then + -- TCB? + if advtrains.interlocking.db.get_tcb(pos) then + return false, attrans("There's a Track Circuit Break here.") + end + -- signal ip? + if advtrains.interlocking.db.is_ip_at(pos) then + return false, attrans("There's a Signal Influence Point here.") + end + end + return true +end + -- slope placer. Defined in register_tracks. --crafted with rail and gravel local sl={} diff --git a/advtrains_interlocking/database.lua b/advtrains_interlocking/database.lua index 8df874f..e2c9edc 100644 --- a/advtrains_interlocking/database.lua +++ b/advtrains_interlocking/database.lua @@ -526,6 +526,14 @@ function ildb.set_sigd_for_signal(pos, sigd) signal_assignments[pts] = sigd end +-- checks if there's any influence point set to this position +function ildb.is_ip_at(pos) + local pts = advtrains.roundfloorpts(pos) + if influence_points[pts] then + return true + end + return false +end -- checks if a signal is influencing here function ildb.get_ip_signal(pts, connid) diff --git a/advtrains_interlocking/tcb_ts_ui.lua b/advtrains_interlocking/tcb_ts_ui.lua index c07a7a2..da318a7 100644 --- a/advtrains_interlocking/tcb_ts_ui.lua +++ b/advtrains_interlocking/tcb_ts_ui.lua @@ -49,12 +49,13 @@ minetest.register_node("advtrains_interlocking:tcb_node", { local tcbpts = meta:get_string("tcb_pos") if tcbpts ~= "" then local tcbpos = minetest.string_to_pos(tcbpts) - advtrains.interlocking.show_tcb_form(tcbpos, pname) - else - if not minetest.check_player_privs(pname, "interlocking") then - minetest.chat_send_player(pname, "Insufficient privileges to use this!") - return + local tcb = ildb.get_tcb(tcbpos) + if tcb then + advtrains.interlocking.show_tcb_form(tcbpos, pname) + else + minetest.chat_send_player(pname, "This TCB has been removed. Please dig marker.") end + else --unconfigured minetest.chat_send_player(pname, "Configuring TCB: Please punch the rail you want to assign this TCB to.") @@ -88,6 +89,11 @@ minetest.register_node("advtrains_interlocking:tcb_node", { if not tcb then return true end for connid=1,2 do if tcb[connid].ts_id or tcb[connid].signal then + minetest.chat_send_player(pname, "Can't remove TCB: Both sides must have no track section and no signal assigned!") + return false + end + if not ildb.may_modify_tcbs(tcb[connid]) then + minetest.chat_send_player(pname, "Can't remove TCB: Side "..connid.." forbids modification (shouldn't happen).") return false end end @@ -99,7 +105,15 @@ minetest.register_node("advtrains_interlocking:tcb_node", { local tcbpts = oldmetadata.fields.tcb_pos if tcbpts and tcbpts ~= "" then local tcbpos = minetest.string_to_pos(tcbpts) - ildb.remove_tcb(tcbpos) + local success = ildb.remove_tcb(tcbpos) + if success and player then + minetest.chat_send_player(player:get_player_name(), "TCB has been removed.") + else + minetest.chat_send_player(player:get_player_name(), "Failed to remove TCB!") + minetest.set_node(pos, oldnode) + local meta = minetest.get_meta(pos) + meta:set_string("tcb_pos", minetest.pos_to_string(tcbpos)) + end end end, }) @@ -118,7 +132,7 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing) local ok = ildb.create_tcb(pos) if not ok then - minetest.chat_send_player(pname, "Configuring TCB: TCB already exists at this position. Aborted.") + minetest.chat_send_player(pname, "Configuring TCB: TCB already exists at this position! It has now been re-assigned.") end ildb.sync_tcb_neighbors(pos, 1) -- cgit v1.2.3