Make trackplacer align rails by any tracks, not just by tracks with the same nnpref
This finally fixes the need to rotate atc rails and bumpers. Also prefers rotation that is closer to the player's look dir (placed bumpers will face the player)master
parent
ce73643b10
commit
409e2125c9
|
@ -151,26 +151,58 @@ function advtrains.yawToDirection(yaw, conn1, conn2)
|
||||||
if not conn1 or not conn2 then
|
if not conn1 or not conn2 then
|
||||||
error("given nil to yawToDirection: conn1="..(conn1 or "nil").." conn2="..(conn1 or "nil"))
|
error("given nil to yawToDirection: conn1="..(conn1 or "nil").." conn2="..(conn1 or "nil"))
|
||||||
end
|
end
|
||||||
local yaw1=math.pi*(conn1/4)
|
local yaw1=math.pi*(conn1/8)
|
||||||
local yaw2=math.pi*(conn2/4)
|
local yaw2=math.pi*(conn2/8)
|
||||||
if advtrains.minAngleDiffRad(yaw, yaw1)<advtrains.minAngleDiffRad(yaw, yaw2) then--change to > if weird behavior
|
local adiff1 = advtrains.minAngleDiffRad(yaw, yaw1)
|
||||||
|
local adiff2 = advtrains.minAngleDiffRad(yaw, yaw2)
|
||||||
|
|
||||||
|
if math.abs(adiff2)<math.abs(adiff1) then
|
||||||
return conn2
|
return conn2
|
||||||
else
|
else
|
||||||
return conn1
|
return conn1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function advtrains.yawToAnyDir(yaw)
|
||||||
|
local min_conn, min_diff=0, 10
|
||||||
|
for conn, vec in pairs(advtrains.dir_trans_tbl) do
|
||||||
|
local uvec = vector.normalize(advtrains.dirToCoord(conn))
|
||||||
|
local yaw1 = math.atan2(uvec.z, uvec.x)
|
||||||
|
local diff = advtrains.minAngleDiffRad(yaw, yaw1)
|
||||||
|
if diff < min_diff then
|
||||||
|
min_conn = conn
|
||||||
|
min_diff = diff
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return min_conn
|
||||||
|
end
|
||||||
|
|
||||||
function advtrains.minAngleDiffRad(r1, r2)
|
function advtrains.minAngleDiffRad(r1, r2)
|
||||||
|
local pi, pi2 = math.pi, 2*math.pi
|
||||||
|
while r1>pi2 do
|
||||||
|
r1=r1-pi2
|
||||||
|
end
|
||||||
|
while r1<0 do
|
||||||
|
r1=r1+pi2
|
||||||
|
end
|
||||||
|
while r2>pi2 do
|
||||||
|
r2=r2-pi2
|
||||||
|
end
|
||||||
|
while r1<0 do
|
||||||
|
r2=r2+pi2
|
||||||
|
end
|
||||||
local try1=r2-r1
|
local try1=r2-r1
|
||||||
local try2=(r2+2*math.pi)-r1
|
local try2=r2+pi2-r1
|
||||||
local try3=r2-(r1+2*math.pi)
|
local try3=r2-pi2-r1
|
||||||
if math.min(math.abs(try1), math.abs(try2), math.abs(try3))==math.abs(try1) then
|
|
||||||
|
local minabs = math.min(math.abs(try1), math.abs(try2), math.abs(try3))
|
||||||
|
if minabs==math.abs(try1) then
|
||||||
return try1
|
return try1
|
||||||
end
|
end
|
||||||
if math.min(math.abs(try1), math.abs(try2), math.abs(try3))==math.abs(try2) then
|
if minabs==math.abs(try2) then
|
||||||
return try2
|
return try2
|
||||||
end
|
end
|
||||||
if math.min(math.abs(try1), math.abs(try2), math.abs(try3))==math.abs(try3) then
|
if minabs==math.abs(try3) then
|
||||||
return try3
|
return try3
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,12 +11,14 @@ function tp.register_tracktype(nnprefix, n_suffix)
|
||||||
tp.tracks[nnprefix]={
|
tp.tracks[nnprefix]={
|
||||||
default=n_suffix,
|
default=n_suffix,
|
||||||
single_conn={},
|
single_conn={},
|
||||||
|
single_conn_1={},
|
||||||
|
single_conn_2={},
|
||||||
double_conn={},
|
double_conn={},
|
||||||
--keys:conn1_conn2 (example:1_4)
|
--keys:conn1_conn2 (example:1_4)
|
||||||
--values:{name=x, param2=x}
|
--values:{name=x, param2=x}
|
||||||
twcycle={},
|
twcycle={},
|
||||||
twrotate={},--indexed by suffix, list, tells order of rotations
|
twrotate={},--indexed by suffix, list, tells order of rotations
|
||||||
modify={}
|
modify={},
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
function tp.add_double_conn(nnprefix, suffix, rotation, conns)
|
function tp.add_double_conn(nnprefix, suffix, rotation, conns)
|
||||||
|
@ -32,10 +34,13 @@ function tp.add_single_conn(nnprefix, suffix, rotation, conns)
|
||||||
for i=0,3 do
|
for i=0,3 do
|
||||||
tp.tracks[nnprefix].single_conn[((conns.conn1+4*i)%16)]={name=nodename, param2=i}
|
tp.tracks[nnprefix].single_conn[((conns.conn1+4*i)%16)]={name=nodename, param2=i}
|
||||||
tp.tracks[nnprefix].single_conn[((conns.conn2+4*i)%16)]={name=nodename, param2=i}
|
tp.tracks[nnprefix].single_conn[((conns.conn2+4*i)%16)]={name=nodename, param2=i}
|
||||||
|
tp.tracks[nnprefix].single_conn_1[((conns.conn1+4*i)%16)]={name=nodename, param2=i}
|
||||||
|
tp.tracks[nnprefix].single_conn_2[((conns.conn2+4*i)%16)]={name=nodename, param2=i}
|
||||||
end
|
end
|
||||||
tp.tracks[nnprefix].modify[nodename]=true
|
tp.tracks[nnprefix].modify[nodename]=true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function tp.add_worked(nnprefix, suffix, rotation, cycle_follows)
|
function tp.add_worked(nnprefix, suffix, rotation, cycle_follows)
|
||||||
tp.tracks[nnprefix].twcycle[suffix]=cycle_follows
|
tp.tracks[nnprefix].twcycle[suffix]=cycle_follows
|
||||||
if not tp.tracks[nnprefix].twrotate[suffix] then tp.tracks[nnprefix].twrotate[suffix]={} end
|
if not tp.tracks[nnprefix].twrotate[suffix] then tp.tracks[nnprefix].twrotate[suffix]={} end
|
||||||
|
@ -59,6 +64,7 @@ end
|
||||||
3. there's no rail around
|
3. there's no rail around
|
||||||
-> set straight
|
-> set straight
|
||||||
]]
|
]]
|
||||||
|
|
||||||
function tp.find_already_connected(pos)--TODO vertical calculations(check node below)
|
function tp.find_already_connected(pos)--TODO vertical calculations(check node below)
|
||||||
local function istrackandbc(pos, conn)
|
local function istrackandbc(pos, conn)
|
||||||
local cnode=minetest.get_node(advtrains.dirCoordSet(pos, conn))
|
local cnode=minetest.get_node(advtrains.dirCoordSet(pos, conn))
|
||||||
|
@ -71,21 +77,24 @@ function tp.find_already_connected(pos)--TODO vertical calculations(check node b
|
||||||
end
|
end
|
||||||
local dnode=minetest.get_node(pos)
|
local dnode=minetest.get_node(pos)
|
||||||
local dconn1, dconn2=advtrains.get_track_connections(dnode.name, dnode.param2)
|
local dconn1, dconn2=advtrains.get_track_connections(dnode.name, dnode.param2)
|
||||||
local t={[true]="true", [false]="false"}
|
|
||||||
if istrackandbc(pos, dconn1) and istrackandbc(pos, dconn2) then return dconn1, dconn2
|
if istrackandbc(pos, dconn1) and istrackandbc(pos, dconn2) then return dconn1, dconn2
|
||||||
elseif istrackandbc(pos, dconn1) then return dconn1
|
elseif istrackandbc(pos, dconn1) then return dconn1
|
||||||
elseif istrackandbc(pos, dconn2) then return dconn2
|
elseif istrackandbc(pos, dconn2) then return dconn2
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
function tp.rail_and_can_be_bent(originpos, conn, nnpref)
|
function tp.rail_and_can_be_bent(originpos, conn)
|
||||||
local pos=advtrains.dirCoordSet(originpos, conn)
|
local pos=advtrains.dirCoordSet(originpos, conn)
|
||||||
local newdir=(conn+8)%16
|
local newdir=(conn+8)%16
|
||||||
local node=minetest.get_node(pos)
|
local node=minetest.get_node(pos)
|
||||||
local tr=tp.tracks[nnpref]
|
|
||||||
if not advtrains.is_track_and_drives_on(node.name, advtrains.all_tracktypes) then
|
if not advtrains.is_track_and_drives_on(node.name, advtrains.all_tracktypes) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
local ndef=minetest.registered_nodes[node.name]
|
||||||
|
local nnpref = ndef and ndef.nnpref
|
||||||
|
if not nnpref then return false end
|
||||||
|
local tr=tp.tracks[nnpref]
|
||||||
|
if not tr then return false end
|
||||||
--rail at other end?
|
--rail at other end?
|
||||||
local adj1, adj2=tp.find_already_connected(pos)
|
local adj1, adj2=tp.find_already_connected(pos)
|
||||||
if adj1 and adj2 then
|
if adj1 and adj2 then
|
||||||
|
@ -102,11 +111,15 @@ function tp.rail_and_can_be_bent(originpos, conn, nnpref)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function tp.bend_rail(originpos, conn, nnpref)
|
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=(conn+8)%16
|
||||||
local node=minetest.get_node(pos)
|
local node=minetest.get_node(pos)
|
||||||
|
local ndef=minetest.registered_nodes[node.name]
|
||||||
|
local nnpref = ndef and ndef.nnpref
|
||||||
|
if not nnpref then return false end
|
||||||
local tr=tp.tracks[nnpref]
|
local tr=tp.tracks[nnpref]
|
||||||
|
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 conn1, conn2=advtrains.get_track_connections(node.name, node.param2)
|
||||||
if newdir==conn1 or newdir==conn2 then
|
if newdir==conn1 or newdir==conn2 then
|
||||||
|
@ -130,7 +143,7 @@ function tp.bend_rail(originpos, conn, nnpref)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function tp.placetrack(pos, nnpref, placer, itemstack, pointed_thing)
|
function tp.placetrack(pos, nnpref, placer, itemstack, pointed_thing, yaw)
|
||||||
--1. find all rails that are likely to be connected
|
--1. find all rails that are likely to be connected
|
||||||
local tr=tp.tracks[nnpref]
|
local tr=tp.tracks[nnpref]
|
||||||
local p_rails={}
|
local p_rails={}
|
||||||
|
@ -139,20 +152,9 @@ function tp.placetrack(pos, nnpref, placer, itemstack, pointed_thing)
|
||||||
p_rails[#p_rails+1]=i
|
p_rails[#p_rails+1]=i
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if #p_rails==0 then
|
-- try double_conn
|
||||||
minetest.set_node(pos, {name=nnpref.."_"..tr.default})
|
if #p_rails > 1 then
|
||||||
if minetest.registered_nodes[nnpref.."_"..tr.default] and minetest.registered_nodes[nnpref.."_"..tr.default].after_place_node then
|
|
||||||
minetest.registered_nodes[nnpref.."_"..tr.default].after_place_node(pos, placer, itemstack, pointed_thing)
|
|
||||||
end
|
|
||||||
elseif #p_rails==1 then
|
|
||||||
tp.bend_rail(pos, p_rails[1], nnpref)
|
|
||||||
advtrains.ndb.swap_node(pos, tr.single_conn[p_rails[1]])
|
|
||||||
local nname=tr.single_conn[p_rails[1]].name
|
|
||||||
if minetest.registered_nodes[nname] and minetest.registered_nodes[nname].after_place_node then
|
|
||||||
minetest.registered_nodes[nname].after_place_node(pos, placer, itemstack, pointed_thing)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
--iterate subsets
|
--iterate subsets
|
||||||
for k1, conn1 in ipairs(p_rails) do
|
for k1, conn1 in ipairs(p_rails) do
|
||||||
for k2, conn2 in ipairs(p_rails) do
|
for k2, conn2 in ipairs(p_rails) do
|
||||||
|
@ -170,14 +172,43 @@ function tp.placetrack(pos, nnpref, placer, itemstack, pointed_thing)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--not found
|
end
|
||||||
tp.bend_rail(pos, p_rails[1], nnpref)
|
-- try single_conn
|
||||||
advtrains.ndb.swap_node(pos, tr.single_conn[p_rails[1]])
|
if #p_rails > 0 then
|
||||||
local nname=tr.single_conn[p_rails[1]].name
|
for ix, p_rail in ipairs(p_rails) do
|
||||||
if minetest.registered_nodes[nname] and minetest.registered_nodes[nname].after_place_node then
|
local sconn1 = tr.single_conn_1
|
||||||
minetest.registered_nodes[nname].after_place_node(pos, placer, itemstack, pointed_thing)
|
local sconn2 = tr.single_conn_2
|
||||||
|
if not (advtrains.yawToDirection(yaw, p_rail, (p_rail+8)%16) == p_rail) then
|
||||||
|
sconn1 = tr.single_conn_2
|
||||||
|
sconn2 = tr.single_conn_1
|
||||||
|
end
|
||||||
|
if sconn1[p_rail] then
|
||||||
|
local using = sconn1[p_rail]
|
||||||
|
tp.bend_rail(pos, p_rail, nnpref)
|
||||||
|
advtrains.ndb.swap_node(pos, using)
|
||||||
|
local nname=using.name
|
||||||
|
if minetest.registered_nodes[nname] and minetest.registered_nodes[nname].after_place_node then
|
||||||
|
minetest.registered_nodes[nname].after_place_node(pos, placer, itemstack, pointed_thing)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
|
if sconn2[p_rail] then
|
||||||
|
local using = sconn2[p_rail]
|
||||||
|
tp.bend_rail(pos, p_rail, nnpref)
|
||||||
|
advtrains.ndb.swap_node(pos, using)
|
||||||
|
local nname=using.name
|
||||||
|
if minetest.registered_nodes[nname] and minetest.registered_nodes[nname].after_place_node then
|
||||||
|
minetest.registered_nodes[nname].after_place_node(pos, placer, itemstack, pointed_thing)
|
||||||
|
end
|
||||||
|
return
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
--use default
|
||||||
|
minetest.set_node(pos, {name=nnpref.."_"..tr.default})
|
||||||
|
if minetest.registered_nodes[nnpref.."_"..tr.default] and minetest.registered_nodes[nnpref.."_"..tr.default].after_place_node then
|
||||||
|
minetest.registered_nodes[nnpref.."_"..tr.default].after_place_node(pos, placer, itemstack, pointed_thing)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,7 +234,8 @@ function tp.register_track_placer(nnprefix, imgprefix, dispname)
|
||||||
if minetest.registered_nodes[minetest.get_node(pos).name] and minetest.registered_nodes[minetest.get_node(pos).name].buildable_to
|
if minetest.registered_nodes[minetest.get_node(pos).name] and minetest.registered_nodes[minetest.get_node(pos).name].buildable_to
|
||||||
and minetest.registered_nodes[minetest.get_node(upos).name] and minetest.registered_nodes[minetest.get_node(upos).name].walkable then
|
and minetest.registered_nodes[minetest.get_node(upos).name] and minetest.registered_nodes[minetest.get_node(upos).name].walkable then
|
||||||
-- minetest.chat_send_all(nnprefix)
|
-- minetest.chat_send_all(nnprefix)
|
||||||
tp.placetrack(pos, nnprefix, placer, itemstack, pointed_thing)
|
local yaw = placer:get_look_horizontal() + (math.pi/2)
|
||||||
|
tp.placetrack(pos, nnprefix, placer, itemstack, pointed_thing, yaw)
|
||||||
if not minetest.settings:get_bool("creative_mode") then
|
if not minetest.settings:get_bool("creative_mode") then
|
||||||
itemstack:take_item()
|
itemstack:take_item()
|
||||||
end
|
end
|
||||||
|
|
|
@ -152,6 +152,12 @@ advtrains.ap.t_30deg_straightonly={
|
||||||
trackworker={
|
trackworker={
|
||||||
["st"]="st",
|
["st"]="st",
|
||||||
},
|
},
|
||||||
|
trackplacer={
|
||||||
|
st=true,
|
||||||
|
},
|
||||||
|
tpsingle={
|
||||||
|
st=true,
|
||||||
|
},
|
||||||
slopenodes={},
|
slopenodes={},
|
||||||
rotation={"", "_30", "_45", "_60"},
|
rotation={"", "_30", "_45", "_60"},
|
||||||
increativeinv={"st"},
|
increativeinv={"st"},
|
||||||
|
@ -177,6 +183,12 @@ advtrains.ap.t_30deg_straightonly_noplacer={
|
||||||
trackworker={
|
trackworker={
|
||||||
["st"]="st",
|
["st"]="st",
|
||||||
},
|
},
|
||||||
|
trackplacer={
|
||||||
|
st=true,
|
||||||
|
},
|
||||||
|
tpsingle={
|
||||||
|
st=true,
|
||||||
|
},
|
||||||
slopenodes={},
|
slopenodes={},
|
||||||
rotation={"", "_30", "_45", "_60"},
|
rotation={"", "_30", "_45", "_60"},
|
||||||
increativeinv={"st"},
|
increativeinv={"st"},
|
||||||
|
@ -346,6 +358,7 @@ function advtrains.register_tracks(tracktype, def, preset)
|
||||||
after_place_node=function(pos)
|
after_place_node=function(pos)
|
||||||
advtrains.ndb.update(pos)
|
advtrains.ndb.update(pos)
|
||||||
end,
|
end,
|
||||||
|
nnpref = def.nodename_prefix,
|
||||||
}, def.common or {})
|
}, def.common or {})
|
||||||
--make trackplacer base def
|
--make trackplacer base def
|
||||||
advtrains.trackplacer.register_tracktype(def.nodename_prefix, preset.tpdefault)
|
advtrains.trackplacer.register_tracktype(def.nodename_prefix, preset.tpdefault)
|
||||||
|
|
Loading…
Reference in New Issue