diff options
Diffstat (limited to 'advtrains/advtrains/trainlogic.lua')
-rw-r--r-- | advtrains/advtrains/trainlogic.lua | 108 |
1 files changed, 82 insertions, 26 deletions
diff --git a/advtrains/advtrains/trainlogic.lua b/advtrains/advtrains/trainlogic.lua index 7dad80c..e62c864 100644 --- a/advtrains/advtrains/trainlogic.lua +++ b/advtrains/advtrains/trainlogic.lua @@ -55,12 +55,16 @@ advtrains.mainloop_trainlogic=function(dtime) local t=os.clock() advtrains.detector.on_node={} for k,v in pairs(advtrains.trains) do + advtrains.atprint_context_tid=sid(k) advtrains.train_step_a(k, v, dtime) end for k,v in pairs(advtrains.trains) do + advtrains.atprint_context_tid=sid(k) advtrains.train_step_b(k, v, dtime) end + advtrains.atprint_context_tid=nil + atprintbm("trainsteps", t) endstep() end @@ -140,7 +144,7 @@ function advtrains.train_step_a(id, train, dtime) end --- 2. prepare initial path and index if needed --- if not train.index then train.index=0 end - if not train.path or #train.path<2 then + if not train.path then if not train.last_pos then --no chance to recover atprint("train hasn't saved last-pos, removing train.") @@ -224,36 +228,43 @@ function advtrains.train_step_a(id, train, dtime) train.tarvelocity=0 end + --- 3a. this can be useful for debugs/warnings and is used for check_trainpartload --- + local t_info, train_pos=sid(id), train.path[math.floor(train.index)] + if train_pos then + t_info=t_info.." @"..minetest.pos_to_string(train_pos) + end + --apply off-track handling: 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_index<train.min_index_on_track local pprint + if front_off_track and back_off_track then--allow movement in both directions if train.tarvelocity>1 then train.tarvelocity=1 - atwarn("Train",sid(id)," is off track at both ends. Clipping velocity to 1") + atwarn("Train",t_info,"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 - atwarn("Train",sid(id)," is off track. Trying to drive further out. Velocity clipped to 0") + atwarn("Train",t_info,"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") + atwarn("Train",t_info,"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 - atwarn("Train",sid(id)," is off track. Trying to drive further out. Velocity clipped to 0") + atwarn("Train",t_info,"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") + atwarn("Train",t_info,"is off track. Velocity clipped to 1") pprint=true end end @@ -322,7 +333,7 @@ function advtrains.train_step_a(id, train, dtime) --why this is an extra function, see under 3. advtrains.pathpredict(id, train, true) - --make pos/yaw available for possible recover calls + --- 5a. make pos/yaw available for possible recover calls --- if train.max_index_on_track<train.index then --whoops, train went too far. the saved position will be the last one that lies on a track, and savedpos_off_track_index_offset will hold how far to go from here train.savedpos_off_track_index_offset=train.index-train.max_index_on_track train.last_pos=train.path[train.max_index_on_track] @@ -339,6 +350,36 @@ function advtrains.train_step_a(id, train, dtime) train.last_pos_prev=train.path[math.floor(train.index-0.5)] end + --- 5b. Remove path items that are no longer used --- + -- Necessary since path items are no longer invalidated in save steps + local path_pregen_keep=20 + local offtrack_keep=4 + local gen_front_keep= path_pregen_keep + local gen_back_keep= - train.trainlen - path_pregen_keep + + local delete_min=math.min(train.max_index_on_track - offtrack_keep, math.floor(train.index)+gen_back_keep) + local delete_max=math.max(train.min_index_on_track + offtrack_keep, math.floor(train.index)+gen_front_keep) + + if train.path_extent_min<delete_min then + atprint(sid(id),"clearing path min ",train.path_extent_min," to ",delete_min) + for i=train.path_extent_min,delete_min-1 do + train.path[i]=nil + train.path_dist[i]=nil + end + train.path_extent_min=delete_min + train.min_index_on_track=math.max(train.min_index_on_track, delete_min) + end + if train.path_extent_max>delete_max then + atprint(sid(id),"clearing path max ",train.path_extent_max," to ",delete_max) + train.path_dist[delete_max]=nil + for i=delete_max+1,train.path_extent_max do + train.path[i]=nil + train.path_dist[i]=nil + end + train.path_extent_max=delete_max + train.max_index_on_track=math.min(train.max_index_on_track, delete_max) + end + --- 6. update node coverage --- -- when paths get cleared, the old indices set above will be up-to-date and represent the state in which the last run of this code was made @@ -406,7 +447,7 @@ function advtrains.train_step_a(id, train, dtime) train.check_trainpartload=(train.check_trainpartload or 0)-dtime local node_range=(math.max((minetest.setting_get("active_block_range") or 0),1)*16) if train.check_trainpartload<=0 then - local ori_pos=advtrains.get_real_index_position(path, train.index) --not much to calculate + local ori_pos=train_pos --see 3a. --atprint("[train "..id.."] at "..minetest.pos_to_string(vector.round(ori_pos))) local should_check=false @@ -429,6 +470,7 @@ end --about regular: Used by 1. to ensure path gets generated far enough, since end index is not known at this time. function advtrains.pathpredict(id, train, regular) + --TODO duplicate code under 5b. local path_pregen=10 local gen_front= path_pregen @@ -440,7 +482,7 @@ function advtrains.pathpredict(id, train, regular) 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])) + atprint("maxn conway for ",maxn,minetest.pos_to_string(train.path[maxn]),maxn-1,minetest.pos_to_string(train.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 @@ -458,7 +500,7 @@ function advtrains.pathpredict(id, train, regular) 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])) + atprint("minn conway for ",minn,minetest.pos_to_string(train.path[minn]),minn+1,minetest.pos_to_string(train.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 @@ -858,23 +900,37 @@ function advtrains.get_train_at_pos(pos) return advtrains.detector.on_node[ph] end -function advtrains.invalidate_all_paths() - --atprint("invalidating all paths") +function advtrains.invalidate_all_paths(pos) + --if a position is given, only invalidate inside a radius to save performance + local inv_radius=50 + atprint("invalidating all paths") for k,v in pairs(advtrains.trains) do - if v.index then - v.restore_add_index=v.index-math.floor(v.index+0.5) - end - v.path=nil - v.path_dist=nil - v.index=nil - v.end_index=nil - v.min_index_on_track=nil - v.max_index_on_track=nil - v.path_extent_min=nil - v.path_extent_max=nil - - v.detector_old_index=nil - v.detector_old_end_index=nil + local exec=true + if pos and v.path and v.index and v.end_index then + --start and end pos of the train + local cmp1=v.path[math.floor(v.index)] + local cmp2=v.path[math.floor(v.end_index)] + if vector.distance(pos, cmp1)>inv_radius and vector.distance(pos, cmp2)>inv_radius then + exec=false + end + end + if exec then + --TODO duplicate code in init.lua avt_save()! + if v.index then + v.restore_add_index=v.index-math.floor(v.index+0.5) + end + v.path=nil + v.path_dist=nil + v.index=nil + v.end_index=nil + v.min_index_on_track=nil + v.max_index_on_track=nil + v.path_extent_min=nil + v.path_extent_max=nil + + v.detector_old_index=nil + v.detector_old_end_index=nil + end end end |