aboutsummaryrefslogtreecommitdiff
path: root/advtrains_interlocking/route_prog.lua
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains_interlocking/route_prog.lua')
-rw-r--r--advtrains_interlocking/route_prog.lua89
1 files changed, 55 insertions, 34 deletions
diff --git a/advtrains_interlocking/route_prog.lua b/advtrains_interlocking/route_prog.lua
index e67abd7..2573ba4 100644
--- a/advtrains_interlocking/route_prog.lua
+++ b/advtrains_interlocking/route_prog.lua
@@ -67,6 +67,9 @@ minetest.register_entity("advtrains_interlocking:routesprite", {
collisionbox = {-0.2,-0.2,-0.2, 0.2,0.2,0.2},
visual_size = {x=1, y=1},
on_punch = function(self)
+ if self.callback then
+ self.callback()
+ end
self.object:remove()
end,
get_staticdata = function() return "STATIC" end,
@@ -79,7 +82,7 @@ minetest.register_entity("advtrains_interlocking:routesprite", {
-- 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)
+local function routesprite(context, pos, key, img, itex, callback)
if not markerent[context] then
markerent[context] = {}
end
@@ -94,6 +97,10 @@ local function routesprite(context, pos, key, img, itex)
textures = {img},
})
+ if callback then
+ obj:get_luaentity().callback = callback
+ end
+
markerent[context][key] = obj
end
@@ -101,19 +108,27 @@ end
Route definition:
route = {
name = <string>
- tcbpath = {
- [n] = <sigd>
- }
- pcfix = {
- [<pts>] = "state"
+ [n] = {
+ next = <sigd>, -- of the next (note: next) TCB on the route
+ locks = {<pts> = "state"} -- route locks of this route segment
}
}
-The first item in the TCB path is always the start signal of this route,
+The first item in the TCB path (namely i=0) is always the start signal of this route,
so this is left out.
-
+All subsequent entries, starting from 1, contain:
+- all route locks of the segment on TS between the (i-1). and the i. TCB
+- the next TCB signal describer in proceeding direction of the route.
]]--
+local function chat(pname, message)
+ minetest.chat_send_player(pname, "[Route programming] "..message)
+end
+local function clear_lock(locks, pname, pts)
+ locks[pts] = nil
+ chat(pname, pts.." is no longer affected when this route is set.")
+end
+
function advtrains.interlocking.clear_visu_context(context)
if not markerent[context] then return end
for key, obj in pairs(markerent[context]) do
@@ -123,8 +138,9 @@ function advtrains.interlocking.clear_visu_context(context)
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)
+-- e.g. prog_<player> or vis_<pts> for later visualizations
+-- last 2 parameters are only to be used in the context of route programming!
+function advtrains.interlocking.visualize_route(origin, route, context, tmp_lcks, pname)
advtrains.interlocking.clear_visu_context(context)
local oyaw = 0
@@ -134,19 +150,27 @@ function advtrains.interlocking.visualize_route(origin, route, context)
end
routemarker(context, origin.p, "rte_origin", "at_il_route_start.png", oyaw, route.name)
- for k,sigd in ipairs(route.tcbpath) do
+ for k,v in ipairs(route) do
+ local sigd = v.next
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
+ if k == #route then img = "at_il_route_end.png" end
routemarker(context, sigd.p, "rte"..k, img, yaw, route.name.." #"..k)
+ for pts, state in pairs(v.locks) do
+ local pos = minetest.string_to_pos(pts)
+ routesprite(context, pos, "fix"..k..pts, "at_il_route_lock.png", "Fixed in state '"..state.."' by route "..route.name.." until segment #"..k.." is freed.")
+ end
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)
+ if tmp_lcks then
+ for pts, state in pairs(tmp_lcks) do
+ local pos = minetest.string_to_pos(pts)
+ routesprite(context, pos, "fixp"..pts, "at_il_route_lock_edit.png", "Fixed in state '"..state.."' by route "..route.name.." (punch to unfix)",
+ function() clear_lock(tmp_lcks, pname, pts) end)
+ end
end
end
@@ -158,25 +182,21 @@ function advtrains.interlocking.init_route_prog(pname, sigd)
origin = sigd,
route = {
name = "PROG["..pname.."]",
- tcbpath = {},
- pcfix = {},
- }
+ },
+ tmp_lcks = {},
}
- advtrains.interlocking.visualize_route(sigd, player_rte_prog[pname].route, "prog_"..pname)
+ advtrains.interlocking.visualize_route(sigd, player_rte_prog[pname].route, "prog_"..pname, player_rte_prog[pname].tmp_lcks, 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)
- if #route.tcbpath == 0 then
+ if #route == 0 then
return origin
end
- return route.tcbpath[#route.tcbpath]
+ return route[#route].next
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
@@ -222,27 +242,29 @@ minetest.register_on_punchnode(function(pos, node, player, pointed_thing)
chat(pname, "Previous and this TCB belong to different track sections!")
return
end
+ -- TODO check the path: are all route turnouts locked to the right position?
+
-- everything worked, just add the other side to the list
- table.insert(rp.route.tcbpath, {p = tcbpos, s = found})
+ table.insert(rp.route, {next = {p = tcbpos, s = found}, locks = rp.tmp_lcks})
+ rp.tmp_lcks = {}
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)
+ advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, 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.")
+ if rp.tmp_lcks[pts] then
+ clear_lock(rp.tmp_lcks, pname, pts)
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.")
+ rp.tmp_lcks[pts] = state
+ chat(pname, pts.." is held in "..state.." position when this route is set and freed ")
end
- advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname)
+ advtrains.interlocking.visualize_route(rp.origin, rp.route, "prog_"..pname, rp.tmp_lcks, pname)
return
end
@@ -261,7 +283,7 @@ minetest.register_chatcommand("at_rp_set",
end
local rp = player_rte_prog[pname]
if rp then
- if #rp.route.tcbpath <= 0 then
+ if #rp.route <= 0 then
return false, "Cannot program route without a target"
end
rp.route.name = param
@@ -337,4 +359,3 @@ minetest.register_chatcommand("at_rp_discard",
-- 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.