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
orwell96 2017-11-22 20:46:36 +01:00
parent ce73643b10
commit 409e2125c9
3 changed files with 112 additions and 35 deletions

View File

@ -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

View File

@ -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

View File

@ -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)