From 24b0639c5f057ccb0fccc3c65be923bee1b571db Mon Sep 17 00:00:00 2001 From: orwell96 Date: Thu, 17 May 2018 21:37:01 +0200 Subject: Mainly make collisions and coupling work Missing: ATC stuff, yaw problems --- advtrains/atc.lua | 4 +- advtrains/couple.lua | 20 ++--- advtrains/occupation.lua | 40 ++++++++-- advtrains/path.lua | 16 ++-- advtrains/tracks.lua | 94 ---------------------- advtrains/trainlogic.lua | 151 +++++++++++++++++++++++++---------- advtrains/wagons.lua | 44 +++++----- advtrains_luaautomation/atc_rail.lua | 23 +++--- 8 files changed, 201 insertions(+), 191 deletions(-) diff --git a/advtrains/atc.lua b/advtrains/atc.lua index 1d3b04c..480c043 100644 --- a/advtrains/atc.lua +++ b/advtrains/atc.lua @@ -30,7 +30,7 @@ function atc.send_command(pos, par_tid) local pts=minetest.pos_to_string(pos) if atc.controllers[pts] then --atprint("Called send_command at "..pts) - local train_id = par_tid or advtrains.detector.get(pos) -- TODO: succesively replace those detector calls! + local train_id = par_tid or advtrains.get_train_at_pos(pos) if train_id then if advtrains.trains[train_id] then --atprint("send_command inside if: "..sid(train_id)) @@ -131,7 +131,7 @@ advtrains.atc_function = function(def, preset, suffix, rotation) local pts=minetest.pos_to_string(pos) local _, conns=advtrains.get_rail_info_at(pos, advtrains.all_tracktypes) atc.controllers[pts]={command=fields.command} - if advtrains.detector.get(pos) then + if #advtrains.occ.get_trains_at(pos) > 0 then atc.send_command(pos) end end diff --git a/advtrains/couple.lua b/advtrains/couple.lua index b09961f..a4eecf4 100644 --- a/advtrains/couple.lua +++ b/advtrains/couple.lua @@ -44,19 +44,19 @@ minetest.register_entity("advtrains:discouple", { end, on_step=function(self, dtime) return advtrains.pcall(function() - local t=os.clock() if not self.wagon then self.object:remove() - atprint("Discouple: no wagon, destroying") return end --getyaw seems to be a reliable method to check if an object is loaded...if it returns nil, it is not. if not self.wagon.object:getyaw() then - atprint("Discouple: wagon no longer loaded, destroying") self.object:remove() return end - atprintbm("discouple_step", t) + if not self.wagon:train() and self.wagon:train().velocity > 0 then + self.object:remove() + return + end end) end, }) @@ -102,13 +102,13 @@ minetest.register_entity("advtrains:couple", { advtrains.train_ensure_init(self.train_id_2, train2) local id1, id2=self.train_id_1, self.train_id_2 - local bp1, bp2 = self.t1_is_backpos, self.t2_is_backpos - if not bp1 then + local bp1, bp2 = self.t1_is_front, self.t2_is_front + if bp1 then if train1.couple_lock_front then lockmarker(self.object) return end - if not bp2 then + if bp2 then if train2.couple_lock_front then lockmarker(self.object) return @@ -127,7 +127,7 @@ minetest.register_entity("advtrains:couple", { lockmarker(self.object) return end - if not bp2 then + if bp2 then if train2.couple_lock_front then lockmarker(self.object) return @@ -174,13 +174,13 @@ minetest.register_entity("advtrains:couple", { if not self.position_set then local tp1 - if not self.train1_is_backpos then + if self.t1_is_front then tp1=advtrains.path_get_interpolated(train1, train1.index) else tp1=advtrains.path_get_interpolated(train1, train1.end_index) end local tp2 - if not self.train2_is_backpos then + if self.t2_is_front then tp2=advtrains.path_get_interpolated(train2, train2.index) else tp2=advtrains.path_get_interpolated(train2, train2.end_index) diff --git a/advtrains/occupation.lua b/advtrains/occupation.lua index 6316bd3..99de521 100644 --- a/advtrains/occupation.lua +++ b/advtrains/occupation.lua @@ -56,7 +56,7 @@ Whenever a path gets invalidated or path items are deleted, their index counterp When a train needs to know whether a position is blocked by another train, it will (and is permitted to) query the train.index and train.end_index and compare them to the blocked position's index. -Callback system for 3rd-party path checkers: TODO +Callback system for 3rd-party path checkers: advtrains.te_register_on_new_path(func(id, train)) -- Called when a train's path is re-initalized, either when it was invalidated -- or the saves were just loaded @@ -72,6 +72,12 @@ advtrains.te_register_on_update(func(id, train)) -- It is ensured that on_new_path callbacks are executed prior to these callbacks whenever -- an invalidation or a reload occured. +advtrains.te_register_on_create(func(id, train)) +-- Called right after a train is created, right after the initial new_path callback +advtrains.te_register_on_remove(func(id, train)) +-- Called right before a train is deleted + + All callbacks are allowed to save certain values inside the train table, but they must ensure that those are reinitialized in the on_new_path callback. The on_new_path callback must explicitly set ALL OF those values to nil or to a new updated value, and must not rely on their existence. @@ -162,11 +168,13 @@ function o.check_collision(pos, train_id) if not t then return end local i = 1 while t[i] do - if t[i]~=train_id then + local ti = t[i] + if ti~=train_id then local idx = t[i+1] - local train = advtrains.trains[train_id] - advtrains.train_ensure_init(train_id, train) + local train = advtrains.trains[ti] + atdebug("checking train",t[i],"index",idx,"<>",train.index,train.end_index) if idx >= train.end_index and idx <= train.index then + atdebug("collides.") return true end end @@ -183,19 +191,39 @@ function o.get_occupations(train, index) local ppos, ontrack = advtrains.path_get(train, index) if not ontrack then atdebug("Train",train.id,"get_occupations requested off-track",index) - return {}, pos + return {}, ppos end local pos = advtrains.round_vector_floor_y(ppos) local t = occget(pos) + if not t then return {} end local r = {} local i = 1 local train_id = train.id while t[i] do if t[i]~=train_id then - r[train_id] = t[i+1] + r[t[i]] = t[i+1] end i = i + 2 end return r, pos end +-- Gets a mapping of train id's to indexes of trains that stand or drive over +-- returns (table with train_id->index), position +function o.get_trains_at(ppos) + local pos = advtrains.round_vector_floor_y(ppos) + local t = occget(pos) + if not t then return {} end + local r = {} + local i = 1 + while t[i] do + local train = advtrains.trains[t[i]] + local idx = t[i+1] + if train.end_index - 0.5 <= idx and idx <= train.index + 0.5 then + r[t[i]] = idx + end + i = i + 2 + end + return r +end + advtrains.occ = o diff --git a/advtrains/path.lua b/advtrains/path.lua index d1d7ad9..d810fd7 100644 --- a/advtrains/path.lua +++ b/advtrains/path.lua @@ -137,7 +137,7 @@ function advtrains.path_setrestore(train, invert) idx = train.end_index end - local pos, connid, frac = advtrains.path_getrestore(train, idx, invert) + local pos, connid, frac = advtrains.path_getrestore(train, idx, invert, true) train.last_pos = pos train.last_connid = connid @@ -145,23 +145,25 @@ function advtrains.path_setrestore(train, invert) end -- Get restore position, connid and frac (in this order) for a train that will originate at the passed index -- If invert is set, it will return path_cp and multiply frac by -1, in order to reverse the train there. -function advtrains.path_getrestore(train, index, invert) - local idx = train.index +function advtrains.path_getrestore(train, index, invert, tmp) + local idx = index local cns = train.path_cn if invert then - idx = train.end_index cns = train.path_cp end - fli = atfloor(train.index) + fli = atfloor(index) + advtrains.path_get(train, fli) if fli > train.path_trk_f then fli = train.path_trk_f end if fli < train.path_trk_b then fli = train.path_trk_b end - + if not tmp then + atdebug ("getrestore ",atround(train.index),"calc",atround(index),fli) + end return advtrains.path_get(train, fli), cns[fli], (idx - fli) * (invert and -1 or 1) @@ -359,7 +361,7 @@ function advtrains.path_clear_unused(train) train.path_cp[i] = nil train.path_cn[i] = nil train.path_dir[i+1] = nil - train.path_ext_b = i - 1 + train.path_ext_f = i - 1 end train.path_req_f = math.ceil(train.index) diff --git a/advtrains/tracks.lua b/advtrains/tracks.lua index f31fef6..eefff66 100644 --- a/advtrains/tracks.lua +++ b/advtrains/tracks.lua @@ -389,100 +389,6 @@ function advtrains.get_track_connections(name, param2) return advtrains.rotate_conn_by(nodedef.at_conns, noderot*AT_CMAX/4), (nodedef.at_rail_y or 0), tracktype end ---detector code ---holds a table with nodes on which trains are on. - -advtrains.detector = {} -advtrains.detector.on_node = {} - ---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) - 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) - - 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 - - - -function advtrains.detector.call_enter_callback(pos, train_id) - --atprint("instructed to call enter calback") - - local node = advtrains.ndb.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) - --atprint("instructed to call leave calback") - - local node = advtrains.ndb.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 - -- slope placer. Defined in register_tracks. --crafted with rail and gravel local sl={} diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua index 129722a..feb35b5 100644 --- a/advtrains/trainlogic.lua +++ b/advtrains/trainlogic.lua @@ -176,29 +176,24 @@ end -- Occupation Callback system -- see occupation.lua -local callbacks_new_path = {} -local callbacks_update = {} - -function advtrains.te_register_on_new_path(func) - assertt(func, "function") - table.insert(callbacks_new_path, func) -end -function advtrains.te_register_on_update(func) - assertt(func, "function") - table.insert(callbacks_update, func) -end - -local function run_callbacks_new_path(id, train) - for _,f in ipairs(callbacks_new_path) do - f(id, train) - end -end -local function run_callbacks_update(id, train) - for _,f in ipairs(callbacks_new_path) do - f(id, train) +local function mkcallback(name) + local callt = {} + advtrains["te_register_on_"..name] = function(func) + assertt(func, "function") + table.insert(callt, func) + end + return callt, function(id, train) + for _,f in ipairs(callt) do + f(id, train) + end end end +local callbacks_new_path, run_callbacks_new_path = mkcallback("new_path") +local callbacks_update, run_callbacks_update = mkcallback("update") +local callbacks_create, run_callbacks_create = mkcallback("create") +local callbacks_remove, run_callbacks_remove = mkcallback("remove") + -- train_ensure_init: responsible for creating a state that we can work on, after one of the following events has happened: -- - the train's path got cleared @@ -385,7 +380,7 @@ function advtrains.train_step_b(id, train, dtime) --- 4. move train --- train.index=train.index and train.index+((train.velocity/(train.path_dist[math.floor(train.index)] or 1))*dtime) or 0 - recalc_end_index() + recalc_end_index(train) end @@ -420,22 +415,21 @@ if train.no_step or train.wait_for_path then return end if train_moves then - local collpos + local collided = false local coll_grace=1 - local collindex = advtrains.path_get_index_by_offset(train, train.index, coll_grace) - collpos = advtrains.path_get(train, atround(collindex)) + local collindex = advtrains.path_get_index_by_offset(train, train.index, -coll_grace) + local collpos = advtrains.path_get(train, atround(collindex)) if collpos then local rcollpos=advtrains.round_vector_floor_y(collpos) for x=-train.extent_h,train.extent_h do for z=-train.extent_h,train.extent_h do local testpos=vector.add(rcollpos, {x=x, y=0, z=z}) --- 8a Check collision --- - if advtrains.occ.check_collision(testpos, id) then + if not collided and advtrains.occ.check_collision(testpos, id) then --collides - --advtrains.collide_and_spawn_couple(id, testpos, advtrains.detector.get(testpos, id), train.movedir==-1) train.velocity = 0 train.tarvelocity = 0 - atwarn("Train",id,"collided!") + collided = true end --- 8b damage players --- if not minetest.settings:get_bool("creative_mode") then @@ -499,7 +493,9 @@ advtrains.te_register_on_new_path(function(id, train) old_index = atround(train.index), old_end_index = atround(train.end_index), } + atdebug(id,"tnc init",train.index,train.end_index) end) + advtrains.te_register_on_update(function(id, train) local new_index = atround(train.index) local new_end_index = atround(train.end_index) @@ -507,14 +503,38 @@ advtrains.te_register_on_update(function(id, train) local old_end_index = train.tnc.old_end_index while old_index < new_index do old_index = old_index + 1 - local pos = advtrains.round_vector_floor_y(advtrains.path_get(old_index)) + local pos = advtrains.round_vector_floor_y(advtrains.path_get(train,old_index)) tnc_call_enter_callback(pos, id) end - while old_end_index > new_end_index do - local pos = advtrains.round_vector_floor_y(advtrains.path_get(old_end_index)) + while old_end_index < new_end_index do + local pos = advtrains.round_vector_floor_y(advtrains.path_get(train,old_end_index)) tnc_call_leave_callback(pos, id) - old_end_index = old_end_index - 1 + old_end_index = old_end_index + 1 end + train.tnc.old_index = new_index + train.tnc.old_end_index = new_end_index +end) + +advtrains.te_register_on_create(function(id, train) + local index = atround(train.index) + local end_index = atround(train.end_index) + while end_index <= index do + local pos = advtrains.round_vector_floor_y(advtrains.path_get(train,end_index)) + tnc_call_enter_callback(pos, id) + end_index = end_index + 1 + end + atdebug(id,"tnc create",train.index,train.end_index) +end) + +advtrains.te_register_on_remove(function(id, train) + local index = atround(train.index) + local end_index = atround(train.end_index) + while end_index <= index do + local pos = advtrains.round_vector_floor_y(advtrains.path_get(train,end_index)) + tnc_call_leave_callback(pos, id) + end_index = end_index + 1 + end + atdebug(id,"tnc remove",train.index,train.end_index) end) -- Calculates the indices where the window borders of the occupation windows are. @@ -572,9 +592,10 @@ function advtrains.create_new_train_at(pos, connid, ioff, trainparts) advtrains.trains[new_id] = t atdebug("Created new train:",t) - advtrains.train_ensure_init(new_id, advtrains.trains[new_id]) + run_callbacks_create(new_id, advtrains.trains[new_id]) + return new_id end @@ -583,9 +604,13 @@ function advtrains.remove_train(id) advtrains.train_ensure_init(id, train) + run_callbacks_remove(id, train) + advtrains.path_invalidate(train) + advtrains.couple_invalidate(train) local tp = train.trainparts + atdebug("Removing train",id,"leftover trainparts:",tp) advtrains.trains[id] = nil @@ -661,6 +686,8 @@ function advtrains.update_trainpart_properties(train_id, invert_flipstate) train.locomotives_in_train = count_l end + +local ablkrng = minetest.settings:get("active_block_range")*16 -- This function checks whether entities need to be spawned for certain wagons, and spawns them. function advtrains.spawn_wagons(train_id) local train = advtrains.trains[train_id] @@ -668,12 +695,23 @@ function advtrains.spawn_wagons(train_id) for i, w_id in ipairs(train.trainparts) do local data = advtrains.wagons[w_id] if data then + if data.train_id ~= train_id then + atwarn("Train",train_id,"Wagon #",1,": Saved train ID",data.train_id,"did not match!") + data.train_id = train_id + end if not data.object or not data.object:getyaw() then -- eventually need to spawn new object. check if position is loaded. local index = advtrains.path_get_index_by_offset(train, train.index, -data.pos_in_train) local pos = advtrains.path_get(train, atfloor(index)) - if minetest.get_node_or_nil(pos) then + local spawn = false + for _,p in pairs(minetest.get_connected_players()) do + if vector.distance(p:get_pos(),pos)<=ablkrng then + spawn = true + end + end + + if spawn then local wt = advtrains.get_wagon_prototype(data) local wagon = minetest.add_entity(pos, wt):get_luaentity() wagon:set_id(w_id) @@ -693,16 +731,15 @@ function advtrains.split_train_at_wagon(wagon_id) advtrains.train_ensure_init(old_id, train) - local index=advtrains.path_get_index_by_offset(train, train.index, -(data.pos_in_train + wagon.wagon_span)) + local index=advtrains.path_get_index_by_offset(train, train.index, - data.pos_in_train + wagon.wagon_span) -- find new initial path position for this train local pos, connid, frac = advtrains.path_getrestore(train, index) - -- build trainparts table, passing it directly to the train constructor local tp = {} for k,v in ipairs(train.trainparts) do - if k>=wagon.pos_in_trainparts then + if k >= data.pos_in_trainparts then table.insert(tp, v) train.trainparts[k]=nil end @@ -728,7 +765,7 @@ function advtrains.split_train_at_wagon(wagon_id) end -- coupling -local CPL_CHK_DST = 1 +local CPL_CHK_DST = -1 local CPL_ZONE = 2 -- train.couple_* contain references to ObjectRefs of couple objects, which contain all relevant information @@ -739,11 +776,24 @@ local function createcouple(pos, train1, t1_is_front, train2, t2_is_front) local le=obj:get_luaentity() le.train_id_1=train1.id le.train_id_2=train2.id - le.train1_is_backpos=not t1_is_front - le.train2_is_backpos=not t2_is_front + le.t1_is_front=t1_is_front + le.t2_is_front=t2_is_front + atdebug("created couple between",train1.id,t1_is_front,train2.id,t2_is_front) + if t1_is_front then + train1.cpl_front = obj + else + train1.cpl_back = obj + end + if t2_is_front then + train2.cpl_front = obj + else + train2.cpl_back = obj + end + end function advtrains.train_check_couples(train) + atdebug("rechecking couples") if train.cpl_front then if not train.cpl_front:getyaw() then -- objectref is no longer valid. reset. @@ -756,6 +806,7 @@ function advtrains.train_check_couples(train) for tid, idx in pairs(front_trains) do local other_train = advtrains.trains[tid] advtrains.train_ensure_init(tid, other_train) + atdebug(train.id,"front: ",idx,"on",tid,atround(other_train.index),atround(other_train.end_index)) if other_train.velocity == 0 then if idx>=other_train.index and idx<=other_train.index + CPL_ZONE then createcouple(pos, train, true, other_train, true) @@ -794,7 +845,17 @@ function advtrains.train_check_couples(train) end end - +function advtrains.couple_invalidate(train) + if train.cpl_back then + train.cpl_back:remove() + train.cpl_back = nil + end + if train.cpl_front then + train.cpl_front:remove() + train.cpl_front = nil + end + train.was_standing = nil +end -- relevant code for this comment is in couple.lua @@ -833,6 +894,9 @@ function advtrains.do_connect_trains(first_id, second_id) first.velocity=0 first.tarvelocity=0 first.couple_lck_back=tmp_cpl_lck + + advtrains.update_trainpart_properties(first_id) + advtrains.couple_invalidate(first) return true end @@ -845,8 +909,12 @@ function advtrains.invert_train(train_id) -- rotate some other stuff train.couple_lck_back, train.couple_lck_front = train.couple_lck_front, train.couple_lck_back + if train.door_open then + train.door_open = - train.door_open + end advtrains.path_invalidate(train) + advtrains.couple_invalidate(train) local old_trainparts=train.trainparts train.trainparts={} @@ -857,7 +925,7 @@ function advtrains.invert_train(train_id) end function advtrains.get_train_at_pos(pos) - return advtrains.detector.get(pos) + return advtrains.occ.get_trains_at(pos)[1] end function advtrains.invalidate_all_paths(pos) @@ -883,6 +951,7 @@ function advtrains.invalidate_path(id) local v=advtrains.trains[id] if not v then return end advtrains.path_invalidate(v) + advtrains.couple_invalidate(v) v.dirty = true end diff --git a/advtrains/wagons.lua b/advtrains/wagons.lua index 38c551e..254e6a8 100644 --- a/advtrains/wagons.lua +++ b/advtrains/wagons.lua @@ -10,6 +10,7 @@ advtrains.wagons = {} advtrains.wagon_prototypes = {} +-- TODO: That yaw thing is still not fixed. seems like minetest itself obeys the counterclockwise system... -- function advtrains.create_wagon(wtype, owner) @@ -107,14 +108,18 @@ function wagon:ensure_init() -- Train not being set just means that this will happen as soon as the train calls update_trainpart_properties. if self.initialized and self.id then local data = advtrains.wagons[self.id] - if data.train_id then + if data and data.train_id and self:train() then if self.noninitticks then self.noninitticks=nil end return true end end - if not self.noninitticks then self.noninitticks=0 end + if not self.noninitticks then + atwarn("wagon",self.id,"uninitialized init=",self.initialized) + self.noninitticks=0 + end self.noninitticks=self.noninitticks+1 if self.noninitticks>20 then + atwarn("wagon",self.id,"uninitialized, removing") self:destroy() else self.object:setvelocity({x=0,y=0,z=0}) @@ -174,6 +179,10 @@ function wagon:destroy() -- not when a driver is inside if self.id then local data = advtrains.wagons[self.id] + if not data then + atwarn("wagon:destroy(): data is not set!") + return + end if self.custom_on_destroy then self.custom_on_destroy(self) @@ -184,14 +193,12 @@ function wagon:destroy() end if data.train_id and self:train() then - table.remove(self:train().trainparts, data.pos_in_trainparts) - advtrains.update_trainpart_properties(data.train_id) + advtrains.remove_train(data.train_id) advtrains.wagons[self.id]=nil if self.discouple then self.discouple.object:remove() end--will have no effect on unloaded objects - return true end end - atprint("[wagon ", self.id, "]: destroying") + atdebug("[wagon ", self.id, "]: destroying") self.object:remove() end @@ -247,7 +254,7 @@ function wagon:on_step(dtime) advtrains.on_control_change(pc, self:train(), data.wagon_flipped) --bordcom if pc.sneak and pc.jump then - self:show_bordcom(self.seatp[seatno]) + self:show_bordcom(data.seatp[seatno]) end --sound horn when required if self.horn_sound and pc.aux1 and not pc.sneak and not self.horn_handle then @@ -458,6 +465,7 @@ function wagon:on_step(dtime) or not vector.equals(accelerationvec, self.old_acceleration_vector) or self.old_yaw~=yaw or self.updatepct_timer<=0 then--only send update packet if something changed + self.object:setpos(pos) self.object:setvelocity(velocityvec) self.object:setacceleration(accelerationvec) @@ -494,6 +502,10 @@ function wagon:on_step(dtime) if self.custom_on_velocity_change then self:custom_on_velocity_change(train.velocity, self.old_velocity or 0, dtime) end + -- remove discouple object, because it will be in a wrong location + if self.discouple then + self.discouple.object:remove() + end end @@ -529,7 +541,7 @@ function wagon:on_rightclick(clicker) poss[#poss+1]={name=attrans("Show Inventory"), key="inv"} end if self.seat_groups[sgr].driving_ctrl_access and advtrains.check_driving_couple_protection(pname, data.owner, data.whitelist) then - poss[#poss+1]={name=attrans("Bord Computer"), key="bordcom"} + poss[#poss+1]={name=attrans("Board Computer"), key="bordcom"} end if data.owner==pname then poss[#poss+1]={name=attrans("Wagon properties"), key="prop"} @@ -706,7 +718,7 @@ function wagon:show_get_on_form(pname) local addtext, colorcode="", "" if data.seatp and data.seatp[seatno] then colorcode="#FF0000" - addtext=" ("..self.seatp[seatno]..")" + addtext=" ("..data.seatp[seatno]..")" end form=form..comma..colorcode..seattbl.name..addtext comma="," @@ -732,16 +744,12 @@ function wagon:show_wagon_properties(pname) end --BordCom -local function checkcouple(eid) - if not eid then return nil end - local ent=minetest.object_refs[eid] +local function checkcouple(ent) if not ent or not ent:getyaw() then - eid=nil return nil end local le = ent:get_luaentity() if not le or not le.is_couple then - eid=nil return nil end return le @@ -793,8 +801,8 @@ function wagon:show_bordcom(pname) form = form .. "label[0.5,"..(linhei)..";<--]" end --check cpl_eid_front and _back of train - local couple_front = checkcouple(train.couple_eid_front) - local couple_back = checkcouple(train.couple_eid_back) + local couple_front = checkcouple(train.cpl_front) + local couple_back = checkcouple(train.cpl_back) if couple_front then form = form .. "image_button[0.5,"..(linhei+1)..";1,1;advtrains_couple.png;cpl_f;]" end @@ -872,8 +880,8 @@ function wagon:handle_bordcom_fields(pname, formname, fields) end end --check cpl_eid_front and _back of train - local couple_front = checkcouple(train.couple_eid_front) - local couple_back = checkcouple(train.couple_eid_back) + local couple_front = checkcouple(train.cpl_front) + local couple_back = checkcouple(train.cpl_back) if fields.cpl_f and couple_front then couple_front:on_rightclick(pname) diff --git a/advtrains_luaautomation/atc_rail.lua b/advtrains_luaautomation/atc_rail.lua index 88c9ee9..d001d88 100644 --- a/advtrains_luaautomation/atc_rail.lua +++ b/advtrains_luaautomation/atc_rail.lua @@ -24,7 +24,7 @@ function r.fire_event(pos, evtdata) --prepare ingame API for ATC. Regenerate each time since pos needs to be known --If no train, then return false. - local train_id=advtrains.detector.get(pos) + local train_id=advtrains.get_train_at_pos(pos) local train, atc_arrow, tvel if train_id then train=advtrains.trains[train_id] end if train then @@ -34,19 +34,16 @@ function r.fire_event(pos, evtdata) atlatc.interrupt.add(0,pos,evtdata) return end - for index, ppos in pairs(train.path) do - if vector.equals(advtrains.round_vector_floor_y(ppos), pos) then - atc_arrow = - vector.equals( - advtrains.dirCoordSet(pos, arrowconn), - advtrains.round_vector_floor_y(train.path[index+train.movedir]) - ) - end - end - if atc_arrow==nil then - atwarn("LuaAutomation ATC rail at", pos, ": Rail not on train's path! Can't determine arrow direction. Assuming +!") - atc_arrow=true + local index = advtrains.path_lookup(train, pos) + + local iconnid = 1 + if index then + iconnid = train.path_cn[index] + else + atwarn("ATC rail at", pos, ": Rail not on train's path! Can't determine arrow direction. Assuming +!") end + atc_arrow = iconnid == 1 + tvel=train.velocity end local customfct={ -- cgit v1.2.3