From b31229d62e05e76a2a658e3b8ed85bd26059cc0e Mon Sep 17 00:00:00 2001 From: orwell96 Date: Sun, 5 Feb 2017 17:22:13 +0100 Subject: Fix ATC components being randomly ignored by trains. Also add warnings to off_track stuff Also pack for release --- advtrains/advtrains/trainlogic.lua | 140 ++++++++++++++++++++++++------------- 1 file changed, 93 insertions(+), 47 deletions(-) (limited to 'advtrains') diff --git a/advtrains/advtrains/trainlogic.lua b/advtrains/advtrains/trainlogic.lua index 3e10c22..5fafb89 100644 --- a/advtrains/advtrains/trainlogic.lua +++ b/advtrains/advtrains/trainlogic.lua @@ -159,6 +159,15 @@ function advtrains.train_step_a(id, train, dtime) train.path_dist[-1]=vector.distance(train.last_pos, train.last_pos_prev) train.path_extent_min=-1 train.path_extent_max=0 + --[[ + Bugfix for trains randomly ignoring ATC rails: + - Paths have been invalidated. 1 gets executed and ensures an initial path + - 2a sets train end index. The problem is that path_dist is not known for the whole path, so train end index will be nearly trainlen + - Since the detector indices are also unknown, they get set to the new (wrong) train_end_index. Enter_node calls are not executed for the nodes that lie in between real end_index and trainlen. + - The next step, mistake is recognized, train leaves some positions. From there, everything works again. + To overcome this, we will generate the full required path here so that path_dist is available for get_train_end_index(). + ]] + advtrains.pathpredict(id, train) end --- 2a. set train.end_index which is required in different places, IF IT IS NOT SET YET by STMT afterwards. --- @@ -186,17 +195,40 @@ function advtrains.train_step_a(id, train, dtime) end --apply off-track handling: - --won't take any effect immediately after path reset because index_on_track not set, but that's not severe. local front_off_track=train.max_index_on_track and train.index>train.max_index_on_track local back_off_track=train.min_index_on_track and train.end_index1 then train.tarvelocity=1 end + if train.tarvelocity>1 then + train.tarvelocity=1 + atwarn("Train",sid(id)," is off track at both ends. Clipping velocity to 1") + pprint=true + end elseif front_off_track then--allow movement only backward - if train.movedir==1 and train.tarvelocity>0 then train.tarvelocity=0 end - if train.movedir==-1 and train.tarvelocity>1 then train.tarvelocity=1 end + if train.movedir==1 and train.tarvelocity>0 then + train.tarvelocity=0 + atwarn("Train",sid(id)," is off track. Trying to drive further out. Velocity clipped to 0") + pprint=true + end + if train.movedir==-1 and train.tarvelocity>1 then + train.tarvelocity=1 + atwarn("Train",sid(id)," is off track. Velocity clipped to 1") + pprint=true + end elseif back_off_track then--allow movement only forward - if train.movedir==-1 and train.tarvelocity>0 then train.tarvelocity=0 end - if train.movedir==1 and train.tarvelocity>1 then train.tarvelocity=1 end + if train.movedir==-1 and train.tarvelocity>0 then + train.tarvelocity=0 + atwarn("Train",sid(id)," is off track. Trying to drive further out. Velocity clipped to 0") + pprint=true + end + if train.movedir==1 and train.tarvelocity>1 then + train.tarvelocity=1 + atwarn("Train",sid(id)," is off track. Velocity clipped to 1") + pprint=true + end + end + if pprint then + atprint("max_iot", train.max_index_on_track, "min_iot", train.min_index_on_track, "<> index", train.index, "end_index", train.end_index) end --interpret ATC command @@ -257,47 +289,8 @@ function advtrains.train_step_a(id, train, dtime) train.end_index=advtrains.get_train_end_index(train) --- 5. extend path as necessary --- - - local gen_front=math.max(train.index, train.detector_old_index) + 10 - local gen_back=math.min(train.end_index, train.detector_old_end_index) - 10 - - local maxn=train.path_extent_max or 0 - while maxn < gen_front do--pregenerate - --atprint("maxn conway for ",maxn,minetest.pos_to_string(path[maxn]),maxn-1,minetest.pos_to_string(path[maxn-1])) - local conway=advtrains.conway(train.path[maxn], train.path[maxn-1], train.drives_on) - if conway then - train.path[maxn+1]=conway - train.max_index_on_track=maxn - else - --do as if nothing has happened and preceed with path - --but do not update max_index_on_track - atprint("over-generating path max to index "..(maxn+1).." (position "..minetest.pos_to_string(train.path[maxn]).." )") - train.path[maxn+1]=vector.add(train.path[maxn], vector.subtract(train.path[maxn], train.path[maxn-1])) - end - train.path_dist[maxn]=vector.distance(train.path[maxn+1], train.path[maxn]) - maxn=maxn+1 - end - train.path_extent_max=maxn - - local minn=train.path_extent_min or -1 - while minn > gen_back do - --atprint("minn conway for ",minn,minetest.pos_to_string(path[minn]),minn+1,minetest.pos_to_string(path[minn+1])) - local conway=advtrains.conway(train.path[minn], train.path[minn+1], train.drives_on) - if conway then - train.path[minn-1]=conway - train.min_index_on_track=minn - else - --do as if nothing has happened and preceed with path - --but do not update min_index_on_track - atprint("over-generating path min to index "..(minn-1).." (position "..minetest.pos_to_string(train.path[minn]).." )") - train.path[minn-1]=vector.add(train.path[minn], vector.subtract(train.path[minn], train.path[minn+1])) - end - train.path_dist[minn-1]=vector.distance(train.path[minn], train.path[minn-1]) - minn=minn-1 - end - train.path_extent_min=minn - if not train.min_index_on_track then train.min_index_on_track=-1 end - if not train.max_index_on_track then train.max_index_on_track=0 end + --why this is an extra function, see under 3. + advtrains.pathpredict(id, train, true) --make pos/yaw available for possible recover calls if train.max_index_on_track gen_back do + --atprint("minn conway for ",minn,minetest.pos_to_string(path[minn]),minn+1,minetest.pos_to_string(path[minn+1])) + local conway=advtrains.conway(train.path[minn], train.path[minn+1], train.drives_on) + if conway then + train.path[minn-1]=conway + train.min_index_on_track=minn + else + --do as if nothing has happened and preceed with path + --but do not update min_index_on_track + atprint("over-generating path min to index "..(minn-1).." (position "..minetest.pos_to_string(train.path[minn]).." )") + train.path[minn-1]=vector.add(train.path[minn], vector.subtract(train.path[minn], train.path[minn+1])) + end + train.path_dist[minn-1]=vector.distance(train.path[minn], train.path[minn-1]) + minn=minn-1 + end + train.path_extent_min=minn + if not train.min_index_on_track then train.min_index_on_track=-1 end + if not train.max_index_on_track then train.max_index_on_track=0 end +end + + function advtrains.train_step_b(id, train, dtime) --- 8. check for collisions with other trains --- -- cgit v1.2.3