diff options
-rw-r--r-- | advtrains/helpers.lua | 48 | ||||
-rw-r--r-- | advtrains/trackplacer.lua | 86 | ||||
-rw-r--r-- | advtrains/tracks.lua | 13 |
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)
|