diff options
| -rw-r--r-- | advtrains.zip | bin | 4992868 -> 4993627 bytes | |||
| -rw-r--r-- | advtrains/advtrains/atc.lua | 2 | ||||
| -rw-r--r-- | advtrains/advtrains/init.lua | 38 | ||||
| -rw-r--r-- | advtrains/advtrains/tracks.lua | 4 | ||||
| -rw-r--r-- | advtrains/advtrains/trainlogic.lua | 108 | ||||
| -rw-r--r-- | advtrains/advtrains_luaautomation/active_common.lua | 2 | 
6 files changed, 119 insertions, 35 deletions
diff --git a/advtrains.zip b/advtrains.zip Binary files differindex 2144e28..957cfb4 100644 --- a/advtrains.zip +++ b/advtrains.zip diff --git a/advtrains/advtrains/atc.lua b/advtrains/advtrains/atc.lua index ed631a3..5f1f64d 100644 --- a/advtrains/advtrains/atc.lua +++ b/advtrains/advtrains/atc.lua @@ -93,7 +93,7 @@ advtrains.register_tracks("default", {  			after_place_node=apn_func,  			after_dig_node=function(pos)  				return advtrains.pcall(function() -					advtrains.invalidate_all_paths() +					advtrains.invalidate_all_paths(pos)  					advtrains.ndb.clear(pos)  					local pts=minetest.pos_to_string(pos)  					atc.controllers[pts]=nil diff --git a/advtrains/advtrains/init.lua b/advtrains/advtrains/init.lua index 022fcee..3fc16ed 100644 --- a/advtrains/advtrains/init.lua +++ b/advtrains/advtrains/init.lua @@ -37,7 +37,7 @@ advtrains.modpath = minetest.get_modpath("advtrains")  function advtrains.print_concat_table(a)  	local str=""  	local stra="" -	for i=1,50 do +	for i=1,10 do  		t=a[i]  		if t==nil then  			stra=stra.."nil " @@ -67,9 +67,12 @@ end  atprint=function() end  if minetest.setting_getbool("advtrains_debug") then  	atprint=function(t, ...) +		local context=advtrains.atprint_context_tid +		if not context then context="" end +		--if context~="4527" then return end  		local text=advtrains.print_concat_table({t, ...}) -		minetest.log("action", "[advtrains]"..text) -		minetest.chat_send_all("[advtrains]"..text) +		minetest.log("action", "[advtrains]"..context..">"..text) +		minetest.chat_send_all("[advtrains]"..context..">"..text)  	end  end  atwarn=function(t, ...) @@ -171,7 +174,8 @@ end  advtrains.avt_save = function()  	--atprint("saving") -	advtrains.invalidate_all_paths() +	--No more invalidating. +	--Instead, remove path a.s.o from the saved table manually  	-- update wagon saves  	for _,wagon in pairs(minetest.luaentities) do @@ -195,10 +199,34 @@ advtrains.avt_save = function()  		end  	end +	local tmp_trains={} +	for id, train in pairs(advtrains.trains) do +		--first, deep_copy the train +		local v=advtrains.merge_tables(train) +		--then invalidate +		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 +		 +		--then save it +		tmp_trains[id]=v +	end +	  	--versions:  	-- 1 - Initial new save format.  	local save_tbl={ -		trains = advtrains.trains, +		trains = tmp_trains,  		wagon_save = advtrains.wagon_save,  		ptmap = advtrains.player_to_train_mapping,  		atc = advtrains.atc.save_data(), diff --git a/advtrains/advtrains/tracks.lua b/advtrains/advtrains/tracks.lua index 86c87ba..b390c6a 100644 --- a/advtrains/advtrains/tracks.lua +++ b/advtrains/advtrains/tracks.lua @@ -263,13 +263,13 @@ function advtrains.register_tracks(tracktype, def, preset)  		local rcswitchfunc=function(pos, node, player)
  			if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
  				advtrains.ndb.swap_node(pos, {name=def.nodename_prefix.."_"..suffix_target, param2=node.param2})
 -				advtrains.invalidate_all_paths()
 +				advtrains.invalidate_all_paths(pos)
  			end
  		end
  		local switchfunc=function(pos, node, newstate)
  			if newstate~=is_state then
  				advtrains.ndb.swap_node(pos, {name=def.nodename_prefix.."_"..suffix_target, param2=node.param2})
 -				advtrains.invalidate_all_paths()
 +				advtrains.invalidate_all_paths(pos)
  			end
  		end
  		local mesec
 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 diff --git a/advtrains/advtrains_luaautomation/active_common.lua b/advtrains/advtrains_luaautomation/active_common.lua index e17af91..8c910c6 100644 --- a/advtrains/advtrains_luaautomation/active_common.lua +++ b/advtrains/advtrains_luaautomation/active_common.lua @@ -49,7 +49,7 @@ function ac.getform(pos, meta_p)  end  function ac.after_dig_node(pos, node, player) -	advtrains.invalidate_all_paths() +	advtrains.invalidate_all_paths(pos)  	advtrains.ndb.clear(pos)  	local ph=minetest.pos_to_string(pos)  	ac.nodes[ph]=nil  | 
