Rewrite rail connection system...
...to support an arbitrary number of connections for rails, which leads to these new features: - switches now get recognized by the trackworker correctly - ability to add real rail crosses During this, I also rewrote the rail registering system and the conway function (important part of path prediction) Note, developers: the track preset format changed, you might need to rewrite them according to the presets in tracks.lua if you wrote your own (possibly breaks advcarts)
This commit is contained in:
parent
faa60e2bd4
commit
46c4447da0
|
@ -124,8 +124,8 @@ advtrains.atc_function = function(def, preset, suffix, rotation)
|
||||||
meta:set_string("formspec", atc.get_atc_controller_formspec(pos, meta))
|
meta:set_string("formspec", atc.get_atc_controller_formspec(pos, meta))
|
||||||
|
|
||||||
local pts=minetest.pos_to_string(pos)
|
local pts=minetest.pos_to_string(pos)
|
||||||
local _, conn1=advtrains.get_rail_info_at(pos, advtrains.all_tracktypes)
|
local _, conns=advtrains.get_rail_info_at(pos, advtrains.all_tracktypes)
|
||||||
atc.controllers[pts]={command=fields.command, arrowconn=conn1}
|
atc.controllers[pts]={command=fields.command, arrowconn=conns[1].c}
|
||||||
if advtrains.detector.on_node[pts] then
|
if advtrains.detector.on_node[pts] then
|
||||||
atc.send_command(pos)
|
atc.send_command(pos)
|
||||||
end
|
end
|
||||||
|
@ -145,8 +145,8 @@ function atc.get_atc_controller_formspec(pos, meta)
|
||||||
local command=meta:get_string("command")
|
local command=meta:get_string("command")
|
||||||
local command_on=meta:get_string("command_on")
|
local command_on=meta:get_string("command_on")
|
||||||
local channel=meta:get_string("channel")
|
local channel=meta:get_string("channel")
|
||||||
local formspec="size[8,6]"..
|
local formspec="size[8,6]"
|
||||||
"dropdown[0,0;3;mode;static,mesecon,digiline;"..mode.."]"
|
-- "dropdown[0,0;3;mode;static,mesecon,digiline;"..mode.."]"
|
||||||
if mode<3 then
|
if mode<3 then
|
||||||
formspec=formspec.."field[0.5,1.5;7,1;command;"..attrans("Command")..";"..minetest.formspec_escape(command).."]"
|
formspec=formspec.."field[0.5,1.5;7,1;command;"..attrans("Command")..";"..minetest.formspec_escape(command).."]"
|
||||||
if tonumber(mode)==2 then
|
if tonumber(mode)==2 then
|
||||||
|
|
|
@ -52,97 +52,6 @@ function atround(number)
|
||||||
return math.floor(number+0.5)
|
return math.floor(number+0.5)
|
||||||
end
|
end
|
||||||
|
|
||||||
--vertical_transmit:
|
|
||||||
--[[
|
|
||||||
rely1, rely2 tell to which height the connections are pointed to. 1 means it will go up the next node
|
|
||||||
|
|
||||||
]]
|
|
||||||
|
|
||||||
function advtrains.conway(midreal, prev, drives_on)--in order prev,mid,return
|
|
||||||
local mid=advtrains.round_vector_floor_y(midreal)
|
|
||||||
|
|
||||||
local midnode_ok, middir1, middir2, midrely1, midrely2=advtrains.get_rail_info_at(mid, drives_on)
|
|
||||||
if not midnode_ok then
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
local next, chkdir, chkrely, y_offset
|
|
||||||
y_offset=0
|
|
||||||
--atprint(" in order mid1,mid2",middir1,middir2)
|
|
||||||
--try if it is dir1
|
|
||||||
local cor1=advtrains.dirCoordSet(mid, middir2)--<<<<
|
|
||||||
if cor1.x==prev.x and cor1.z==prev.z then--this was previous
|
|
||||||
next=advtrains.dirCoordSet(mid, middir1)
|
|
||||||
if midrely1>=1 then
|
|
||||||
next.y=next.y+1
|
|
||||||
--atprint("found midrely1 to be >=1: next is now "..(next and minetest.pos_to_string(next) or "nil"))
|
|
||||||
y_offset=1
|
|
||||||
end
|
|
||||||
chkdir=middir1
|
|
||||||
chkrely=midrely1
|
|
||||||
--atprint("dir2 applied next pos:",minetest.pos_to_string(next),"(chkdir is ",chkdir,")")
|
|
||||||
end
|
|
||||||
--dir2???
|
|
||||||
local cor2=advtrains.dirCoordSet(mid, middir1)--<<<<
|
|
||||||
if atround(cor2.x)==atround(prev.x) and atround(cor2.z)==atround(prev.z) then
|
|
||||||
next=advtrains.dirCoordSet(mid, middir2)--dir2 wird überprüft, alles gut.
|
|
||||||
if midrely2>=1 then
|
|
||||||
next.y=next.y+1
|
|
||||||
--atprint("found midrely2 to be >=1: next is now "..(next and minetest.pos_to_string(next) or "nil"))
|
|
||||||
y_offset=1
|
|
||||||
end
|
|
||||||
chkdir=middir2
|
|
||||||
chkrely=midrely2
|
|
||||||
--atprint(" dir2 applied next pos:",minetest.pos_to_string(next),"(chkdir is ",chkdir,")")
|
|
||||||
end
|
|
||||||
--atprint("dir applied next pos: "..(next and minetest.pos_to_string(next) or "nil").."(chkdir is "..(chkdir or "nil")..", y-offset "..y_offset..")")
|
|
||||||
--is there a next
|
|
||||||
if not next then
|
|
||||||
--atprint("in conway: no next rail(nil), returning!")
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
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
|
|
||||||
--atprint("in conway: next "..minetest.pos_to_string(next).." not a rail, trying one node below!")
|
|
||||||
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), drives_on)
|
|
||||||
if(not nextnode_ok) then
|
|
||||||
--atprint("in conway: one below "..minetest.pos_to_string(next).." is not a rail either, returning!")
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--is this next rail connecting to the mid?
|
|
||||||
if not ( (((nextdir1+8)%16)==chkdir and nextrely1==chkrely-y_offset) or (((nextdir2+8)%16)==chkdir and nextrely2==chkrely-y_offset) ) then
|
|
||||||
--atprint("in conway: next "..minetest.pos_to_string(next).." not connecting, trying one node below!")
|
|
||||||
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), drives_on)
|
|
||||||
if(not nextnode_ok) then
|
|
||||||
--atprint("in conway: (at connecting if check again) one below "..minetest.pos_to_string(next).." is not a rail either, returning!")
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
if not ( (((nextdir1+8)%16)==chkdir and nextrely1==chkrely) or (((nextdir2+8)%16)==chkdir and nextrely2==chkrely) ) then
|
|
||||||
--atprint("in conway: one below "..minetest.pos_to_string(next).." rail not connecting, returning!")
|
|
||||||
--atprint(" in order mid1,2,next1,2,chkdir "..middir1.." "..middir2.." "..nextdir1.." "..nextdir2.." "..chkdir)
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--atprint("conway found rail.")
|
|
||||||
return vector.add(advtrains.round_vector_floor_y(next), {x=0, y=nextrailheight, z=0}), chkdir
|
|
||||||
end
|
|
||||||
--TODO use this
|
|
||||||
function advtrains.oppd(dir)
|
|
||||||
return ((dir+8)%16)
|
|
||||||
end
|
|
||||||
|
|
||||||
function advtrains.round_vector_floor_y(vec)
|
function advtrains.round_vector_floor_y(vec)
|
||||||
return {x=math.floor(vec.x+0.5), y=math.floor(vec.y), z=math.floor(vec.z+0.5)}
|
return {x=math.floor(vec.x+0.5), y=math.floor(vec.y), z=math.floor(vec.z+0.5)}
|
||||||
end
|
end
|
||||||
|
@ -176,6 +85,20 @@ function advtrains.yawToAnyDir(yaw)
|
||||||
end
|
end
|
||||||
return min_conn
|
return min_conn
|
||||||
end
|
end
|
||||||
|
function advtrains.yawToClosestConn(yaw, conns)
|
||||||
|
local min_connid, min_diff=1, 10
|
||||||
|
for connid, conn in ipairs(conns) do
|
||||||
|
local uvec = vector.normalize(advtrains.dirToCoord(conn.c))
|
||||||
|
local yaw1 = math.atan2(uvec.z, uvec.x)
|
||||||
|
local diff = advtrains.minAngleDiffRad(yaw, yaw1)
|
||||||
|
if diff < min_diff then
|
||||||
|
min_connid = connid
|
||||||
|
min_diff = diff
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return min_connid
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
function advtrains.minAngleDiffRad(r1, r2)
|
function advtrains.minAngleDiffRad(r1, r2)
|
||||||
local pi, pi2 = math.pi, 2*math.pi
|
local pi, pi2 = math.pi, 2*math.pi
|
||||||
|
@ -300,3 +223,95 @@ end
|
||||||
function advtrains.ms_to_kmh(speed)
|
function advtrains.ms_to_kmh(speed)
|
||||||
return speed * 3.6
|
return speed * 3.6
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 4 possible inputs:
|
||||||
|
-- integer: just do that modulo calculation
|
||||||
|
-- table with c set: rotate c
|
||||||
|
-- table with tables: rotate each
|
||||||
|
-- table with integers: rotate each (probably no use case)
|
||||||
|
function advtrains.rotate_conn_by(conn, rotate)
|
||||||
|
if tonumber(conn) then
|
||||||
|
return (conn+rotate)%AT_CMAX
|
||||||
|
elseif conn.c then
|
||||||
|
return { c = (conn.c+rotate)%AT_CMAX, y = conn.y}
|
||||||
|
end
|
||||||
|
local tmp={}
|
||||||
|
for connid, data in ipairs(conn) do
|
||||||
|
tmp[connid]=advtrains.rotate_conn_by(data, rotate)
|
||||||
|
end
|
||||||
|
return tmp
|
||||||
|
end
|
||||||
|
|
||||||
|
--TODO use this
|
||||||
|
function advtrains.oppd(dir)
|
||||||
|
return advtrains.rotate_conn_by(dir, AT_CMAX/2)
|
||||||
|
end
|
||||||
|
--conn_to_match like rotate_conn_by
|
||||||
|
--other_conns have to be a table of conn tables!
|
||||||
|
function advtrains.conn_matches_to(conn, other_conns)
|
||||||
|
if tonumber(conn) then
|
||||||
|
for connid, data in ipairs(other_conns) do
|
||||||
|
if advtrains.oppd(conn) == data.c then return connid end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
elseif conn.c then
|
||||||
|
for connid, data in ipairs(other_conns) do
|
||||||
|
local cmp = advtrains.oppd(conn)
|
||||||
|
if cmp.c == data.c and (cmp.y or 0) == (data.y or 0) then return connid end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
local tmp={}
|
||||||
|
for connid, data in ipairs(conn) do
|
||||||
|
local backmatch = advtrains.conn_matches_to(data, other_conns)
|
||||||
|
if backmatch then return backmatch, connid end --returns <connid of other rail> <connid of this rail>
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- returns: <adjacent pos>, <conn index of adjacent>, <my conn index>, <railheight of adjacent>
|
||||||
|
function advtrains.get_adjacent_rail(this_posnr, this_conns_p, conn_idx, drives_on)
|
||||||
|
local this_pos = advtrains.round_vector_floor_y(this_posnr)
|
||||||
|
local this_conns = this_conns_p
|
||||||
|
if not this_conns then
|
||||||
|
_, this_conns = advtrains.get_rail_info_at(this_pos)
|
||||||
|
end
|
||||||
|
if not conn_idx then
|
||||||
|
for coni, _ in ipairs(this_conns) do
|
||||||
|
local adj_pos, adj_conn_idx, _, nry = advtrains.get_adjacent_rail(this_pos, this_conns, coni)
|
||||||
|
if adj_pos then return adj_pos,adj_conn_idx,coni,nry end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local conn = this_conns[conn_idx]
|
||||||
|
local conn_y = conn.y or 0
|
||||||
|
local adj_pos = advtrains.dirCoordSet(this_pos, conn.c);
|
||||||
|
|
||||||
|
while conn_y>=1 do
|
||||||
|
conn_y = conn_y - 1
|
||||||
|
adj_pos.y = adj_pos.y + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
local nextnode_ok, nextconns, nextrail_y=advtrains.get_rail_info_at(adj_pos, drives_on)
|
||||||
|
if not nextnode_ok then
|
||||||
|
adj_pos.y = adj_pos.y - 1
|
||||||
|
conn_y = conn_y + 1
|
||||||
|
nextnode_ok, nextconns, nextrail_y=advtrains.get_rail_info_at(adj_pos, drives_on)
|
||||||
|
if not nextnode_ok then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local adj_connid = advtrains.conn_matches_to({c=conn.c, y=conn_y}, nextconns)
|
||||||
|
if adj_connid then
|
||||||
|
return adj_pos, adj_connid, conn_idx, nextrail_y
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
local connlku={[2]={2,1}, [3]={2,1,1}, [4]={2,1,4,3}}
|
||||||
|
function advtrains.get_matching_conn(conn, nconns)
|
||||||
|
return connlku[nconns][conn]
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,9 @@ end
|
||||||
|
|
||||||
--advtrains
|
--advtrains
|
||||||
|
|
||||||
|
--Constant for maximum connection value/division of the circle
|
||||||
|
AT_CMAX = 16
|
||||||
|
|
||||||
advtrains = {trains={}, wagon_save={}, player_to_train_mapping={}}
|
advtrains = {trains={}, wagon_save={}, player_to_train_mapping={}}
|
||||||
|
|
||||||
--pcall
|
--pcall
|
||||||
|
@ -99,6 +102,13 @@ atwarn=function(t, ...)
|
||||||
end
|
end
|
||||||
sid=function(id) if id then return string.sub(id, -6) end end
|
sid=function(id) if id then return string.sub(id, -6) end end
|
||||||
|
|
||||||
|
--TEMP
|
||||||
|
atdebug=function(t, ...)
|
||||||
|
local text=advtrains.print_concat_table({t, ...})
|
||||||
|
minetest.log("action", "[advtrains]"..text)
|
||||||
|
minetest.chat_send_all("[advtrains]"..text)
|
||||||
|
end
|
||||||
|
|
||||||
if minetest.settings:get_bool("advtrains_enable_debugging") then
|
if minetest.settings:get_bool("advtrains_enable_debugging") then
|
||||||
atprint=function(t, ...)
|
atprint=function(t, ...)
|
||||||
local context=advtrains.atprint_context_tid or ""
|
local context=advtrains.atprint_context_tid or ""
|
||||||
|
@ -135,7 +145,7 @@ advtrains.meseconrules =
|
||||||
{x=0, y=-2, z=0}}
|
{x=0, y=-2, z=0}}
|
||||||
|
|
||||||
|
|
||||||
|
dofile(advtrains.modpath.."/path.lua")
|
||||||
dofile(advtrains.modpath.."/trainlogic.lua")
|
dofile(advtrains.modpath.."/trainlogic.lua")
|
||||||
dofile(advtrains.modpath.."/trainhud.lua")
|
dofile(advtrains.modpath.."/trainhud.lua")
|
||||||
dofile(advtrains.modpath.."/trackplacer.lua")
|
dofile(advtrains.modpath.."/trackplacer.lua")
|
||||||
|
|
|
@ -132,9 +132,12 @@ function ndb.get_node_raw(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function ndb.swap_node(pos, node)
|
function ndb.swap_node(pos, node, no_inval)
|
||||||
minetest.swap_node(pos, node)
|
minetest.swap_node(pos, node)
|
||||||
ndb.update(pos, node)
|
ndb.update(pos, node)
|
||||||
|
if not no_inval then
|
||||||
|
advtrains.invalidate_all_paths(pos)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function ndb.update(pos, pnode)
|
function ndb.update(pos, pnode)
|
||||||
|
@ -175,30 +178,15 @@ function advtrains.get_rail_info_at(pos, drives_on)
|
||||||
local rdp=advtrains.round_vector_floor_y(pos)
|
local rdp=advtrains.round_vector_floor_y(pos)
|
||||||
|
|
||||||
local node=ndb.get_node_or_nil(rdp)
|
local node=ndb.get_node_or_nil(rdp)
|
||||||
|
if not node then return end
|
||||||
|
|
||||||
--still no node?
|
|
||||||
--advtrains.trackdb is nil when there's no data available.
|
|
||||||
if not node then
|
|
||||||
if advtrains.trackdb then
|
|
||||||
--try raildb (see trackdb_legacy.lua)
|
|
||||||
local dbe=(advtrains.trackdb[rdp.y] and advtrains.trackdb[rdp.y][rdp.x] and advtrains.trackdb[rdp.y][rdp.x][rdp.z])
|
|
||||||
if dbe then
|
|
||||||
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
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return nil
|
|
||||||
end
|
|
||||||
local nodename=node.name
|
local nodename=node.name
|
||||||
if(not advtrains.is_track_and_drives_on(nodename, drives_on)) then
|
if(not advtrains.is_track_and_drives_on(nodename, drives_on)) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local conn1, conn2, rely1, rely2, railheight, tracktype=advtrains.get_track_connections(node.name, node.param2)
|
local conns, railheight, tracktype=advtrains.get_track_connections(node.name, node.param2)
|
||||||
|
|
||||||
return true, conn1, conn2, rely1, rely2, railheight
|
return true, conns, railheight
|
||||||
end
|
end
|
||||||
|
|
||||||
ndb.run_lbm = function(pos, node)
|
ndb.run_lbm = function(pos, node)
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
-- path.lua
|
||||||
|
-- Functions for pathpredicting, put in a separate file.
|
||||||
|
|
||||||
|
function advtrains.conway(midreal, prev, drives_on)--in order prev,mid,return
|
||||||
|
local mid=advtrains.round_vector_floor_y(midreal)
|
||||||
|
|
||||||
|
local midnode_ok, midconns=advtrains.get_rail_info_at(mid, drives_on)
|
||||||
|
if not midnode_ok then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local pconnid
|
||||||
|
for connid, conn in ipairs(midconns) do
|
||||||
|
local tps = advtrains.dirCoordSet(mid, conn.c)
|
||||||
|
if tps.x==prev.x and tps.z==prev.z then
|
||||||
|
pconnid=connid
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local nconnid = advtrains.get_matching_conn(pconnid, #midconns)
|
||||||
|
|
||||||
|
local next, next_connid, _, nextrailheight = advtrains.get_adjacent_rail(mid, midconns, nconnid, drives_on)
|
||||||
|
if not next then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
return vector.add(advtrains.round_vector_floor_y(next), {x=0, y=nextrailheight, z=0}), midconns[nconnid].c
|
||||||
|
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
|
||||||
|
local gen_back= - train.trainlen - path_pregen
|
||||||
|
if regular then
|
||||||
|
gen_front=math.max(train.index, train.detector_old_index) + path_pregen
|
||||||
|
gen_back=math.min(train.end_index, train.detector_old_end_index) - path_pregen
|
||||||
|
end
|
||||||
|
|
||||||
|
local maxn=train.path_extent_max or 0
|
||||||
|
while maxn < gen_front do--pregenerate
|
||||||
|
local conway
|
||||||
|
if train.max_index_on_track == maxn then
|
||||||
|
--atprint("maxn conway for ",maxn,train.path[maxn],maxn-1,train.path[maxn-1])
|
||||||
|
conway=advtrains.conway(train.path[maxn], train.path[maxn-1], train.drives_on)
|
||||||
|
end
|
||||||
|
if conway then
|
||||||
|
train.path[maxn+1]=conway
|
||||||
|
train.max_index_on_track=maxn+1
|
||||||
|
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 ",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
|
||||||
|
local conway
|
||||||
|
if train.min_index_on_track == minn then
|
||||||
|
--atprint("minn conway for ",minn,train.path[minn],minn+1,train.path[minn+1])
|
||||||
|
conway=advtrains.conway(train.path[minn], train.path[minn+1], train.drives_on)
|
||||||
|
end
|
||||||
|
if conway then
|
||||||
|
train.path[minn-1]=conway
|
||||||
|
train.min_index_on_track=minn-1
|
||||||
|
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 ",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
|
|
@ -37,12 +37,12 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
rules=advtrains.meseconrules,
|
rules=advtrains.meseconrules,
|
||||||
["action_"..f.as] = function (pos, node)
|
["action_"..f.as] = function (pos, node)
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_"..f.as..rotation, param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_"..f.as..rotation, param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
}},
|
}},
|
||||||
on_rightclick=function(pos, node, player)
|
on_rightclick=function(pos, node, player)
|
||||||
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_"..f.as..rotation, param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:retrosignal_"..f.as..rotation, param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
@ -72,20 +72,20 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
rules=advtrains.meseconrules,
|
rules=advtrains.meseconrules,
|
||||||
["action_"..f.as] = function (pos, node)
|
["action_"..f.as] = function (pos, node)
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f.as..rotation, param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f.as..rotation, param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
}},
|
}},
|
||||||
luaautomation = {
|
luaautomation = {
|
||||||
getstate = f.ls,
|
getstate = f.ls,
|
||||||
setstate = function(pos, node, newstate)
|
setstate = function(pos, node, newstate)
|
||||||
if newstate == f.als then
|
if newstate == f.als then
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f.as..rotation, param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f.as..rotation, param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
on_rightclick=function(pos, node, player)
|
on_rightclick=function(pos, node, player)
|
||||||
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f.as..rotation, param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_"..f.as..rotation, param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
@ -121,20 +121,20 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
rules = mrules_wallsignal,
|
rules = mrules_wallsignal,
|
||||||
["action_"..f.as] = function (pos, node)
|
["action_"..f.as] = function (pos, node)
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_"..f.as, param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_"..f.as, param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
}},
|
}},
|
||||||
luaautomation = {
|
luaautomation = {
|
||||||
getstate = f.ls,
|
getstate = f.ls,
|
||||||
setstate = function(pos, node, newstate)
|
setstate = function(pos, node, newstate)
|
||||||
if newstate == f.als then
|
if newstate == f.als then
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_"..f.as, param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_"..f.as, param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
on_rightclick=function(pos, node, player)
|
on_rightclick=function(pos, node, player)
|
||||||
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_"..f.as, param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:signal_wall_"..loc.."_"..f.as, param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
@ -167,20 +167,20 @@ minetest.register_node("advtrains:across_off", {
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
rules = advtrains.meseconrules,
|
rules = advtrains.meseconrules,
|
||||||
action_on = function (pos, node)
|
action_on = function (pos, node)
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:across_on", param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:across_on", param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
}},
|
}},
|
||||||
luaautomation = {
|
luaautomation = {
|
||||||
getstate = "off",
|
getstate = "off",
|
||||||
setstate = function(pos, node, newstate)
|
setstate = function(pos, node, newstate)
|
||||||
if newstate == "on" then
|
if newstate == "on" then
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:across_on", param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:across_on", param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
on_rightclick=function(pos, node, player)
|
on_rightclick=function(pos, node, player)
|
||||||
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:across_on", param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:across_on", param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
@ -208,20 +208,20 @@ minetest.register_node("advtrains:across_on", {
|
||||||
mesecons = {effector = {
|
mesecons = {effector = {
|
||||||
rules = advtrains.meseconrules,
|
rules = advtrains.meseconrules,
|
||||||
action_off = function (pos, node)
|
action_off = function (pos, node)
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:across_off", param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:across_off", param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
}},
|
}},
|
||||||
luaautomation = {
|
luaautomation = {
|
||||||
getstate = "on",
|
getstate = "on",
|
||||||
setstate = function(pos, node, newstate)
|
setstate = function(pos, node, newstate)
|
||||||
if newstate == "off" then
|
if newstate == "off" then
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:across_off", param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:across_off", param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
},
|
},
|
||||||
on_rightclick=function(pos, node, player)
|
on_rightclick=function(pos, node, player)
|
||||||
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
||||||
advtrains.ndb.swap_node(pos, {name = "advtrains:across_off", param2 = node.param2})
|
advtrains.ndb.swap_node(pos, {name = "advtrains:across_off", param2 = node.param2}, true)
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
|
@ -71,31 +71,35 @@ end
|
||||||
|
|
||||||
local function istrackandbc(pos_p, conn)
|
local function istrackandbc(pos_p, conn)
|
||||||
local tpos = pos_p
|
local tpos = pos_p
|
||||||
local cnode=minetest.get_node(advtrains.dirCoordSet(tpos, conn))
|
local cnode=minetest.get_node(advtrains.dirCoordSet(tpos, conn.c))
|
||||||
local bconn=(conn+8)%16
|
|
||||||
if advtrains.is_track_and_drives_on(cnode.name, advtrains.all_tracktypes) then
|
if advtrains.is_track_and_drives_on(cnode.name, advtrains.all_tracktypes) then
|
||||||
local cconn1, cconn2=advtrains.get_track_connections(cnode.name, cnode.param2)
|
local cconns=advtrains.get_track_connections(cnode.name, cnode.param2)
|
||||||
return cconn1==bconn or cconn2==bconn
|
return advtrains.conn_matches_to(conn, cconns)
|
||||||
end
|
end
|
||||||
--try the same 1 node below
|
--try the same 1 node below
|
||||||
tpos = {x=tpos.x, y=tpos.y-1, z=tpos.z}
|
tpos = {x=tpos.x, y=tpos.y-1, z=tpos.z}
|
||||||
cnode=minetest.get_node(advtrains.dirCoordSet(tpos, conn))
|
cnode=minetest.get_node(advtrains.dirCoordSet(tpos, conn.c))
|
||||||
bconn=(conn+8)%16
|
|
||||||
if advtrains.is_track_and_drives_on(cnode.name, advtrains.all_tracktypes) then
|
if advtrains.is_track_and_drives_on(cnode.name, advtrains.all_tracktypes) then
|
||||||
local cconn1, cconn2=advtrains.get_track_connections(cnode.name, cnode.param2)
|
local cconns=advtrains.get_track_connections(cnode.name, cnode.param2)
|
||||||
return cconn1==bconn or cconn2==bconn
|
return advtrains.conn_matches_to(conn, cconns)
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
function tp.find_already_connected(pos)
|
function tp.find_already_connected(pos)
|
||||||
local dnode=minetest.get_node(pos)
|
local dnode=minetest.get_node(pos)
|
||||||
local dconn1, dconn2=advtrains.get_track_connections(dnode.name, dnode.param2)
|
local dconns=advtrains.get_track_connections(dnode.name, dnode.param2)
|
||||||
if istrackandbc(pos, dconn1) and istrackandbc(pos, dconn2) then return dconn1, dconn2
|
local found_conn
|
||||||
elseif istrackandbc(pos, dconn1) then return dconn1
|
for connid, conn in ipairs(dconns) do
|
||||||
elseif istrackandbc(pos, dconn2) then return dconn2
|
if istrackandbc(pos, conn) then
|
||||||
|
if found_conn then --we found one in previous iteration
|
||||||
|
return true, true --signal that it's connected
|
||||||
|
else
|
||||||
|
found_conn = conn.c
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
return nil
|
return found_conn
|
||||||
end
|
end
|
||||||
function tp.rail_and_can_be_bent(originpos, conn)
|
function tp.rail_and_can_be_bent(originpos, conn)
|
||||||
local pos=advtrains.dirCoordSet(originpos, conn)
|
local pos=advtrains.dirCoordSet(originpos, conn)
|
||||||
|
@ -105,16 +109,15 @@ function tp.rail_and_can_be_bent(originpos, conn)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
local ndef=minetest.registered_nodes[node.name]
|
local ndef=minetest.registered_nodes[node.name]
|
||||||
local nnpref = ndef and ndef.nnpref
|
local nnpref = ndef and ndef.at_nnpref
|
||||||
if not nnpref then return false end
|
if not nnpref then return false end
|
||||||
local tr=tp.tracks[nnpref]
|
local tr=tp.tracks[nnpref]
|
||||||
if not tr then return false end
|
if not tr then return false end
|
||||||
if not tr.modify[node.name] then
|
if not tr.modify[node.name] then
|
||||||
--we actually can use this rail, but only if it already points to the desired direction.
|
--we actually can use this rail, but only if it already points to the desired direction.
|
||||||
local bconn=(conn+8)%16
|
|
||||||
if advtrains.is_track_and_drives_on(node.name, advtrains.all_tracktypes) then
|
if advtrains.is_track_and_drives_on(node.name, advtrains.all_tracktypes) then
|
||||||
local cconn1, cconn2=advtrains.get_track_connections(node.name, node.param2)
|
local cconns=advtrains.get_track_connections(node.name, node.param2)
|
||||||
return cconn1==bconn or cconn2==bconn
|
return advtrains.conn_matches_to(conn, cconns)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--rail at other end?
|
--rail at other end?
|
||||||
|
@ -135,16 +138,16 @@ function tp.rail_and_can_be_bent(originpos, conn)
|
||||||
end
|
end
|
||||||
function tp.bend_rail(originpos, conn)
|
function tp.bend_rail(originpos, conn)
|
||||||
local pos=advtrains.dirCoordSet(originpos, conn)
|
local pos=advtrains.dirCoordSet(originpos, conn)
|
||||||
local newdir=(conn+8)%16
|
local newdir=advtrains.oppd(conn)
|
||||||
local node=minetest.get_node(pos)
|
local node=minetest.get_node(pos)
|
||||||
local ndef=minetest.registered_nodes[node.name]
|
local ndef=minetest.registered_nodes[node.name]
|
||||||
local nnpref = ndef and ndef.nnpref
|
local nnpref = ndef and ndef.at_nnpref
|
||||||
if not nnpref then return false end
|
if not nnpref then return false end
|
||||||
local tr=tp.tracks[nnpref]
|
local tr=tp.tracks[nnpref]
|
||||||
if not tr then return false end
|
if not tr then return false end
|
||||||
--is rail already connected? no need to bend.
|
--is rail already connected? no need to bend.
|
||||||
local conn1, conn2=advtrains.get_track_connections(node.name, node.param2)
|
local conns=advtrains.get_track_connections(node.name, node.param2)
|
||||||
if newdir==conn1 or newdir==conn2 then
|
if advtrains.conn_matches_to(conn, conns) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
--rail at other end?
|
--rail at other end?
|
||||||
|
@ -309,6 +312,7 @@ minetest.register_craftitem("advtrains:trackworker",{
|
||||||
if not name then
|
if not name then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
local has_aux1_down = placer:get_player_control().aux1
|
||||||
if pointed_thing.type=="node" then
|
if pointed_thing.type=="node" then
|
||||||
local pos=pointed_thing.under
|
local pos=pointed_thing.under
|
||||||
if advtrains.is_protected(pos, name) then
|
if advtrains.is_protected(pos, name) then
|
||||||
|
@ -319,6 +323,13 @@ minetest.register_craftitem("advtrains:trackworker",{
|
||||||
|
|
||||||
--if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
|
--if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
|
||||||
if advtrains.get_train_at_pos(pos) then return end
|
if advtrains.get_train_at_pos(pos) then return end
|
||||||
|
|
||||||
|
if has_aux1_down then
|
||||||
|
--feature: flip the node by 180°
|
||||||
|
--i've always wanted this!
|
||||||
|
advtrains.ndb.swap_node(pos, {name=node.name, param2=(node.param2+2)%4})
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$")
|
local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$")
|
||||||
--atprint(node.name.."\npattern recognizes:"..nodeprefix.." / "..railtype.." / "..rotation)
|
--atprint(node.name.."\npattern recognizes:"..nodeprefix.." / "..railtype.." / "..rotation)
|
||||||
|
|
|
@ -34,90 +34,80 @@ vert2={
|
||||||
advtrains.all_tracktypes={}
|
advtrains.all_tracktypes={}
|
||||||
|
|
||||||
--definition preparation
|
--definition preparation
|
||||||
local function conns(c1, c2, r1, r2, rh, rots) return {conn1=c1, conn2=c2, rely1=r1, rely2=r2, railheight=rh} end
|
local function conns(c1, c2, r1, r2) return {{c=c1, y=r1}, {c=c2, y=r2}} end
|
||||||
|
local function conns3(c1, c2, c3, r1, r2, r3) return {{c=c1, y=r1}, {c=c2, y=r2}, {c=c3, y=r3}} end
|
||||||
|
|
||||||
advtrains.ap={}
|
advtrains.ap={}
|
||||||
advtrains.ap.t_30deg_flat={
|
advtrains.ap.t_30deg_flat={
|
||||||
regstep=1,
|
regstep=1,
|
||||||
variant={
|
variant={
|
||||||
st=conns(0,8),
|
st={
|
||||||
cr=conns(0,7),
|
conns = conns(0,8),
|
||||||
swlst=conns(0,8),
|
desc = "straight",
|
||||||
swlcr=conns(0,7),
|
tpdouble = true,
|
||||||
swrst=conns(0,8),
|
tpsingle = true,
|
||||||
swrcr=conns(0,9),
|
trackworker = "cr",
|
||||||
},
|
},
|
||||||
description={
|
cr={
|
||||||
st="straight",
|
conns = conns(0,7),
|
||||||
cr="curve",
|
desc = "curve",
|
||||||
swlst="left switch (straight)",
|
tpdouble = true,
|
||||||
swlcr="left switch (curve)",
|
trackworker = "swlst",
|
||||||
swrst="right switch (straight)",
|
},
|
||||||
swrcr="right switch (curve)",
|
swlst={
|
||||||
},
|
conns = conns3(0,8,7),
|
||||||
switch={
|
desc = "left switch (straight)",
|
||||||
swlst="swlcr",
|
trackworker = "swrst",
|
||||||
swlcr="swlst",
|
switchalt = "swlcr",
|
||||||
swrst="swrcr",
|
switchmc = "on",
|
||||||
swrcr="swrst",
|
switchst = "st",
|
||||||
},
|
},
|
||||||
switchmc={
|
swlcr={
|
||||||
swlst="on",
|
conns = conns3(0,7,8),
|
||||||
swlcr="off",
|
desc = "left switch (curve)",
|
||||||
swrst="on",
|
trackworker = "swrcr",
|
||||||
swrcr="off",
|
switchalt = "swlst",
|
||||||
},
|
switchmc = "off",
|
||||||
switchst={
|
switchst = "cr",
|
||||||
swlst="st",
|
},
|
||||||
swlcr="cr",
|
swrst={
|
||||||
swrst="st",
|
conns = conns3(0,8,9),
|
||||||
swrcr="cr",
|
desc = "right switch (straight)",
|
||||||
|
trackworker = "st",
|
||||||
|
switchalt = "swrcr",
|
||||||
|
switchmc = "on",
|
||||||
|
switchst = "st",
|
||||||
|
},
|
||||||
|
swrcr={
|
||||||
|
conns = conns3(0,9,8),
|
||||||
|
desc = "right switch (curve)",
|
||||||
|
trackworker = "st",
|
||||||
|
switchalt = "swrst",
|
||||||
|
switchmc = "off",
|
||||||
|
switchst = "cr",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
regtp=true,
|
regtp=true,
|
||||||
trackplacer={
|
|
||||||
st=true,
|
|
||||||
cr=true,
|
|
||||||
},
|
|
||||||
tpsingle={
|
|
||||||
st=true,
|
|
||||||
},
|
|
||||||
tpdefault="st",
|
tpdefault="st",
|
||||||
trackworker={
|
trackworker={
|
||||||
["swrcr"]="st",
|
["swrcr"]="st",
|
||||||
["swrst"]="st",
|
["swrst"]="st",
|
||||||
["st"]="cr",
|
|
||||||
["cr"]="swlst",
|
["cr"]="swlst",
|
||||||
["swlcr"]="swrcr",
|
["swlcr"]="swrcr",
|
||||||
["swlst"]="swrst",
|
["swlst"]="swrst",
|
||||||
},
|
},
|
||||||
rotation={"", "_30", "_45", "_60"},
|
rotation={"", "_30", "_45", "_60"},
|
||||||
slopenodes={},
|
|
||||||
increativeinv={},
|
|
||||||
}
|
}
|
||||||
advtrains.ap.t_30deg_slope={
|
advtrains.ap.t_30deg_slope={
|
||||||
regstep=1,
|
regstep=1,
|
||||||
variant={
|
variant={
|
||||||
vst1=conns(8,0,0,0.5,0.25),
|
vst1={conns = conns(8,0,0,0.5), rail_y = 0.25, desc = "steep uphill 1/2", slope=true},
|
||||||
vst2=conns(8,0,0.5,1,0.75),
|
vst2={conns = conns(8,0,0.5,1), rail_y = 0.75, desc = "steep uphill 2/2", slope=true},
|
||||||
vst31=conns(8,0,0,0.33,0.16),
|
vst31={conns = conns(8,0,0,0.33), rail_y = 0.16, desc = "uphill 1/3", slope=true},
|
||||||
vst32=conns(8,0,0.33,0.66,0.5),
|
vst32={conns = conns(8,0,0.33,0.66), rail_y = 0.5, desc = "uphill 2/3", slope=true},
|
||||||
vst33=conns(8,0,0.66,1,0.83),
|
vst33={conns = conns(8,0,0.66,1), rail_y = 0.83, desc = "uphill 3/3", slope=true},
|
||||||
},
|
},
|
||||||
description={
|
|
||||||
vst1="steep uphill 1/2",
|
|
||||||
vst2="steep uphill 2/2",
|
|
||||||
vst31="uphill 1/3",
|
|
||||||
vst32="uphill 2/3",
|
|
||||||
vst33="uphill 3/3",
|
|
||||||
},
|
|
||||||
switch={},
|
|
||||||
switchmc={},
|
|
||||||
switchst={},
|
|
||||||
regsp=true,
|
regsp=true,
|
||||||
slopenodes={
|
|
||||||
vst1=true, vst2=true,
|
|
||||||
vst31=true, vst32=true, vst33=true,
|
|
||||||
},
|
|
||||||
slopeplacer={
|
slopeplacer={
|
||||||
[2]={"vst1", "vst2"},
|
[2]={"vst1", "vst2"},
|
||||||
[3]={"vst31", "vst32", "vst33"},
|
[3]={"vst31", "vst32", "vst33"},
|
||||||
|
@ -134,125 +124,91 @@ advtrains.ap.t_30deg_slope={
|
||||||
advtrains.ap.t_30deg_straightonly={
|
advtrains.ap.t_30deg_straightonly={
|
||||||
regstep=1,
|
regstep=1,
|
||||||
variant={
|
variant={
|
||||||
st=conns(0,8),
|
st={
|
||||||
},
|
conns = conns(0,8),
|
||||||
description={
|
desc = "straight",
|
||||||
st="straight",
|
tpdouble = true,
|
||||||
},
|
tpsingle = true,
|
||||||
switch={
|
trackworker = "st",
|
||||||
},
|
},
|
||||||
switchmc={
|
|
||||||
},
|
},
|
||||||
regtp=true,
|
regtp=true,
|
||||||
trackplacer={
|
|
||||||
},
|
|
||||||
tpsingle={
|
|
||||||
},
|
|
||||||
tpdefault="st",
|
tpdefault="st",
|
||||||
trackworker={
|
|
||||||
["st"]="st",
|
|
||||||
},
|
|
||||||
trackplacer={
|
|
||||||
st=true,
|
|
||||||
},
|
|
||||||
tpsingle={
|
|
||||||
st=true,
|
|
||||||
},
|
|
||||||
slopenodes={},
|
|
||||||
rotation={"", "_30", "_45", "_60"},
|
rotation={"", "_30", "_45", "_60"},
|
||||||
increativeinv={"st"},
|
|
||||||
}
|
}
|
||||||
advtrains.ap.t_30deg_straightonly_noplacer={
|
advtrains.ap.t_30deg_straightonly_noplacer={
|
||||||
regstep=1,
|
regstep=1,
|
||||||
variant={
|
variant={
|
||||||
st=conns(0,8),
|
st={
|
||||||
},
|
conns = conns(0,8),
|
||||||
description={
|
desc = "straight",
|
||||||
st="straight",
|
tpdouble = true,
|
||||||
},
|
tpsingle = true,
|
||||||
switch={
|
trackworker = "st",
|
||||||
},
|
},
|
||||||
switchmc={
|
|
||||||
},
|
|
||||||
regtp=false,
|
|
||||||
trackplacer={
|
|
||||||
},
|
|
||||||
tpsingle={
|
|
||||||
},
|
},
|
||||||
tpdefault="st",
|
tpdefault="st",
|
||||||
trackworker={
|
|
||||||
["st"]="st",
|
|
||||||
},
|
|
||||||
trackplacer={
|
|
||||||
st=true,
|
|
||||||
},
|
|
||||||
tpsingle={
|
|
||||||
st=true,
|
|
||||||
},
|
|
||||||
slopenodes={},
|
|
||||||
rotation={"", "_30", "_45", "_60"},
|
rotation={"", "_30", "_45", "_60"},
|
||||||
increativeinv={"st"},
|
|
||||||
}
|
}
|
||||||
advtrains.ap.t_45deg={
|
advtrains.ap.t_45deg={
|
||||||
regstep=2,
|
regstep=2,
|
||||||
variant={
|
variant={
|
||||||
st=conns(0,8),
|
st={
|
||||||
cr=conns(0,6),
|
conns = conns(0,8),
|
||||||
swlst=conns(0,8),
|
desc = "straight",
|
||||||
swlcr=conns(0,6),
|
tpdouble = true,
|
||||||
swrst=conns(0,8),
|
tpsingle = true,
|
||||||
swrcr=conns(0,10),
|
trackworker = "cr",
|
||||||
vst1=conns(8,0,0,0.5,0.25),
|
},
|
||||||
vst2=conns(8,0,0.5,1,0.75),
|
cr={
|
||||||
},
|
conns = conns(0,6),
|
||||||
description={
|
desc = "curve",
|
||||||
st="straight",
|
tpdouble = true,
|
||||||
cr="curve",
|
trackworker = "swlst",
|
||||||
swlst="left switch (straight)",
|
},
|
||||||
swlcr="left switch (curve)",
|
swlst={
|
||||||
swrst="right switch (straight)",
|
conns = conns3(0,8,6),
|
||||||
swrcr="right switch (curve)",
|
desc = "left switch (straight)",
|
||||||
vst1="vertical lower node",
|
trackworker = "swrst",
|
||||||
vst2="vertical upper node",
|
switchalt = "swlcr",
|
||||||
},
|
switchmc = "on",
|
||||||
switch={
|
switchst = "st",
|
||||||
swlst="swlcr",
|
},
|
||||||
swlcr="swlst",
|
swlcr={
|
||||||
swrst="swrcr",
|
conns = conns3(0,6,8),
|
||||||
swrcr="swrst",
|
desc = "left switch (curve)",
|
||||||
},
|
trackworker = "swrcr",
|
||||||
switchmc={
|
switchalt = "swlst",
|
||||||
swlst="on",
|
switchmc = "off",
|
||||||
swlcr="off",
|
switchst = "cr",
|
||||||
swrst="on",
|
},
|
||||||
swrcr="off",
|
swrst={
|
||||||
},
|
conns = conns3(0,8,10),
|
||||||
switchst={
|
desc = "right switch (straight)",
|
||||||
swlst="st",
|
trackworker = "st",
|
||||||
swlcr="cr",
|
switchalt = "swrcr",
|
||||||
swrst="st",
|
switchmc = "on",
|
||||||
swrcr="cr",
|
switchst = "st",
|
||||||
|
},
|
||||||
|
swrcr={
|
||||||
|
conns = conns3(0,10,8),
|
||||||
|
desc = "right switch (curve)",
|
||||||
|
trackworker = "st",
|
||||||
|
switchalt = "swrst",
|
||||||
|
switchmc = "off",
|
||||||
|
switchst = "cr",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
regtp=true,
|
regtp=true,
|
||||||
trackplacer={
|
|
||||||
st=true,
|
|
||||||
cr=true,
|
|
||||||
},
|
|
||||||
tpsingle={
|
|
||||||
st=true,
|
|
||||||
},
|
|
||||||
tpdefault="st",
|
tpdefault="st",
|
||||||
trackworker={
|
trackworker={
|
||||||
["swrcr"]="st",
|
["swrcr"]="st",
|
||||||
["swrst"]="st",
|
["swrst"]="st",
|
||||||
["st"]="cr",
|
|
||||||
["cr"]="swlst",
|
["cr"]="swlst",
|
||||||
["swlcr"]="swrcr",
|
["swlcr"]="swrcr",
|
||||||
["swlst"]="swrst",
|
["swlst"]="swrst",
|
||||||
},
|
},
|
||||||
slopenodes={},
|
rotation={"", "_30", "_45", "_60"},
|
||||||
rotation={"", "_45"},
|
|
||||||
increativeinv={vst1=true, vst2=true}
|
|
||||||
}
|
}
|
||||||
advtrains.trackpresets = advtrains.ap
|
advtrains.trackpresets = advtrains.ap
|
||||||
|
|
||||||
|
@ -269,98 +225,23 @@ advtrains.trackpresets = advtrains.ap
|
||||||
(each a table with indices 0-3, for if to register a rail with this 'rotation' table entry. nil is assumed as 'all', set {} to not register at all)
|
(each a table with indices 0-3, for if to register a rail with this 'rotation' table entry. nil is assumed as 'all', set {} to not register at all)
|
||||||
}
|
}
|
||||||
common={} change something on common rail appearance
|
common={} change something on common rail appearance
|
||||||
}]]
|
}
|
||||||
|
[18.12.17] Note on new connection system:
|
||||||
|
In order to support real rail crossing nodes and finally make the trackplacer respect switches, I changed the connection system.
|
||||||
|
There can be a variable number of connections available. These are specified as tuples {c=<connection>, y=<rely>}
|
||||||
|
The table "at_conns" consists of {<conn1>, <conn2>...}
|
||||||
|
the "at_rail_y" property holds the value that was previously called "railheight"
|
||||||
|
Depending on the number of connections:
|
||||||
|
2 conns: regular rail
|
||||||
|
3 conns: switch:
|
||||||
|
- when train passes in at conn1, will move out of conn2
|
||||||
|
- when train passes in at conn2 or conn3, will move out of conn1
|
||||||
|
4 conns: cross (or cross switch, depending on arrangement of conns):
|
||||||
|
- conn1 <> conn2
|
||||||
|
- conn3 <> conn4
|
||||||
|
]]
|
||||||
|
|
||||||
function advtrains.register_tracks(tracktype, def, preset)
|
function advtrains.register_tracks(tracktype, def, preset)
|
||||||
local function make_switchfunc(suffix_target, mesecon_state, is_state)
|
|
||||||
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(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(pos)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
local mesec
|
|
||||||
if mesecon_state then -- if mesecons is not wanted, do not.
|
|
||||||
mesec = {effector = {
|
|
||||||
["action_"..mesecon_state] = switchfunc,
|
|
||||||
rules=advtrains.meseconrules
|
|
||||||
}}
|
|
||||||
end
|
|
||||||
return rcswitchfunc, mesec,
|
|
||||||
{
|
|
||||||
getstate = is_state,
|
|
||||||
setstate = switchfunc,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
local function make_overdef(suffix, rotation, conns, rcswitchfunc, mesecontbl, luaautomation, in_creative_inv, drop_slope)
|
|
||||||
local img_suffix=suffix..rotation
|
|
||||||
return {
|
|
||||||
mesh = def.shared_model or (def.models_prefix.."_"..img_suffix..def.models_suffix),
|
|
||||||
tiles = {def.shared_texture or (def.texture_prefix.."_"..img_suffix..".png"), def.second_texture},
|
|
||||||
--inventory_image = def.texture_prefix.."_"..img_suffix..".png",
|
|
||||||
--wield_image = def.texture_prefix.."_"..img_suffix..".png",
|
|
||||||
description=def.description.."("..preset.description[suffix]..rotation..")",
|
|
||||||
connect1=conns.conn1,
|
|
||||||
connect2=conns.conn2,
|
|
||||||
rely1=conns.rely1 or 0,
|
|
||||||
rely2=conns.rely2 or 0,
|
|
||||||
railheight=conns.railheight or 0,
|
|
||||||
|
|
||||||
on_rightclick=rcswitchfunc,
|
|
||||||
groups = {
|
|
||||||
attached_node=1,
|
|
||||||
["advtrains_track_"..tracktype]=1,
|
|
||||||
save_in_at_nodedb=1,
|
|
||||||
dig_immediate=2,
|
|
||||||
not_in_creative_inventory=(not in_creative_inv and 1 or nil),
|
|
||||||
not_blocking_trains=1,
|
|
||||||
},
|
|
||||||
mesecons=mesecontbl,
|
|
||||||
luaautomation=luaautomation,
|
|
||||||
drop = (drop_slope and def.nodename_prefix.."_slopeplacer" or def.nodename_prefix.."_placer"),
|
|
||||||
}
|
|
||||||
end
|
|
||||||
local function cycle_conns(conns, rotid)
|
|
||||||
local add=(rotid-1)*preset.regstep
|
|
||||||
return {
|
|
||||||
conn1=(conns.conn1+add)%16,
|
|
||||||
conn2=(conns.conn2+add)%16,
|
|
||||||
rely1=conns.rely1 or 0,
|
|
||||||
rely2=conns.rely2 or 0,
|
|
||||||
railheight=conns.railheight or 0,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
local common_def=advtrains.merge_tables({
|
|
||||||
description = def.description,
|
|
||||||
drawtype = "mesh",
|
|
||||||
paramtype="light",
|
|
||||||
paramtype2="facedir",
|
|
||||||
walkable = false,
|
|
||||||
selection_box = {
|
|
||||||
type = "fixed",
|
|
||||||
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
|
|
||||||
},
|
|
||||||
rely1=0,
|
|
||||||
rely2=0,
|
|
||||||
railheight=0,
|
|
||||||
drop=def.nodename_prefix.."_placer",
|
|
||||||
can_dig=function(pos)
|
|
||||||
return not advtrains.get_train_at_pos(pos)
|
|
||||||
end,
|
|
||||||
after_dig_node=function(pos)
|
|
||||||
advtrains.ndb.update(pos)
|
|
||||||
end,
|
|
||||||
after_place_node=function(pos)
|
|
||||||
advtrains.ndb.update(pos)
|
|
||||||
end,
|
|
||||||
nnpref = def.nodename_prefix,
|
|
||||||
}, def.common or {})
|
|
||||||
--make trackplacer base def
|
|
||||||
advtrains.trackplacer.register_tracktype(def.nodename_prefix, preset.tpdefault)
|
advtrains.trackplacer.register_tracktype(def.nodename_prefix, preset.tpdefault)
|
||||||
if preset.regtp then
|
if preset.regtp then
|
||||||
advtrains.trackplacer.register_track_placer(def.nodename_prefix, def.texture_prefix, def.description)
|
advtrains.trackplacer.register_track_placer(def.nodename_prefix, def.texture_prefix, def.description)
|
||||||
|
@ -368,45 +249,106 @@ function advtrains.register_tracks(tracktype, def, preset)
|
||||||
if preset.regsp then
|
if preset.regsp then
|
||||||
advtrains.slope.register_placer(def, preset)
|
advtrains.slope.register_placer(def, preset)
|
||||||
end
|
end
|
||||||
for suffix, conns in pairs(preset.variant) do
|
for suffix, var in pairs(preset.variant) do
|
||||||
for rotid, rotation in ipairs(preset.rotation) do
|
for rotid, rotation in ipairs(preset.rotation) do
|
||||||
if not def.formats[suffix] or def.formats[suffix][rotid] then
|
if not def.formats[suffix] or def.formats[suffix][rotid] then
|
||||||
local rcswitchfunc, mesecontbl, luaautomation
|
local img_suffix = suffix..rotation
|
||||||
if preset.switch[suffix] then
|
local ndef = advtrains.merge_tables({
|
||||||
rcswitchfunc, mesecontbl, luaautomation=make_switchfunc(preset.switch[suffix]..rotation, preset.switchmc[suffix], preset.switchst[suffix])
|
description=def.description.."("..(var.desc or "any")..rotation..")",
|
||||||
|
drawtype = "mesh",
|
||||||
|
paramtype="light",
|
||||||
|
paramtype2="facedir",
|
||||||
|
walkable = false,
|
||||||
|
selection_box = {
|
||||||
|
type = "fixed",
|
||||||
|
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
|
||||||
|
},
|
||||||
|
|
||||||
|
mesh = def.shared_model or (def.models_prefix.."_"..img_suffix..def.models_suffix),
|
||||||
|
tiles = {def.shared_texture or (def.texture_prefix.."_"..img_suffix..".png"), def.second_texture},
|
||||||
|
|
||||||
|
groups = {
|
||||||
|
attached_node=1,
|
||||||
|
["advtrains_track_"..tracktype]=1,
|
||||||
|
save_in_at_nodedb=1,
|
||||||
|
dig_immediate=2,
|
||||||
|
not_in_creative_inventory=1,
|
||||||
|
not_blocking_trains=1,
|
||||||
|
},
|
||||||
|
|
||||||
|
can_dig=function(pos)
|
||||||
|
return not advtrains.get_train_at_pos(pos)
|
||||||
|
end,
|
||||||
|
after_dig_node=function(pos)
|
||||||
|
advtrains.ndb.update(pos)
|
||||||
|
end,
|
||||||
|
after_place_node=function(pos)
|
||||||
|
advtrains.ndb.update(pos)
|
||||||
|
end,
|
||||||
|
at_nnpref = def.nodename_prefix,
|
||||||
|
at_suffix = suffix,
|
||||||
|
at_rotation = rotation,
|
||||||
|
at_rail_y = var.rail_y
|
||||||
|
}, def.common or {})
|
||||||
|
|
||||||
|
if preset.regtp then
|
||||||
|
ndef.drop = def.nodename_prefix.."_placer"
|
||||||
end
|
end
|
||||||
|
if preset.regsp and var.slope then
|
||||||
|
ndef.drop = def.nodename_prefix.."_slopeplacer"
|
||||||
|
end
|
||||||
|
|
||||||
|
--connections
|
||||||
|
ndef.at_conns = advtrains.rotate_conn_by(var.conns, (rotid-1)*preset.regstep)
|
||||||
|
|
||||||
|
if var.switchalt and var.switchst then
|
||||||
|
local switchfunc=function(pos, node, newstate)
|
||||||
|
if newstate~=var.switchst then
|
||||||
|
advtrains.ndb.swap_node(pos, {name=def.nodename_prefix.."_"..var.switchalt..rotation, param2=node.param2})
|
||||||
|
advtrains.invalidate_all_paths(pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
ndef.on_rightclick = function(pos, node, player)
|
||||||
|
if minetest.check_player_privs(player:get_player_name(), {train_operator=true}) then
|
||||||
|
switchfunc(pos, node)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if var.switchmc then
|
||||||
|
ndef.mesecons = {effector = {
|
||||||
|
["action_"..var.switchmc] = switchfunc,
|
||||||
|
rules=advtrains.meseconrules
|
||||||
|
}}
|
||||||
|
end
|
||||||
|
ndef.luaautomation = {
|
||||||
|
getstate = var.switchst,
|
||||||
|
setstate = switchfunc,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
local adef={}
|
local adef={}
|
||||||
if def.get_additional_definiton then
|
if def.get_additional_definiton then
|
||||||
adef=def.get_additional_definiton(def, preset, suffix, rotation)
|
adef=def.get_additional_definiton(def, preset, suffix, rotation)
|
||||||
end
|
end
|
||||||
|
ndef = advtrains.merge_tables(ndef, adef)
|
||||||
|
|
||||||
minetest.register_node(":"..def.nodename_prefix.."_"..suffix..rotation, advtrains.merge_tables(
|
minetest.register_node(":"..def.nodename_prefix.."_"..suffix..rotation, ndef)
|
||||||
common_def,
|
|
||||||
make_overdef(
|
|
||||||
suffix, rotation,
|
|
||||||
cycle_conns(conns, rotid),
|
|
||||||
rcswitchfunc, mesecontbl, luaautomation, preset.increativeinv[suffix], preset.slopenodes[suffix]
|
|
||||||
),
|
|
||||||
adef
|
|
||||||
)
|
|
||||||
)
|
|
||||||
--trackplacer
|
--trackplacer
|
||||||
if preset.regtp then
|
if preset.regtp then
|
||||||
if preset.trackplacer[suffix] then
|
local tpconns = {conn1=ndef.at_conns[1].c, conn2=ndef.at_conns[2].c}
|
||||||
advtrains.trackplacer.add_double_conn(def.nodename_prefix, suffix, rotation, cycle_conns(conns, rotid))
|
if var.tpdouble then
|
||||||
|
advtrains.trackplacer.add_double_conn(def.nodename_prefix, suffix, rotation, tpconns)
|
||||||
end
|
end
|
||||||
if preset.tpsingle[suffix] then
|
if var.tpsingle then
|
||||||
advtrains.trackplacer.add_single_conn(def.nodename_prefix, suffix, rotation, cycle_conns(conns, rotid))
|
advtrains.trackplacer.add_single_conn(def.nodename_prefix, suffix, rotation, tpconns)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
advtrains.trackplacer.add_worked(def.nodename_prefix, suffix, rotation, preset.trackworker[suffix])
|
advtrains.trackplacer.add_worked(def.nodename_prefix, suffix, rotation, var.trackworker)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
advtrains.all_tracktypes[tracktype]=true
|
advtrains.all_tracktypes[tracktype]=true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function advtrains.is_track_and_drives_on(nodename, drives_on_p)
|
function advtrains.is_track_and_drives_on(nodename, drives_on_p)
|
||||||
local drives_on = drives_on_p
|
local drives_on = drives_on_p
|
||||||
if not drives_on then drives_on = advtrains.all_tracktypes end
|
if not drives_on then drives_on = advtrains.all_tracktypes end
|
||||||
|
@ -430,7 +372,7 @@ end
|
||||||
|
|
||||||
function advtrains.get_track_connections(name, param2)
|
function advtrains.get_track_connections(name, param2)
|
||||||
local nodedef=minetest.registered_nodes[name]
|
local nodedef=minetest.registered_nodes[name]
|
||||||
if not nodedef then atprint(" get_track_connections couldn't find nodedef for nodename "..(name or "nil")) return 0, 8, 0, 0, 0 end
|
if not nodedef then atprint(" get_track_connections couldn't find nodedef for nodename "..(name or "nil")) return nil end
|
||||||
local noderot=param2
|
local noderot=param2
|
||||||
if not param2 then noderot=0 end
|
if not param2 then noderot=0 end
|
||||||
if noderot > 3 then atprint(" get_track_connections: rail has invaild param2 of "..noderot) noderot=0 end
|
if noderot > 3 then atprint(" get_track_connections: rail has invaild param2 of "..noderot) noderot=0 end
|
||||||
|
@ -442,7 +384,7 @@ function advtrains.get_track_connections(name, param2)
|
||||||
tracktype=tt
|
tracktype=tt
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return (nodedef.connect1 + 4 * noderot)%16, (nodedef.connect2 + 4 * noderot)%16, nodedef.rely1 or 0, nodedef.rely2 or 0, nodedef.railheight or 0, tracktype
|
return advtrains.rotate_conn_by(nodedef.at_conns, noderot*AT_CMAX/4), (nodedef.at_rail_y or 0), tracktype
|
||||||
end
|
end
|
||||||
|
|
||||||
--detector code
|
--detector code
|
||||||
|
|
|
@ -428,63 +428,6 @@ function advtrains.train_step_a(id, train, dtime)
|
||||||
end
|
end
|
||||||
end
|
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
|
|
||||||
local gen_back= - train.trainlen - path_pregen
|
|
||||||
if regular then
|
|
||||||
gen_front=math.max(train.index, train.detector_old_index) + path_pregen
|
|
||||||
gen_back=math.min(train.end_index, train.detector_old_end_index) - path_pregen
|
|
||||||
end
|
|
||||||
|
|
||||||
local maxn=train.path_extent_max or 0
|
|
||||||
while maxn < gen_front do--pregenerate
|
|
||||||
local conway
|
|
||||||
if train.max_index_on_track == maxn then
|
|
||||||
--atprint("maxn conway for ",maxn,train.path[maxn],maxn-1,train.path[maxn-1])
|
|
||||||
conway=advtrains.conway(train.path[maxn], train.path[maxn-1], train.drives_on)
|
|
||||||
end
|
|
||||||
if conway then
|
|
||||||
train.path[maxn+1]=conway
|
|
||||||
train.max_index_on_track=maxn+1
|
|
||||||
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 ",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
|
|
||||||
local conway
|
|
||||||
if train.min_index_on_track == minn then
|
|
||||||
--atprint("minn conway for ",minn,train.path[minn],minn+1,train.path[minn+1])
|
|
||||||
conway=advtrains.conway(train.path[minn], train.path[minn+1], train.drives_on)
|
|
||||||
end
|
|
||||||
if conway then
|
|
||||||
train.path[minn-1]=conway
|
|
||||||
train.min_index_on_track=minn-1
|
|
||||||
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 ",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)
|
function advtrains.train_step_b(id, train, dtime)
|
||||||
|
|
||||||
|
|
|
@ -931,8 +931,13 @@ function advtrains.register_wagon(sysname_p, prototype, desc, inv_img)
|
||||||
minetest.record_protection_violation(pointed_thing.under, placer:get_player_name())
|
minetest.record_protection_violation(pointed_thing.under, placer:get_player_name())
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local conn1=advtrains.get_track_connections(node.name, node.param2)
|
local tconns=advtrains.get_track_connections(node.name, node.param2)
|
||||||
local id=advtrains.create_new_train_at(pointed_thing.under, advtrains.dirCoordSet(pointed_thing.under, conn1))
|
local yaw = placer:get_look_horizontal() + (math.pi/2)
|
||||||
|
local plconnid = advtrains.yawToClosestConn(yaw, tconns)
|
||||||
|
|
||||||
|
local prevpos = advtrains.get_adjacent_rail(pointed_thing.under, tconns, plconnid, prototype.drives_on)
|
||||||
|
if not prevpos then return end
|
||||||
|
local id=advtrains.create_new_train_at(pointed_thing.under, prevpos)
|
||||||
|
|
||||||
local ob=minetest.add_entity(pointed_thing.under, sysname)
|
local ob=minetest.add_entity(pointed_thing.under, sysname)
|
||||||
if not ob then
|
if not ob then
|
||||||
|
|
|
@ -107,8 +107,8 @@ advtrains.register_tracks("default", {
|
||||||
|
|
||||||
--set arrowconn (for ATC)
|
--set arrowconn (for ATC)
|
||||||
local ph=minetest.pos_to_string(pos)
|
local ph=minetest.pos_to_string(pos)
|
||||||
local _, conn1=advtrains.get_rail_info_at(pos, advtrains.all_tracktypes)
|
local _, conns=advtrains.get_rail_info_at(pos, advtrains.all_tracktypes)
|
||||||
atlatc.active.nodes[ph].arrowconn=conn1
|
atlatc.active.nodes[ph].arrowconn=conns[1].c
|
||||||
end,
|
end,
|
||||||
|
|
||||||
advtrains = {
|
advtrains = {
|
||||||
|
|
|
@ -128,8 +128,14 @@ minetest.register_craftitem(":advtrains:subway_train", {
|
||||||
minetest.record_protection_violation(pointed_thing.under, placer:get_player_name())
|
minetest.record_protection_violation(pointed_thing.under, placer:get_player_name())
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local conn1=advtrains.get_track_connections(node.name, node.param2)
|
|
||||||
local id=advtrains.create_new_train_at(pointed_thing.under, advtrains.dirCoordSet(pointed_thing.under, conn1))
|
local tconns=advtrains.get_track_connections(node.name, node.param2)
|
||||||
|
local yaw = placer:get_look_horizontal() + (math.pi/2)
|
||||||
|
local plconnid = advtrains.yawToClosestConn(yaw, tconns)
|
||||||
|
|
||||||
|
local prevpos = advtrains.get_adjacent_rail(pointed_thing.under, tconns, plconnid, prototype.drives_on)
|
||||||
|
if not prevpos then return end
|
||||||
|
local id=advtrains.create_new_train_at(pointed_thing.under, prevpos)
|
||||||
|
|
||||||
for i=1,3 do
|
for i=1,3 do
|
||||||
local ob=minetest.add_entity(pointed_thing.under, "advtrains:subway_wagon")
|
local ob=minetest.add_entity(pointed_thing.under, "advtrains:subway_wagon")
|
||||||
|
|
Loading…
Reference in New Issue