aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--init.lua8
-rw-r--r--textures/advtrains_dtrack_rail.pngbin2810 -> 2810 bytes
-rw-r--r--tracks.lua68
-rw-r--r--trainlogic.lua68
4 files changed, 128 insertions, 16 deletions
diff --git a/init.lua b/init.lua
index dcf2524..c535668 100644
--- a/init.lua
+++ b/init.lua
@@ -4,10 +4,10 @@ advtrains={}
advtrains.modpath = minetest.get_modpath("advtrains")
-print=function(text)
- minetest.log("action", tostring(text) or "<non-string>")
-end
-
+--print=function(text)
+-- minetest.log("action", tostring(text) or "<non-string>")
+--end
+print = function(t) minetest.log("action", t) minetest.chat_send_all(t) end
dofile(advtrains.modpath.."/helpers.lua");
dofile(advtrains.modpath.."/debugitems.lua");
diff --git a/textures/advtrains_dtrack_rail.png b/textures/advtrains_dtrack_rail.png
index 5fb0c67..568e533 100644
--- a/textures/advtrains_dtrack_rail.png
+++ b/textures/advtrains_dtrack_rail.png
Binary files differ
diff --git a/tracks.lua b/tracks.lua
index 9a2b462..7ec0ab3 100644
--- a/tracks.lua
+++ b/tracks.lua
@@ -237,8 +237,7 @@ function advtrains.register_tracks(tracktype, def, preset)
}, def.common or {})
--make trackplacer base def
advtrains.trackplacer.register_tracktype(def.nodename_prefix, preset.tpdefault)
- advtrains.trackplacer.register_track_placer(def.nodename_prefix, def.texture_prefix, def.description)
-
+ advtrains.trackplacer.register_track_placer(def.nodename_prefix, def.texture_prefix, def.description)
for suffix, conns in pairs(preset.variant) do
for rotid, rotation in ipairs(preset.rotation) do
if not def.formats[suffix] or def.formats[suffix][rotid] then
@@ -246,6 +245,7 @@ function advtrains.register_tracks(tracktype, def, preset)
if preset.switch[suffix] then
switchfunc, mesecontbl=make_switchfunc(preset.switch[suffix]..rotation, preset.switchmc[suffix])
end
+
minetest.register_node(def.nodename_prefix.."_"..suffix..rotation, advtrains.merge_tables(
common_def,
make_overdef(
@@ -293,6 +293,70 @@ function advtrains.get_track_connections(name, param2)
return (nodedef.connect1 + 4 * noderot)%16, (nodedef.connect2 + 4 * noderot)%16, nodedef.rely1 or 0, nodedef.rely2 or 0, nodedef.railheight or 0
end
+--detector code
+--holds a table with nodes on which trains are on.
+
+advtrains.detector = {}
+advtrains.detector.on_node = {}
+advtrains.detector.on_node_restore = {}
+--set if paths were invalidated before. tells trainlogic.lua to call advtrains.detector.finalize_restore()
+advtrains.detector.clean_step_before = false
+
+--when train enters a node, call this
+--The entry already being contained in advtrains.detector.on_node_restore will not trigger an on_train_enter event on the node. (when path is reset, this is saved).
+function advtrains.detector.enter_node(pos, train_id)
+ local pts = minetest.pos_to_string(advtrains.round_vector_floor_y(pos))
+ --print("enterNode "..pts.." "..train_id)
+ if not advtrains.detector.on_node[pts] then
+ advtrains.detector.on_node[pts]=train_id
+ if advtrains.detector.on_node_restore[pts] then
+ advtrains.detector.on_node_restore[pts]=nil
+ else
+ advtrains.detector.call_enter_callback(advtrains.round_vector_floor_y(pos), train_id)
+ end
+ end
+end
+function advtrains.detector.leave_node(pos, train_id)
+ local pts = minetest.pos_to_string(advtrains.round_vector_floor_y(pos))
+ --print("leaveNode "..pts.." "..train_id)
+ if advtrains.detector.on_node[pts] then
+ advtrains.detector.call_leave_callback(advtrains.round_vector_floor_y(pos), train_id)
+ advtrains.detector.on_node[pts]=nil
+ end
+end
+--called immediately before invalidating paths
+function advtrains.detector.setup_restore()
+ --print("setup_restore")
+ advtrains.detector.on_node_restore = advtrains.detector.on_node
+ advtrains.detector.on_node = {}
+end
+--called one step after invalidating paths, when all trains have restored their path and called enter_node for their contents.
+function advtrains.detector.finalize_restore()
+ --print("finalize_restore")
+ for pts, train_id in pairs(advtrains.detector.on_node_restore) do
+ --print("called leave callback "..pts.." "..train_id)
+ advtrains.detector.call_leave_callback(minetest.string_to_pos(pts), train_id)
+ end
+ advtrains.detector.on_node_restore = {}
+end
+function advtrains.detector.call_enter_callback(pos, train_id)
+ --print("instructed to call enter calback")
+
+ local node = minetest.get_node(pos) --this spares the check if node is nil, it has a name in any case
+ local mregnode=minetest.registered_nodes[node.name]
+ if mregnode and mregnode.advtrains and mregnode.advtrains.on_train_enter then
+ mregnode.advtrains.on_train_enter(pos, train_id)
+ end
+end
+function advtrains.detector.call_leave_callback(pos, train_id)
+ --print("instructed to call leave calback")
+
+ local node = minetest.get_node(pos) --this spares the check if node is nil, it has a name in any case
+ local mregnode=minetest.registered_nodes[node.name]
+ if mregnode and mregnode.advtrains and mregnode.advtrains.on_train_leave then
+ mregnode.advtrains.on_train_leave(pos, train_id)
+ end
+end
--END code, BEGIN definition
--definition format: ([] optional)
--[[{
diff --git a/trainlogic.lua b/trainlogic.lua
index 37d7b86..5b9390c 100644
--- a/trainlogic.lua
+++ b/trainlogic.lua
@@ -155,6 +155,12 @@ minetest.register_globalstep(function(dtime)
for k,v in pairs(advtrains.trains) do
advtrains.train_step(k, v, dtime)
end
+
+ --see tracks.lua
+ if advtrains.detector.clean_step_before then
+ advtrains.detector.finalize_restore()
+ end
+
printbm("trainsteps", t)
endstep()
end)
@@ -204,6 +210,41 @@ function advtrains.train_step(id, train, dtime)
if train.tarvelocity<0 then train.tarvelocity=0 end
end
+ --update advtrains.detector
+ if not train.detector_old_index then
+ train.detector_old_index = math.floor(train_end_index)
+ train.detector_old_end_index = math.floor(train_end_index)
+ end
+ local ifo, ifn, ibo, ibn = train.detector_old_index, math.floor(train.index), train.detector_old_end_index, math.floor(train_end_index)
+ if ifn>ifo then
+ for i=ifo, ifn do
+ if path[i] then
+ advtrains.detector.enter_node(path[i], id)
+ end
+ end
+ elseif ifn<ifo then
+ for i=ifn, ifo do
+ if path[i] then
+ advtrains.detector.leave_node(path[i], id)
+ end
+ end
+ end
+ if ibn<ibo then
+ for i=ibn, ibn do
+ if path[i] then
+ advtrains.detector.enter_node(path[i], id)
+ end
+ end
+ elseif ibn>ibo then
+ for i=ibo, ibn do
+ if path[i] then
+ advtrains.detector.leave_node(path[i], id)
+ end
+ end
+ end
+ train.detector_old_index = math.floor(train.index)
+ train.detector_old_end_index = math.floor(train_end_index)
+
if train_moves then
--check for collisions by finding objects
--front
@@ -224,23 +265,26 @@ function advtrains.train_step(id, train, dtime)
end
end
end
- --new train collisions (only search in the direction of the driving train)
- local coll_search_radius=2
- local coll_grace=0
+ --heh, new collision again.
+ --this time, based on NODES and the advtrains.detector.on_node table.
local collpos
+ local coll_grace=1
if train.velocity>0 then
collpos=advtrains.get_real_index_position(path, train.index-coll_grace)
elseif train.velocity<0 then
collpos=advtrains.get_real_index_position(path, train_end_index+coll_grace)
end
if collpos then
- local objrefs=minetest.get_objects_inside_radius(collpos, coll_search_radius)
- for _,v in pairs(objrefs) do
- local le=v:get_luaentity()
- if le and le.is_wagon and le.initialized and le.train_id~=id then
- train.recently_collided_with_env=true
- train.velocity=-0.5*train.velocity
- train.tarvelocity=0
+ local rcollpos=advtrains.round_vector_floor_y(collpos)
+ for x=-1,1 do
+ for z=-1,1 do
+ local testpts=minetest.pos_to_string(vector.add(rcollpos, {x=x, y=0, z=z}))
+ if advtrains.detector.on_node[testpts] and advtrains.detector.on_node[testpts]~=id then
+ --collides
+ train.recently_collided_with_env=true
+ train.velocity=-0.5*train.velocity
+ train.tarvelocity=0
+ end
end
end
end
@@ -775,6 +819,10 @@ function advtrains.invalidate_all_paths()
v.index=nil
v.min_index_on_track=nil
v.max_index_on_track=nil
+
+ advtrains.detector.setup_restore()
+ v.detector_old_index=nil
+ v.detector_old_end_index=nil
end
end