200 lines
8.7 KiB
Lua
200 lines
8.7 KiB
Lua
--trackplacer.lua
|
|
--holds code for the track-placing system. the default 'track' item will be a craftitem that places rails as needed. this will neither place or change switches nor place vertical rails.
|
|
|
|
--keys:conn1_conn2 (example:1_4)
|
|
--values:{name=x, param2=x}
|
|
advtrains.trackplacer_dir_to_node_mapping={}
|
|
--keys are nodenames!
|
|
advtrains.trackplacer_modified_rails={}
|
|
|
|
function advtrains.trackplacer_register(nodename, conn1, conn2)
|
|
for i=0,3 do
|
|
advtrains.trackplacer_dir_to_node_mapping[((conn1+2*i)%8).."_"..((conn2+2*i)%8)]={name=nodename, param2=i}
|
|
advtrains.trackplacer_dir_to_node_mapping[((conn2+2*i)%8).."_"..((conn1+2*i)%8)]={name=nodename, param2=i}
|
|
end
|
|
advtrains.trackplacer_modified_rails[nodename]=true
|
|
end
|
|
function advtrains.find_adjacent_tracks(pos)--TODO vertical calculations(check node below)
|
|
local conn1=0
|
|
while conn1<8 and not advtrains.is_track_and_drives_on(minetest.get_node(advtrains.dirCoordSet(pos, conn1)).name, advtrains.all_tracktypes) do
|
|
conn1=conn1+1
|
|
end
|
|
if conn1>=8 then
|
|
return nil, nil
|
|
end
|
|
local conn2=0
|
|
while conn2<8 and not advtrains.is_track_and_drives_on(minetest.get_node(advtrains.dirCoordSet(pos, conn2)).name, advtrains.all_tracktypes) or conn2==conn1 do
|
|
conn2=conn2+1
|
|
end
|
|
if conn2>=8 then
|
|
return conn1, nil
|
|
end
|
|
return conn1, conn2
|
|
end
|
|
function advtrains.placetrack(pos)
|
|
local conn1, conn2=advtrains.find_adjacent_tracks(pos)
|
|
|
|
if not conn1 and not conn2 then
|
|
minetest.set_node(pos, {name="advtrains:track_st"})
|
|
elseif conn1 and not conn2 then
|
|
local node1=minetest.get_node(advtrains.dirCoordSet(pos, conn1))
|
|
local node1_conn1, node1_conn2=advtrains.get_track_connections(node1.name, node1.param2)
|
|
local node1_backconnects=(conn1+4)%8==node1_conn1 or (conn1+4)%8==node1_conn2
|
|
|
|
if not node1_backconnects and advtrains.trackplacer_modified_rails[node1.name] then
|
|
--check if this rail has a dangling connection
|
|
--TODO possible problems on |- situation
|
|
if not advtrains.is_track_and_drives_on(minetest.get_node(advtrains.dirCoordSet(pos, node1_conn1)).name, advtrains.all_tracktypes) then
|
|
if advtrains.trackplacer_dir_to_node_mapping[node1_conn1.."_"..((conn1+4)%8)] then
|
|
minetest.set_node(advtrains.dirCoordSet(pos, conn1), advtrains.trackplacer_dir_to_node_mapping[node1_conn1.."_"..((conn1+4)%8)])
|
|
end
|
|
elseif not advtrains.is_track_and_drives_on(minetest.get_node(advtrains.dirCoordSet(pos, node1_conn2)).name, advtrains.all_tracktypes) then
|
|
if advtrains.trackplacer_dir_to_node_mapping[node1_conn2.."_"..((conn1+4)%8)] then
|
|
minetest.set_node(advtrains.dirCoordSet(pos, conn1), advtrains.trackplacer_dir_to_node_mapping[node1_conn2.."_"..((conn1+4)%8)])
|
|
end
|
|
end
|
|
end
|
|
--second end will be free. place standard rail
|
|
if conn1%2==1 then
|
|
minetest.set_node(pos, {name="advtrains:track_st_45", param2=(conn1-1)/2})
|
|
else
|
|
minetest.set_node(pos, {name="advtrains:track_st", param2=conn1/2})
|
|
end
|
|
elseif conn1 and conn2 then
|
|
if not advtrains.trackplacer_dir_to_node_mapping[conn1.."_"..conn2] then
|
|
minetest.set_node(pos, {name="advtrains:track_st"})
|
|
return
|
|
end
|
|
local node1=minetest.get_node(advtrains.dirCoordSet(pos, conn1))
|
|
local node1_conn1, node1_conn2=advtrains.get_track_connections(node1.name, node1.param2)
|
|
local node1_backconnects=(conn1+4)%8==node1_conn1 or (conn1+4)%8==node1_conn2
|
|
if not node1_backconnects and advtrains.trackplacer_modified_rails[node1.name] then
|
|
--check if this rail has a dangling connection
|
|
--TODO possible problems on |- situation
|
|
if not advtrains.is_track_and_drives_on(minetest.get_node(advtrains.dirCoordSet(pos, node1_conn1)).name, advtrains.all_tracktypes) then
|
|
if advtrains.trackplacer_dir_to_node_mapping[node1_conn1.."_"..((conn1+4)%8)] then
|
|
minetest.set_node(advtrains.dirCoordSet(pos, conn1), advtrains.trackplacer_dir_to_node_mapping[node1_conn1.."_"..((conn1+4)%8)])
|
|
end
|
|
elseif not advtrains.is_track_and_drives_on(minetest.get_node(advtrains.dirCoordSet(pos, node1_conn2)).name, advtrains.all_tracktypes) then
|
|
if advtrains.trackplacer_dir_to_node_mapping[node1_conn2.."_"..((conn1+4)%8)] then
|
|
minetest.set_node(advtrains.dirCoordSet(pos, conn1), advtrains.trackplacer_dir_to_node_mapping[node1_conn2.."_"..((conn1+4)%8)])
|
|
end
|
|
end
|
|
end
|
|
|
|
local node2=minetest.get_node(advtrains.dirCoordSet(pos, conn2))
|
|
local node2_conn1, node2_conn2=advtrains.get_track_connections(node2.name, node2.param2)
|
|
local node2_backconnects=(conn2+4)%8==node2_conn1 or (conn2+4)%8==node2_conn2
|
|
if not node2_backconnects and advtrains.trackplacer_modified_rails[node2.name] then
|
|
--check if this rail has a dangling connection
|
|
--TODO possible problems on |- situation
|
|
if not advtrains.is_track_and_drives_on(minetest.get_node(advtrains.dirCoordSet(pos, node2_conn1)).name, advtrains.all_tracktypes) then
|
|
if advtrains.trackplacer_dir_to_node_mapping[node2_conn1.."_"..((conn2+4)%8)] then
|
|
minetest.set_node(advtrains.dirCoordSet(pos, conn2), advtrains.trackplacer_dir_to_node_mapping[node2_conn1.."_"..((conn2+4)%8)])
|
|
end
|
|
elseif not advtrains.is_track_and_drives_on(minetest.get_node(advtrains.dirCoordSet(pos, node2_conn2)).name, advtrains.all_tracktypes) then
|
|
if advtrains.trackplacer_dir_to_node_mapping[node2_conn2.."_"..((conn1+4)%8)] then
|
|
minetest.set_node(advtrains.dirCoordSet(pos, conn2), advtrains.trackplacer_dir_to_node_mapping[node2_conn2.."_"..((conn2+4)%8)])
|
|
end
|
|
end
|
|
end
|
|
minetest.set_node(pos, advtrains.trackplacer_dir_to_node_mapping[conn1.."_"..conn2])
|
|
end
|
|
end
|
|
|
|
|
|
advtrains.trackworker_cycle_nodes={
|
|
["swr_cr"]="st",
|
|
["swr_st"]="st",
|
|
["st"]="cr",
|
|
["cr"]="swl_st",
|
|
["swl_cr"]="swr_cr",
|
|
["swl_st"]="swr_st",
|
|
}
|
|
|
|
function advtrains.register_track_placer(nnprefix, imgprefix, dispname)
|
|
minetest.register_craftitem(nnprefix.."_placer",{
|
|
description = dispname,
|
|
inventory_image = imgprefix.."_placer.png",
|
|
wield_image = imgprefix.."_placer.png",
|
|
on_place = function(itemstack, placer, pointed_thing)
|
|
if pointed_thing.type=="node" then
|
|
local pos=pointed_thing.above
|
|
if minetest.registered_nodes[minetest.get_node(pos).name] and minetest.registered_nodes[minetest.get_node(pos).name].buildable_to then
|
|
advtrains.placetrack(pos, nnprefix)
|
|
itemstack:take_item()
|
|
end
|
|
end
|
|
return itemstack
|
|
end,
|
|
})
|
|
end
|
|
|
|
|
|
|
|
minetest.register_craftitem("advtrains:trackworker",{
|
|
description = "Track Worker Tool\n\nLeft-click: change rail type (straight/curve/switch)\nRight-click: rotate rail",
|
|
groups = {cracky=1}, -- key=name, value=rating; rating=1..3.
|
|
inventory_image = "advtrains_trackworker.png",
|
|
wield_image = "advtrains_trackworker.png",
|
|
stack_max = 1,
|
|
on_place = function(itemstack, placer, pointed_thing)
|
|
if pointed_thing.type=="node" then
|
|
local pos=pointed_thing.under
|
|
local node=minetest.get_node(pos)
|
|
|
|
if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
|
|
if advtrains.is_train_at_pos(pos) then return end
|
|
local nodeprefix, railtype=string.match(node.name, "^(.-)_(.+)$")
|
|
|
|
local basename=string.match(railtype, "^(.+)_45$")
|
|
if basename then
|
|
if not advtrains.trackworker_cycle_nodes[basename] then
|
|
print("[advtrains]rail not workable by trackworker")
|
|
return
|
|
end
|
|
minetest.set_node(pos, {name=nodeprefix.."_"..basename, param2=(node.param2+1)%4})
|
|
return
|
|
else
|
|
if not advtrains.trackworker_cycle_nodes[railtype] then
|
|
print("[advtrains]rail not workable by trackworker")
|
|
return
|
|
end
|
|
minetest.set_node(pos, {name=nodeprefix.."_"..railtype.."_45", param2=node.param2})
|
|
end
|
|
end
|
|
end,
|
|
on_use=function(itemstack, user, pointed_thing)
|
|
if pointed_thing.type=="node" then
|
|
local pos=pointed_thing.under
|
|
local node=minetest.get_node(pos)
|
|
|
|
if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
|
|
if advtrains.is_train_at_pos(pos) then return end
|
|
local nodeprefix, railtype=string.match(node.name, "^(.-)_(.+)$")
|
|
|
|
local basename=string.match(railtype, "^(.+)_45$")
|
|
if basename then
|
|
if not advtrains.trackworker_cycle_nodes[basename] then
|
|
print("[advtrains]trackworker does not know what to set here...")
|
|
return
|
|
end
|
|
print(advtrains.trackworker_cycle_nodes[basename].."_45")
|
|
minetest.set_node(pos, {name=nodeprefix.."_"..advtrains.trackworker_cycle_nodes[basename].."_45", param2=node.param2})
|
|
return
|
|
else
|
|
if not advtrains.trackworker_cycle_nodes[railtype] then
|
|
print("[advtrains]trackworker does not know what to set here...")
|
|
return
|
|
end
|
|
minetest.set_node(pos, {name=nodeprefix.."_"..advtrains.trackworker_cycle_nodes[railtype], param2=node.param2})
|
|
end
|
|
--invalidate trains
|
|
for k,v in pairs(advtrains.trains) do
|
|
v.restore_add_index=v.index-math.floor(v.index+0.5)
|
|
v.path=nil
|
|
v.index=nil
|
|
end
|
|
end
|
|
end,
|
|
}) |