aboutsummaryrefslogtreecommitdiff
path: root/advtrains/tracks.lua
diff options
context:
space:
mode:
authororwell96 <orwell@bleipb.de>2017-10-25 11:49:34 +0200
committerorwell96 <orwell@bleipb.de>2017-10-25 11:49:34 +0200
commitf1a8b4f505313f3b2c37ced2dd3402e2740889fb (patch)
tree8bf4bd99774ad7e7f5b48edcd3598bafe722ba57 /advtrains/tracks.lua
parent1f9a9062e022c401826155efd3cd45a479d50c15 (diff)
downloadadvtrains-f1a8b4f505313f3b2c37ced2dd3402e2740889fb.tar.gz
advtrains-f1a8b4f505313f3b2c37ced2dd3402e2740889fb.tar.bz2
advtrains-f1a8b4f505313f3b2c37ced2dd3402e2740889fb.zip
Implement multi-occupation in detector.on_node table to finally fix collisions
Diffstat (limited to 'advtrains/tracks.lua')
-rw-r--r--advtrains/tracks.lua57
1 files changed, 54 insertions, 3 deletions
diff --git a/advtrains/tracks.lua b/advtrains/tracks.lua
index fa7f84d..3771090 100644
--- a/advtrains/tracks.lua
+++ b/advtrains/tracks.lua
@@ -430,20 +430,71 @@ end
advtrains.detector = {}
advtrains.detector.on_node = {}
-function advtrains.detector.enter_node(pos, train_id)
+--Returns true when position is occupied by a train other than train_id, false when occupied by the same train as train_id and nil in case there's no train at all
+function advtrains.detector.occupied(pos, train_id)
+ local ppos=advtrains.round_vector_floor_y(pos)
+ local pts=minetest.pos_to_string(ppos)
+ local s=advtrains.detector.on_node[pts]
+ if not s then return nil end
+ if s==train_id then return false end
+ --in case s is a table, it's always occupied by another train
+ return true
+end
+-- If given a train id as second argument, this is considered as 'not there'.
+-- Returns the train id of (one of, nondeterministic) the trains at this position
+function advtrains.detector.get(pos, train_id)
local ppos=advtrains.round_vector_floor_y(pos)
local pts=minetest.pos_to_string(ppos)
- advtrains.detector.on_node[pts]=train_id
+ local s=advtrains.detector.on_node[pts]
+ if not s then return nil end
+ if type(s)=="table" then
+ for _,t in ipairs(s) do
+ if t~=train_id then return t end
+ end
+ return nil
+ end
+ return s
+end
+
+function advtrains.detector.enter_node(pos, train_id)
+ advtrains.detector.stay_node(pos, train_id)
+ local ppos=advtrains.round_vector_floor_y(pos)
advtrains.detector.call_enter_callback(ppos, train_id)
end
function advtrains.detector.leave_node(pos, train_id)
local ppos=advtrains.round_vector_floor_y(pos)
+ local pts=minetest.pos_to_string(ppos)
+ local s=advtrains.detector.on_node[pts]
+ if type(s)=="table" then
+ local i
+ for j,t in ipairs(s) do
+ if t==train_id then i=j end
+ end
+ if not i then return end
+ s=table.remove(s,i)
+ if #s==0 then
+ s=nil
+ elseif #s==1 then
+ s=s[1]
+ end
+ advtrains.detector.on_node[pts]=s
+ else
+ advtrains.detector.on_node[pts]=nil
+ end
advtrains.detector.call_leave_callback(ppos, train_id)
end
function advtrains.detector.stay_node(pos, train_id)
local ppos=advtrains.round_vector_floor_y(pos)
local pts=minetest.pos_to_string(ppos)
- advtrains.detector.on_node[pts]=train_id
+
+ local s=advtrains.detector.on_node[pts]
+ if not s then
+ advtrains.detector.on_node[pts]=train_id
+ elseif type(s)=="string" then
+ advtrains.detector.on_node[pts]={s, train_id}
+ elseif type(s)=="table" then
+ advtrains.detector.on_node[pts]=table.insert(s, train_id)
+ end
end