diff options
-rw-r--r-- | init.lua | 8 | ||||
-rw-r--r-- | textures/advtrains_dtrack_rail.png | bin | 2810 -> 2810 bytes | |||
-rw-r--r-- | tracks.lua | 68 | ||||
-rw-r--r-- | trainlogic.lua | 68 |
4 files changed, 128 insertions, 16 deletions
@@ -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 Binary files differindex 5fb0c67..568e533 100644 --- a/textures/advtrains_dtrack_rail.png +++ b/textures/advtrains_dtrack_rail.png @@ -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 |