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