diff --git a/advtrains/helpers.lua b/advtrains/helpers.lua index 6a8175f..1a02621 100644 --- a/advtrains/helpers.lua +++ b/advtrains/helpers.lua @@ -55,15 +55,14 @@ rely1, rely2 tell to which height the connections are pointed to. 1 means it wil ]] -function advtrains.conway(midreal, prev, traintype)--in order prev,mid,return +function advtrains.conway(midreal, prev, drives_on)--in order prev,mid,return local mid=advtrains.round_vector_floor_y(midreal) - local drives_on=advtrains.all_traintypes[traintype].drives_on - if not advtrains.get_rail_info_at(advtrains.round_vector_floor_y(prev), traintype) then + if not advtrains.get_rail_info_at(advtrains.round_vector_floor_y(prev), drives_on) then return nil end - local midnode_ok, middir1, middir2, midrely1, midrely2=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(mid), traintype) + local midnode_ok, middir1, middir2, midrely1, midrely2=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(mid), drives_on) if not midnode_ok then return nil end @@ -104,7 +103,7 @@ function advtrains.conway(midreal, prev, traintype)--in order prev,mid,return return nil end - local nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(next), traintype) + local nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(next), drives_on) --is it a rail? if(not nextnode_ok) then @@ -112,7 +111,7 @@ function advtrains.conway(midreal, prev, traintype)--in order prev,mid,return next.y=next.y-1 y_offset=y_offset-1 - nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(next), traintype) + nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(next), drives_on) if(not nextnode_ok) then --print("[advtrains]in conway: one below "..minetest.pos_to_string(next).." is not a rail either, returning!") return nil @@ -125,7 +124,7 @@ function advtrains.conway(midreal, prev, traintype)--in order prev,mid,return next.y=next.y-1 y_offset=y_offset-1 - nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(next), traintype) + nextnode_ok, nextdir1, nextdir2, nextrely1, nextrely2, nextrailheight=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(next), drives_on) if(not nextnode_ok) then --print("[advtrains]in conway: (at connecting if check again) one below "..minetest.pos_to_string(next).." is not a rail either, returning!") return nil diff --git a/advtrains/pseudoload.lua b/advtrains/pseudoload.lua index 8511811..3f4f321 100644 --- a/advtrains/pseudoload.lua +++ b/advtrains/pseudoload.lua @@ -101,7 +101,7 @@ function advtrains.save_trackdb() end ]]--end temp outcomment advtrains.trackdb={} -advtrains.fpath_tdb=minetest.get_worldpath().."/advtrains_trackdb" +advtrains.fpath_tdb=minetest.get_worldpath().."/advtrains_trackdb2" local file, err = io.open(advtrains.fpath_tdb, "r") if not file then local er=err or "Unknown Error" @@ -133,34 +133,38 @@ end --false if it's not a rail or the train does not drive on this rail, but it is loaded or --nil if the node is neither loaded nor in trackdb --the distraction between false and nil will be needed only in special cases.(train initpos) -function advtrains.get_rail_info_at(pos, traintype) +function advtrains.get_rail_info_at(pos, drives_on) local node=minetest.get_node_or_nil(pos) if not node then --try raildb local rdp=vector.round(pos) local dbe=(advtrains.trackdb[traintype] and advtrains.trackdb[traintype][rdp.y] and advtrains.trackdb[traintype][rdp.y][rdp.x] and advtrains.trackdb[traintype][rdp.y][rdp.x][rdp.z]) if dbe then - return true, dbe.conn1, dbe.conn2, dbe.rely1 or 0, dbe.rely2 or 0, dbe.railheight or 0 + for tt,_ in pairs(drives_on) do + if not dbe.tracktype or tt==dbe.tracktype then + return true, dbe.conn1, dbe.conn2, dbe.rely1 or 0, dbe.rely2 or 0, dbe.railheight or 0 + end + end else return nil end end local nodename=node.name - if(not advtrains.is_track_and_drives_on(nodename, advtrains.all_traintypes[traintype].drives_on)) then + if(not advtrains.is_track_and_drives_on(nodename, drives_on)) then return false end - local conn1, conn2, rely1, rely2, railheight=advtrains.get_track_connections(node.name, node.param2) + local conn1, conn2, rely1, rely2, railheight, tracktype=advtrains.get_track_connections(node.name, node.param2) --already in trackdb? local rdp=vector.round(pos) - if not (advtrains.trackdb[traintype] and advtrains.trackdb[traintype][rdp.y] and advtrains.trackdb[traintype][rdp.y][rdp.x] and advtrains.trackdb[traintype][rdp.y][rdp.x][rdp.z]) then--TODO is this necessary? - if not advtrains.trackdb[traintype] then advtrains.trackdb[traintype]={} end - if not advtrains.trackdb[traintype][rdp.y] then advtrains.trackdb[traintype][rdp.y]={} end - if not advtrains.trackdb[traintype][rdp.y][rdp.x] then advtrains.trackdb[traintype][rdp.y][rdp.x]={} end - advtrains.trackdb[traintype][rdp.y][rdp.x][rdp.z]={ + if not (advtrains.trackdb and advtrains.trackdb[rdp.y] and advtrains.trackdb[rdp.y][rdp.x] and advtrains.trackdb[rdp.y][rdp.x][rdp.z]) then--TODO is this necessary? + if not advtrains.trackdb then advtrains.trackdb={} end + if not advtrains.trackdb[rdp.y] then advtrains.trackdb[rdp.y]={} end + if not advtrains.trackdb[rdp.y][rdp.x] then advtrains.trackdb[rdp.y][rdp.x]={} end + advtrains.trackdb[rdp.y][rdp.x][rdp.z]={ conn1=conn1, conn2=conn2, rely1=rely1, rely2=rely2, - railheight=railheight + railheight=railheight, tracktype=tracktype } end @@ -168,13 +172,11 @@ function advtrains.get_rail_info_at(pos, traintype) end function advtrains.reset_trackdb_position(pos) local rdp=vector.round(pos) - for tt, _ in pairs(advtrains.all_traintypes) do - if not advtrains.trackdb[tt] then advtrains.trackdb[tt]={} end - if not advtrains.trackdb[tt][rdp.y] then advtrains.trackdb[tt][rdp.y]={} end - if not advtrains.trackdb[tt][rdp.y][rdp.x] then advtrains.trackdb[tt][rdp.y][rdp.x]={} end - advtrains.trackdb[tt][rdp.y][rdp.x][rdp.z]=nil - advtrains.get_rail_info_at(pos, tt)--to restore it. - end + if not advtrains.trackdb then advtrains.trackdb={} end + if not advtrains.trackdb[rdp.y] then advtrains.trackdb[rdp.y]={} end + if not advtrains.trackdb[rdp.y][rdp.x] then advtrains.trackdb[rdp.y][rdp.x]={} end + advtrains.trackdb[rdp.y][rdp.x][rdp.z]=nil + advtrains.get_rail_info_at(pos)--to restore it. end diff --git a/advtrains/tracks.lua b/advtrains/tracks.lua index 99dbb27..8bd5666 100644 --- a/advtrains/tracks.lua +++ b/advtrains/tracks.lua @@ -346,17 +346,17 @@ function advtrains.register_tracks(tracktype, def, preset) end end end - table.insert(advtrains.all_tracktypes, tracktype) + advtrains.all_tracktypes[tracktype]=true end -function advtrains.is_track_and_drives_on(nodename, drives_on) +function advtrains.is_track_and_drives_on(nodename, drives_on_p) if not minetest.registered_nodes[nodename] then return false end local nodedef=minetest.registered_nodes[nodename] - for k,v in ipairs(drives_on) do - if nodedef.groups["advtrains_track_"..v] then + for k,v in pairs(drives_on_p) do + if nodedef.groups["advtrains_track_"..k] then return true end end diff --git a/advtrains/trainhud.lua b/advtrains/trainhud.lua index aead246..19e4f6f 100644 --- a/advtrains/trainhud.lua +++ b/advtrains/trainhud.lua @@ -94,14 +94,14 @@ function advtrains.set_trainhud(name, text) end function advtrains.hud_train_format(train, flip) local fct=flip and -1 or 1 - if not train or not train.traintype then return "" end + if not train then return "" end - local max=advtrains.all_traintypes[train.traintype].max_speed or 10 + local max=train.max_speed or 10 local vel=advtrains.abs_ceil(train.velocity) local tvel=advtrains.abs_ceil(train.tarvelocity) local topLine, firstLine, secondLine - topLine=train.traintype.." ["..mletter[fct*train.movedir].."] "..(train.brake and "="..( train.brake_hold_state==2 and "^" or "" ).."B=" or "") + topLine="Train".." ["..mletter[fct*train.movedir].."] "..(train.brake and "="..( train.brake_hold_state==2 and "^" or "" ).."B=" or "") firstLine="Speed: |"..string.rep("+", vel)..string.rep("_", max-vel)..">" secondLine="Target: |"..string.rep("+", tvel)..string.rep("_", max-tvel)..">" diff --git a/advtrains/trainlogic.lua b/advtrains/trainlogic.lua index 5e3936f..bb38fce 100644 --- a/advtrains/trainlogic.lua +++ b/advtrains/trainlogic.lua @@ -1,8 +1,8 @@ --trainlogic.lua --controls train entities stuff about connecting/disconnecting/colliding trains and other things ---local print=function(t, ...) minetest.log("action", table.concat({t, ...}, " ")) minetest.chat_send_all(table.concat({t, ...}, " ")) end -local print=function() end +local print=function(t, ...) minetest.log("action", table.concat({t, ...}, " ")) minetest.chat_send_all(table.concat({t, ...}, " ")) end +--local print=function() end local benchmark=false --printbm=function(str, t) print("[advtrains]"..str.." "..((os.clock()-t)*1000).."ms") end @@ -34,7 +34,6 @@ function endstep() end end ---TODO: these values need to be integrated when i remove traintypes. advtrains.train_accel_force=2--per second and divided by number of wagons advtrains.train_brake_force=3--per second, not divided by number of wagons advtrains.train_roll_force=0.5--per second, not divided by number of wagons, acceleration when rolling without brake @@ -42,13 +41,6 @@ advtrains.train_emerg_force=10--for emergency brakes(when going off track) advtrains.audit_interval=30 -advtrains.all_traintypes={} -function advtrains.register_train_type(name, drives_on, max_speed) - advtrains.all_traintypes[name]={} - advtrains.all_traintypes[name].drives_on=drives_on - advtrains.all_traintypes[name].max_speed=max_speed or 10 -end - advtrains.trains={} advtrains.wagon_save={} @@ -168,7 +160,10 @@ minetest.register_globalstep(function(dtime) end) function advtrains.train_step(id, train, dtime) - + --Legacy: set drives_on and max_speed + if not train.drives_on or not train.max_speed then + advtrains.update_trainpart_properties(id) + end --TODO check for all vars to be present if not train.velocity then train.velocity=0 @@ -377,7 +372,7 @@ function advtrains.train_step(id, train, dtime) end end train.last_accel=(applydiff*train.movedir) - train.velocity=math.min(math.max( train.velocity+applydiff , 0), advtrains.all_traintypes[train.traintype].max_speed) + train.velocity=math.min(math.max( train.velocity+applydiff , 0), train.max_speed or 10) else train.last_accel=0 end @@ -420,14 +415,13 @@ wagon_proto={ ]] --returns new id -function advtrains.create_new_train_at(pos, pos_prev, traintype) +function advtrains.create_new_train_at(pos, pos_prev) local newtrain_id=os.time()..os.clock() while advtrains.trains[newtrain_id] do newtrain_id=os.time()..os.clock() end--ensure uniqueness(will be unneccessary) advtrains.trains[newtrain_id]={} advtrains.trains[newtrain_id].last_pos=pos advtrains.trains[newtrain_id].last_pos_prev=pos_prev - advtrains.trains[newtrain_id].traintype=traintype advtrains.trains[newtrain_id].tarvelocity=0 advtrains.trains[newtrain_id].velocity=0 advtrains.trains[newtrain_id].trainparts={} @@ -448,7 +442,7 @@ function advtrains.pathpredict(id, train) return false end - local node_ok=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(train.last_pos), train.traintype) + local node_ok=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(train.last_pos), train.drives_on) if node_ok==nil then --block not loaded, do nothing @@ -466,7 +460,7 @@ function advtrains.pathpredict(id, train) return false end - local prevnode_ok=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(train.last_pos_prev), train.traintype) + local prevnode_ok=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(train.last_pos_prev), train.drives_on) if prevnode_ok==nil then --block not loaded, do nothing @@ -501,7 +495,7 @@ function advtrains.pathpredict(id, train) local maxn=advtrains.maxN(train.path) while (maxn-train.index) < pregen_front do--pregenerate --print("[advtrains]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.traintype) + 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 @@ -518,7 +512,7 @@ function advtrains.pathpredict(id, train) local minn=advtrains.minN(train.path) while (train.index-minn) < (train.trainlen or 0) + pregen_back do --post_generate. has to be at least trainlen. (we let go of the exact calculation here since this would be unuseful here) --print("[advtrains]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.traintype) + 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 @@ -576,6 +570,8 @@ function advtrains.add_wagon_to_train(wagon, train_id, index) end function advtrains.update_trainpart_properties(train_id, invert_flipstate) local train=advtrains.trains[train_id] + train.drives_on=advtrains.all_tracktypes + train.max_speed=100 local rel_pos=0 local count_l=0 for i, w_id in ipairs(train.trainparts) do @@ -595,6 +591,15 @@ function advtrains.update_trainpart_properties(train_id, invert_flipstate) end rel_pos=rel_pos+wagon.wagon_span any_loaded=true + + if wagon.drives_on then + for k,_ in pairs(train.drives_on) do + if not wagon.drives_on[k] then + train.drives_on[k]=nil + end + end + end + train.max_speed=math.min(train.max_speed, wagon.max_speed) end end if not any_loaded then @@ -617,7 +622,7 @@ function advtrains.split_train_at_wagon(wagon) print("split_train: pos_for_new_train not set") return false end - local node_ok=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(pos_for_new_train), train.traintype) + local node_ok=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(pos_for_new_train), train.drives_on) if not node_ok then print("split_train: pos_for_new_train "..minetest.pos_to_string(advtrains.round_vector_floor_y(pos_for_new_train_prev)).." not loaded or is not a rail") return false @@ -628,14 +633,14 @@ function advtrains.split_train_at_wagon(wagon) return false end - local prevnode_ok=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(pos_for_new_train), train.traintype) + local prevnode_ok=advtrains.get_rail_info_at(advtrains.round_vector_floor_y(pos_for_new_train), train.drives_on) if not prevnode_ok then print("split_train: pos_for_new_train_prev "..minetest.pos_to_string(advtrains.round_vector_floor_y(pos_for_new_train_prev)).." not loaded or is not a rail") return false end --create subtrain - local newtrain_id=advtrains.create_new_train_at(pos_for_new_train, pos_for_new_train_prev, train.traintype) + local newtrain_id=advtrains.create_new_train_at(pos_for_new_train, pos_for_new_train_prev) local newtrain=advtrains.trains[newtrain_id] --insert all wagons to new train for k,v in ipairs(train.trainparts) do @@ -669,7 +674,7 @@ function advtrains.try_connect_trains(id1, id2) local frontpos1=advtrains.get_real_index_position(train1.path, train1.index) local backpos1=advtrains.get_real_index_position(train1.path, advtrains.get_train_end_index(train1)) --couple logic - if train1.traintype==train2.traintype then + --if train1.traintype==train2.traintype then local frontpos2=advtrains.get_real_index_position(train2.path, train2.index) local backpos2=advtrains.get_real_index_position(train2.path, advtrains.get_train_end_index(train2)) @@ -689,7 +694,7 @@ function advtrains.try_connect_trains(id1, id2) elseif vector.distance(frontpos2, frontpos1)