rewrite collision system again
this time, it is based on nodes that trains stand on. advtrains.detector (in tracks.lua) keeps a table with nodes that trains are standing /driving on. This will be used now for detector rails.
This commit is contained in:
parent
6a0186f042
commit
ab652da5f4
8
init.lua
8
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");
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
66
tracks.lua
66
tracks.lua
|
@ -238,7 +238,6 @@ function advtrains.register_tracks(tracktype, def, preset)
|
|||
--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)
|
||||
|
||||
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)
|
||||
--[[{
|
||||
|
|
|
@ -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,20 +265,22 @@ 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
|
||||
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
|
||||
|
@ -245,6 +288,7 @@ function advtrains.train_step(id, train, dtime)
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--check for any trainpart entities if they have been unloaded. do this only if train is near a player, to not spawn entities into unloaded areas
|
||||
train.check_trainpartload=(train.check_trainpartload or 0)-dtime
|
||||
local node_range=(math.max((minetest.setting_get("active_block_range") or 0),1)*16)
|
||||
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue