aboutsummaryrefslogtreecommitdiff
path: root/advtrains
diff options
context:
space:
mode:
Diffstat (limited to 'advtrains')
-rw-r--r--advtrains/helpers.lua48
-rw-r--r--advtrains/trackplacer.lua86
-rw-r--r--advtrains/tracks.lua13
3 files changed, 112 insertions, 35 deletions
diff --git a/advtrains/helpers.lua b/advtrains/helpers.lua
index d7b977e..f2e969f 100644
--- a/advtrains/helpers.lua
+++ b/advtrains/helpers.lua
@@ -151,26 +151,58 @@ function advtrains.yawToDirection(yaw, conn1, conn2)
if not conn1 or not conn2 then
error("given nil to yawToDirection: conn1="..(conn1 or "nil").." conn2="..(conn1 or "nil"))
end
- local yaw1=math.pi*(conn1/4)
- local yaw2=math.pi*(conn2/4)
- if advtrains.minAngleDiffRad(yaw, yaw1)<advtrains.minAngleDiffRad(yaw, yaw2) then--change to > if weird behavior
+ local yaw1=math.pi*(conn1/8)
+ local yaw2=math.pi*(conn2/8)
+ local adiff1 = advtrains.minAngleDiffRad(yaw, yaw1)
+ local adiff2 = advtrains.minAngleDiffRad(yaw, yaw2)
+
+ if math.abs(adiff2)<math.abs(adiff1) then
return conn2
else
return conn1
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)
+ 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 try2=(r2+2*math.pi)-r1
- local try3=r2-(r1+2*math.pi)
- if math.min(math.abs(try1), math.abs(try2), math.abs(try3))==math.abs(try1) then
+ local try2=r2+pi2-r1
+ local try3=r2-pi2-r1
+
+ local minabs = math.min(math.abs(try1), math.abs(try2), math.abs(try3))
+ if minabs==math.abs(try1) then
return try1
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
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
end
end
diff --git a/advtrains/trackplacer.lua b/advtrains/trackplacer.lua
index 124e958..8c943c8 100644
--- a/advtrains/trackplacer.lua
+++ b/advtrains/trackplacer.lua
@@ -11,12 +11,14 @@ function tp.register_tracktype(nnprefix, n_suffix)
tp.tracks[nnprefix]={
default=n_suffix,
single_conn={},
+ single_conn_1={},
+ single_conn_2={},
double_conn={},
--keys:conn1_conn2 (example:1_4)
--values:{name=x, param2=x}
twcycle={},
twrotate={},--indexed by suffix, list, tells order of rotations
- modify={}
+ modify={},
}
end
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
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_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
tp.tracks[nnprefix].modify[nodename]=true
end
+
function tp.add_worked(nnprefix, suffix, rotation, cycle_follows)
tp.tracks[nnprefix].twcycle[suffix]=cycle_follows
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
-> set straight
]]
+
function tp.find_already_connected(pos)--TODO vertical calculations(check node below)
local function istrackandbc(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
local dnode=minetest.get_node(pos)
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
elseif istrackandbc(pos, dconn1) then return dconn1
elseif istrackandbc(pos, dconn2) then return dconn2
end
return nil
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 newdir=(conn+8)%16
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
return false
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?
local adj1, adj2=tp.find_already_connected(pos)
if adj1 and adj2 then
@@ -102,11 +111,15 @@ function tp.rail_and_can_be_bent(originpos, conn, nnpref)
return false
end
end
-function tp.bend_rail(originpos, conn, nnpref)
+function tp.bend_rail(originpos, conn)
local pos=advtrains.dirCoordSet(originpos, conn)
local newdir=(conn+8)%16
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]
+ if not tr then return false end
--is rail already connected? no need to bend.
local conn1, conn2=advtrains.get_track_connections(node.name, node.param2)
if newdir==conn1 or newdir==conn2 then
@@ -130,7 +143,7 @@ function tp.bend_rail(originpos, conn, nnpref)
return false
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
local tr=tp.tracks[nnpref]
local p_rails={}
@@ -139,20 +152,9 @@ function tp.placetrack(pos, nnpref, placer, itemstack, pointed_thing)
p_rails[#p_rails+1]=i
end
end
-
- if #p_rails==0 then
- 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
- 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
+
+ -- try double_conn
+ if #p_rails > 1 then
--iterate subsets
for k1, conn1 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
- --not found
- 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
+ -- try single_conn
+ if #p_rails > 0 then
+ for ix, p_rail in ipairs(p_rails) do
+ local sconn1 = tr.single_conn_1
+ 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
+ --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
@@ -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
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)
- 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
itemstack:take_item()
end
diff --git a/advtrains/tracks.lua b/advtrains/tracks.lua
index fdc8ae9..bfa95fe 100644
--- a/advtrains/tracks.lua
+++ b/advtrains/tracks.lua
@@ -152,6 +152,12 @@ advtrains.ap.t_30deg_straightonly={
trackworker={
["st"]="st",
},
+ trackplacer={
+ st=true,
+ },
+ tpsingle={
+ st=true,
+ },
slopenodes={},
rotation={"", "_30", "_45", "_60"},
increativeinv={"st"},
@@ -177,6 +183,12 @@ advtrains.ap.t_30deg_straightonly_noplacer={
trackworker={
["st"]="st",
},
+ trackplacer={
+ st=true,
+ },
+ tpsingle={
+ st=true,
+ },
slopenodes={},
rotation={"", "_30", "_45", "_60"},
increativeinv={"st"},
@@ -346,6 +358,7 @@ function advtrains.register_tracks(tracktype, def, preset)
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)