Begin major rework of track registration system
This commit is contained in:
parent
7ca8ac8d00
commit
950d6f640c
|
@ -18,8 +18,6 @@ advtrains.register_wagon(name, prototype, description, inventory_image)
|
|||
# Wagon prototype properties
|
||||
{
|
||||
... all regular luaentity properties (mesh, textures, collisionbox a.s.o)...
|
||||
drives_on = {default=true},
|
||||
^- used to define the tracktypes (see below) that wagon can drive on. The tracktype identifiers are given as keys, similar to privileges)
|
||||
max_speed = 10,
|
||||
^- optional, default 10: defines the maximum speed this wagon can drive. The maximum speed of a train is determined by the wagon with the lowest max_speed value.
|
||||
seats = {
|
||||
|
|
|
@ -21,7 +21,7 @@ minetest.register_tool("advtrains:copytool", {
|
|||
local node=minetest.get_node_or_nil(pointed_thing.under)
|
||||
if not node then atprint("[advtrains]Ignore at placer position") return itemstack end
|
||||
local nodename=node.name
|
||||
if(not advtrains.is_track_and_drives_on(nodename, {default=true})) then
|
||||
if(not advtrains.is_track(nodename)) then
|
||||
atprint("no track here, not placing.")
|
||||
return itemstack
|
||||
end
|
||||
|
|
|
@ -294,7 +294,7 @@ end
|
|||
-- Going from the rail at pos (does not need to be rounded) along connection with id conn_idx, if there is a matching rail, return it and the matching connid
|
||||
-- returns: <adjacent pos>, <conn index of adjacent>, <my conn index>, <railheight of adjacent>
|
||||
-- parameter this_conns_p is connection table of this rail and is optional, is determined by get_rail_info_at if not provided.
|
||||
function advtrains.get_adjacent_rail(this_posnr, this_conns_p, conn_idx, drives_on)
|
||||
function advtrains.get_adjacent_rail(this_posnr, this_conns_p, conn_idx)
|
||||
local this_pos = advtrains.round_vector_floor_y(this_posnr)
|
||||
local this_conns = this_conns_p
|
||||
local _
|
||||
|
@ -318,11 +318,11 @@ function advtrains.get_adjacent_rail(this_posnr, this_conns_p, conn_idx, drives_
|
|||
adj_pos.y = adj_pos.y + 1
|
||||
end
|
||||
|
||||
local nextnode_ok, nextconns, nextrail_y=advtrains.get_rail_info_at(adj_pos, drives_on)
|
||||
local nextnode_ok, nextconns, nextrail_y=advtrains.get_rail_info_at(adj_pos)
|
||||
if not nextnode_ok then
|
||||
adj_pos.y = adj_pos.y - 1
|
||||
conn_y = conn_y + 1
|
||||
nextnode_ok, nextconns, nextrail_y=advtrains.get_rail_info_at(adj_pos, drives_on)
|
||||
nextnode_ok, nextconns, nextrail_y=advtrains.get_rail_info_at(adj_pos)
|
||||
if not nextnode_ok then
|
||||
return nil
|
||||
end
|
||||
|
|
|
@ -268,17 +268,17 @@ end
|
|||
--false if it's not a rail or the train does not drive on this rail, but it is loaded or
|
||||
--nil if the node is neither loaded nor in trackdb
|
||||
--the distraction between false and nil will be needed only in special cases.(train initpos)
|
||||
function advtrains.get_rail_info_at(pos, drives_on)
|
||||
function advtrains.get_rail_info_at(pos)
|
||||
local rdp=advtrains.round_vector_floor_y(pos)
|
||||
|
||||
local node=ndb.get_node_or_nil(rdp)
|
||||
if not node then return end
|
||||
|
||||
local nodename=node.name
|
||||
if(not advtrains.is_track_and_drives_on(nodename, drives_on)) then
|
||||
if(not advtrains.is_track(nodename)) then
|
||||
return false
|
||||
end
|
||||
local conns, railheight, tracktype=advtrains.get_track_connections(node.name, node.param2)
|
||||
local conns, railheight = advtrains.get_track_connections(node.name, node.param2)
|
||||
|
||||
return true, conns, railheight
|
||||
end
|
||||
|
|
|
@ -0,0 +1,751 @@
|
|||
--advtrains by orwell96, see readme.txt
|
||||
|
||||
--dev-time settings:
|
||||
--EDIT HERE
|
||||
--If the old non-model rails on straight tracks should be replaced by the new...
|
||||
--false: no
|
||||
--true: yes
|
||||
advtrains.register_replacement_lbms=false
|
||||
|
||||
--[[TracksDefinition
|
||||
nodename_prefix
|
||||
texture_prefix
|
||||
description
|
||||
common={}
|
||||
straight={}
|
||||
straight45={}
|
||||
curve={}
|
||||
curve45={}
|
||||
lswitchst={}
|
||||
lswitchst45={}
|
||||
rswitchst={}
|
||||
rswitchst45={}
|
||||
lswitchcr={}
|
||||
lswitchcr45={}
|
||||
rswitchcr={}
|
||||
rswitchcr45={}
|
||||
vert1={
|
||||
--you'll probably want to override mesh here
|
||||
}
|
||||
vert2={
|
||||
--you'll probably want to override mesh here
|
||||
}
|
||||
]]--
|
||||
advtrains.all_tracktypes={}
|
||||
|
||||
--definition preparation
|
||||
local function conns(c1, c2, r1, r2) return {{c=c1, y=r1}, {c=c2, y=r2}} end
|
||||
local function conns3(c1, c2, c3, r1, r2, r3) return {{c=c1, y=r1}, {c=c2, y=r2}, {c=c3, y=r3}} end
|
||||
|
||||
advtrains.ap={}
|
||||
advtrains.ap.t_30deg_flat={
|
||||
regstep=1,
|
||||
variant={
|
||||
st={
|
||||
conns = conns(0,8),
|
||||
desc = "straight",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "cr",
|
||||
},
|
||||
cr={
|
||||
conns = conns(0,7),
|
||||
desc = "curve",
|
||||
tpdouble = true,
|
||||
trackworker = "swlst",
|
||||
},
|
||||
swlst={
|
||||
conns = conns3(0,8,7),
|
||||
desc = "left switch (straight)",
|
||||
trackworker = "swrst",
|
||||
switchalt = "cr",
|
||||
switchmc = "on",
|
||||
switchst = "st",
|
||||
switchprefix = "swl",
|
||||
},
|
||||
swlcr={
|
||||
conns = conns3(0,7,8),
|
||||
desc = "left switch (curve)",
|
||||
trackworker = "swrcr",
|
||||
switchalt = "st",
|
||||
switchmc = "off",
|
||||
switchst = "cr",
|
||||
switchprefix = "swl",
|
||||
},
|
||||
swrst={
|
||||
conns = conns3(0,8,9),
|
||||
desc = "right switch (straight)",
|
||||
trackworker = "st",
|
||||
switchalt = "cr",
|
||||
switchmc = "on",
|
||||
switchst = "st",
|
||||
switchprefix = "swr",
|
||||
},
|
||||
swrcr={
|
||||
conns = conns3(0,9,8),
|
||||
desc = "right switch (curve)",
|
||||
trackworker = "st",
|
||||
switchalt = "st",
|
||||
switchmc = "off",
|
||||
switchst = "cr",
|
||||
switchprefix = "swr",
|
||||
},
|
||||
},
|
||||
regtp=true,
|
||||
tpdefault="st",
|
||||
trackworker={
|
||||
["swrcr"]="st",
|
||||
["swrst"]="st",
|
||||
["cr"]="swlst",
|
||||
["swlcr"]="swrcr",
|
||||
["swlst"]="swrst",
|
||||
},
|
||||
rotation={"", "_30", "_45", "_60"},
|
||||
}
|
||||
advtrains.ap.t_yturnout={
|
||||
regstep=1,
|
||||
variant={
|
||||
l={
|
||||
conns = conns3(0,7,9),
|
||||
desc = "Y-turnout (left)",
|
||||
switchalt = "r",
|
||||
switchmc = "off",
|
||||
switchst = "l",
|
||||
switchprefix = "",
|
||||
},
|
||||
r={
|
||||
conns = conns3(0,9,7),
|
||||
desc = "Y-turnout (right)",
|
||||
switchalt = "l",
|
||||
switchmc = "on",
|
||||
switchst = "r",
|
||||
switchprefix = "",
|
||||
}
|
||||
},
|
||||
regtp=true,
|
||||
tpdefault="l",
|
||||
rotation={"", "_30", "_45", "_60"},
|
||||
}
|
||||
advtrains.ap.t_s3way={
|
||||
regstep=1,
|
||||
variant={
|
||||
l={
|
||||
conns = { {c=0}, {c=7}, {c=8}, {c=9}, {c=0} },
|
||||
desc = "3-way turnout (left)",
|
||||
switchalt = "s",
|
||||
switchst="l",
|
||||
switchprefix = "",
|
||||
},
|
||||
s={
|
||||
conns = { {c=0}, {c=8}, {c=7}, {c=9}, {c=0} },
|
||||
desc = "3-way turnout (straight)",
|
||||
switchalt ="r",
|
||||
switchst = "s",
|
||||
switchprefix = "",
|
||||
},
|
||||
r={
|
||||
conns = { {c=0}, {c=9}, {c=8}, {c=7}, {c=0} },
|
||||
desc = "3-way turnout (right)",
|
||||
switchalt = "l",
|
||||
switchst="r",
|
||||
switchprefix = "",
|
||||
}
|
||||
},
|
||||
regtp=true,
|
||||
tpdefault="l",
|
||||
rotation={"", "_30", "_45", "_60"},
|
||||
}
|
||||
advtrains.ap.t_30deg_slope={
|
||||
regstep=1,
|
||||
variant={
|
||||
vst1={conns = conns(8,0,0,0.5), rail_y = 0.25, desc = "steep uphill 1/2", slope=true},
|
||||
vst2={conns = conns(8,0,0.5,1), rail_y = 0.75, desc = "steep uphill 2/2", slope=true},
|
||||
vst31={conns = conns(8,0,0,0.33), rail_y = 0.16, desc = "uphill 1/3", slope=true},
|
||||
vst32={conns = conns(8,0,0.33,0.66), rail_y = 0.5, desc = "uphill 2/3", slope=true},
|
||||
vst33={conns = conns(8,0,0.66,1), rail_y = 0.83, desc = "uphill 3/3", slope=true},
|
||||
},
|
||||
regsp=true,
|
||||
slopeplacer={
|
||||
[2]={"vst1", "vst2"},
|
||||
[3]={"vst31", "vst32", "vst33"},
|
||||
max=3,--highest entry
|
||||
},
|
||||
slopeplacer_45={
|
||||
[2]={"vst1_45", "vst2_45"},
|
||||
max=2,
|
||||
},
|
||||
rotation={"", "_30", "_45", "_60"},
|
||||
trackworker={},
|
||||
increativeinv={},
|
||||
}
|
||||
advtrains.ap.t_30deg_straightonly={
|
||||
regstep=1,
|
||||
variant={
|
||||
st={
|
||||
conns = conns(0,8),
|
||||
desc = "straight",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "st",
|
||||
},
|
||||
},
|
||||
regtp=true,
|
||||
tpdefault="st",
|
||||
rotation={"", "_30", "_45", "_60"},
|
||||
}
|
||||
advtrains.ap.t_30deg_straightonly_noplacer={
|
||||
regstep=1,
|
||||
variant={
|
||||
st={
|
||||
conns = conns(0,8),
|
||||
desc = "straight",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "st",
|
||||
},
|
||||
},
|
||||
tpdefault="st",
|
||||
rotation={"", "_30", "_45", "_60"},
|
||||
}
|
||||
advtrains.ap.t_45deg={
|
||||
regstep=2,
|
||||
variant={
|
||||
st={
|
||||
conns = conns(0,8),
|
||||
desc = "straight",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "cr",
|
||||
},
|
||||
cr={
|
||||
conns = conns(0,6),
|
||||
desc = "curve",
|
||||
tpdouble = true,
|
||||
trackworker = "swlst",
|
||||
},
|
||||
swlst={
|
||||
conns = conns3(0,8,6),
|
||||
desc = "left switch (straight)",
|
||||
trackworker = "swrst",
|
||||
switchalt = "cr",
|
||||
switchmc = "on",
|
||||
switchst = "st",
|
||||
},
|
||||
swlcr={
|
||||
conns = conns3(0,6,8),
|
||||
desc = "left switch (curve)",
|
||||
trackworker = "swrcr",
|
||||
switchalt = "st",
|
||||
switchmc = "off",
|
||||
switchst = "cr",
|
||||
},
|
||||
swrst={
|
||||
conns = conns3(0,8,10),
|
||||
desc = "right switch (straight)",
|
||||
trackworker = "st",
|
||||
switchalt = "cr",
|
||||
switchmc = "on",
|
||||
switchst = "st",
|
||||
},
|
||||
swrcr={
|
||||
conns = conns3(0,10,8),
|
||||
desc = "right switch (curve)",
|
||||
trackworker = "st",
|
||||
switchalt = "st",
|
||||
switchmc = "off",
|
||||
switchst = "cr",
|
||||
},
|
||||
},
|
||||
regtp=true,
|
||||
tpdefault="st",
|
||||
trackworker={
|
||||
["swrcr"]="st",
|
||||
["swrst"]="st",
|
||||
["cr"]="swlst",
|
||||
["swlcr"]="swrcr",
|
||||
["swlst"]="swrst",
|
||||
},
|
||||
rotation={"", "_30", "_45", "_60"},
|
||||
}
|
||||
advtrains.ap.t_perpcrossing={
|
||||
regstep = 1,
|
||||
variant={
|
||||
st={
|
||||
conns = { {c=0}, {c=8}, {c=4}, {c=12} },
|
||||
desc = "perpendicular crossing",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "st",
|
||||
},
|
||||
},
|
||||
regtp=true,
|
||||
tpdefault="st",
|
||||
rotation={"", "_30", "_45", "_60"},
|
||||
}
|
||||
advtrains.ap.t_90plusx_crossing={
|
||||
regstep = 1,
|
||||
variant={
|
||||
["30l"]={
|
||||
conns = { {c=0}, {c=8}, {c=1}, {c=9} },
|
||||
desc = "30/90 degree crossing (left)",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "45l"
|
||||
},
|
||||
["45l"]={
|
||||
conns = { {c=0}, {c=8}, {c=2}, {c=10} },
|
||||
desc = "45/90 degree crossing (left)",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "60l",
|
||||
},
|
||||
["60l"]={
|
||||
conns = { {c=0}, {c=8}, {c=3}, {c=11}},
|
||||
desc = "60/90 degree crossing (left)",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "60r",
|
||||
},
|
||||
["60r"]={
|
||||
conns = { {c=0}, {c=8}, {c=5}, {c=13} },
|
||||
desc = "60/90 degree crossing (right)",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "45r"
|
||||
},
|
||||
["45r"]={
|
||||
conns = { {c=0}, {c=8}, {c=6}, {c=14} },
|
||||
desc = "45/90 degree crossing (right)",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "30r",
|
||||
},
|
||||
["30r"]={
|
||||
conns = { {c=0}, {c=8}, {c=7}, {c=15}},
|
||||
desc = "30/90 degree crossing (right)",
|
||||
tpdouble = true,
|
||||
tpsingle = true,
|
||||
trackworker = "30l",
|
||||
},
|
||||
},
|
||||
regtp=true,
|
||||
tpdefault="30l",
|
||||
rotation={""},
|
||||
trackworker = {
|
||||
["30l"] = "45l",
|
||||
["45l"] = "60l",
|
||||
["60l"] = "60r",
|
||||
["60r"] = "45r",
|
||||
["45r"] = "30r",
|
||||
["30r"] = "30l",
|
||||
}
|
||||
}
|
||||
|
||||
advtrains.ap.t_diagonalcrossing = {
|
||||
regstep=1,
|
||||
variant={
|
||||
["30l45r"]={
|
||||
conns = {{c=1}, {c=9}, {c=6}, {c=14}},
|
||||
desc = "30left-45right diagonal crossing",
|
||||
tpdouble=true,
|
||||
tpsingle=true,
|
||||
trackworker="60l30l",
|
||||
},
|
||||
["60l30l"]={
|
||||
conns = {{c=3}, {c=11}, {c=1}, {c=9}},
|
||||
desc = "30left-60right diagonal crossing",
|
||||
tpdouble=true,
|
||||
tpsingle=true,
|
||||
trackworker="60l45r"
|
||||
},
|
||||
["60l45r"]={
|
||||
conns = {{c=3}, {c=11}, {c=6}, {c=14}},
|
||||
desc = "60left-45right diagonal crossing",
|
||||
tpdouble=true,
|
||||
tpsingle=true,
|
||||
trackworker="60l60r"
|
||||
},
|
||||
["60l60r"]={
|
||||
conns = {{c=3}, {c=11}, {c=5}, {c=13}},
|
||||
desc = "60left-60right diagonal crossing",
|
||||
tpdouble=true,
|
||||
tpsingle=true,
|
||||
trackworker="60r45l",
|
||||
},
|
||||
--If 60l60r had a mirror image, it would be here, but it's symmetric.
|
||||
-- 60l60r is also equivalent to 30l30r but rotated 90 degrees.
|
||||
["60r45l"]={
|
||||
conns = {{c=5}, {c=13}, {c=2}, {c=10}},
|
||||
desc = "60right-45left diagonal crossing",
|
||||
tpdouble=true,
|
||||
tpsingle=true,
|
||||
trackworker="60r30r",
|
||||
},
|
||||
["60r30r"]={
|
||||
conns = {{c=5}, {c=13}, {c=7}, {c=15}},
|
||||
desc = "60right-30right diagonal crossing",
|
||||
tpdouble=true,
|
||||
tpsingle=true,
|
||||
trackworker="30r45l",
|
||||
},
|
||||
["30r45l"]={
|
||||
conns = {{c=7}, {c=15}, {c=2}, {c=10}},
|
||||
desc = "30right-45left diagonal crossing",
|
||||
tpdouble=true,
|
||||
tpsingle=true,
|
||||
trackworker="30l45r",
|
||||
},
|
||||
|
||||
},
|
||||
regtp=true,
|
||||
tpdefault="30l45r",
|
||||
rotation={""},
|
||||
trackworker = {
|
||||
["30l45r"] = "60l30l",
|
||||
["60l30l"] = "60l45r",
|
||||
["60l45r"] = "60l60r",
|
||||
["60l60r"] = "60r45l",
|
||||
["60r45l"] = "60r30r",
|
||||
["60r30r"] = "30r45l",
|
||||
["30r45l"] = "30l45r",
|
||||
}
|
||||
}
|
||||
|
||||
advtrains.trackpresets = advtrains.ap
|
||||
|
||||
--definition format: ([] optional)
|
||||
--[[{
|
||||
nodename_prefix
|
||||
texture_prefix
|
||||
[shared_texture]
|
||||
models_prefix
|
||||
models_suffix (with dot)
|
||||
[shared_model]
|
||||
formats={
|
||||
st,cr,swlst,swlcr,swrst,swrcr,vst1,vst2
|
||||
(each a table with indices 0-3, for if to register a rail with this 'rotation' table entry. nil is assumed as 'all', set {} to not register at all)
|
||||
}
|
||||
common={} change something on common rail appearance
|
||||
}
|
||||
[18.12.17] Note on new connection system:
|
||||
In order to support real rail crossing nodes and finally make the trackplacer respect switches, I changed the connection system.
|
||||
There can be a variable number of connections available. These are specified as tuples {c=<connection>, y=<rely>}
|
||||
The table "at_conns" consists of {<conn1>, <conn2>...}
|
||||
the "at_rail_y" property holds the value that was previously called "railheight"
|
||||
Depending on the number of connections:
|
||||
2 conns: regular rail
|
||||
3 conns: switch:
|
||||
- when train passes in at conn1, will move out of conn2
|
||||
- when train passes in at conn2 or conn3, will move out of conn1
|
||||
4 conns: cross (or cross switch, depending on arrangement of conns):
|
||||
- conn1 <> conn2
|
||||
- conn3 <> conn4
|
||||
]]
|
||||
|
||||
-- Notify the user if digging the rail is not allowed
|
||||
local function can_dig_callback(pos, player)
|
||||
local ok, reason = advtrains.can_dig_or_modify_track(pos)
|
||||
if not ok and player then
|
||||
minetest.chat_send_player(player:get_player_name(), attrans("This track can not be removed!") .. " " .. reason)
|
||||
end
|
||||
return ok
|
||||
end
|
||||
|
||||
function advtrains.register_tracks(tracktype, def, preset)
|
||||
advtrains.trackplacer.register_tracktype(def.nodename_prefix, preset.tpdefault)
|
||||
if preset.regtp then
|
||||
advtrains.trackplacer.register_track_placer(def.nodename_prefix, def.texture_prefix, def.description, def)
|
||||
end
|
||||
if preset.regsp then
|
||||
advtrains.slope.register_placer(def, preset)
|
||||
end
|
||||
for suffix, var in pairs(preset.variant) do
|
||||
for rotid, rotation in ipairs(preset.rotation) do
|
||||
if not def.formats[suffix] or def.formats[suffix][rotid] then
|
||||
local img_suffix = suffix..rotation
|
||||
local ndef = advtrains.merge_tables({
|
||||
description=def.description.."("..(var.desc or "any")..rotation..")",
|
||||
drawtype = "mesh",
|
||||
paramtype="light",
|
||||
paramtype2="facedir",
|
||||
walkable = false,
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2-1/16, -1/2, -1/2, 1/2+1/16, -1/2+2/16, 1/2},
|
||||
},
|
||||
|
||||
mesh = def.shared_model or (def.models_prefix.."_"..img_suffix..def.models_suffix),
|
||||
tiles = {def.shared_texture or (def.texture_prefix.."_"..img_suffix..".png"), def.second_texture},
|
||||
|
||||
groups = {
|
||||
attached_node = advtrains.IGNORE_WORLD and 0 or 1,
|
||||
advtrains_track=1,
|
||||
["advtrains_track_"..tracktype]=1,
|
||||
save_in_at_nodedb=1,
|
||||
dig_immediate=2,
|
||||
not_in_creative_inventory=1,
|
||||
not_blocking_trains=1,
|
||||
},
|
||||
|
||||
can_dig = can_dig_callback,
|
||||
after_dig_node=function(pos)
|
||||
advtrains.ndb.update(pos)
|
||||
end,
|
||||
after_place_node=function(pos)
|
||||
advtrains.ndb.update(pos)
|
||||
end,
|
||||
at_nnpref = def.nodename_prefix,
|
||||
at_suffix = suffix,
|
||||
at_rotation = rotation,
|
||||
at_rail_y = var.rail_y
|
||||
}, def.common or {})
|
||||
|
||||
if preset.regtp then
|
||||
ndef.drop = def.nodename_prefix.."_placer"
|
||||
end
|
||||
if preset.regsp and var.slope then
|
||||
ndef.drop = def.nodename_prefix.."_slopeplacer"
|
||||
end
|
||||
|
||||
--connections
|
||||
ndef.at_conns = advtrains.rotate_conn_by(var.conns, (rotid-1)*preset.regstep)
|
||||
|
||||
local ndef_avt_table
|
||||
|
||||
if var.switchalt and var.switchst then
|
||||
local switchfunc=function(pos, node, newstate)
|
||||
newstate = newstate or var.switchalt -- support for 3 (or more) state switches
|
||||
-- this code is only called from the internal setstate function, which
|
||||
-- ensures that it is safe to switch the turnout
|
||||
if newstate~=var.switchst then
|
||||
advtrains.ndb.swap_node(pos, {name=def.nodename_prefix.."_"..(var.switchprefix or "")..newstate..rotation, param2=node.param2})
|
||||
advtrains.invalidate_all_paths(pos)
|
||||
end
|
||||
end
|
||||
ndef.on_rightclick = function(pos, node, player)
|
||||
if advtrains.check_turnout_signal_protection(pos, player:get_player_name()) then
|
||||
advtrains.setstate(pos, nil, node)
|
||||
advtrains.log("Switch", player:get_player_name(), pos)
|
||||
end
|
||||
end
|
||||
if var.switchmc then
|
||||
ndef.mesecons = {effector = {
|
||||
["action_"..var.switchmc] = function(pos, node)
|
||||
advtrains.setstate(pos, nil, node)
|
||||
end,
|
||||
rules=advtrains.meseconrules
|
||||
}}
|
||||
end
|
||||
ndef_avt_table = {
|
||||
getstate = var.switchst,
|
||||
setstate = switchfunc,
|
||||
}
|
||||
end
|
||||
|
||||
local adef={}
|
||||
if def.get_additional_definiton then
|
||||
adef=def.get_additional_definiton(def, preset, suffix, rotation)
|
||||
end
|
||||
ndef = advtrains.merge_tables(ndef, adef)
|
||||
|
||||
-- insert getstate/setstate functions after merging the additional definitions
|
||||
if ndef_avt_table then
|
||||
ndef.advtrains = advtrains.merge_tables(ndef.advtrains or {}, ndef_avt_table)
|
||||
end
|
||||
|
||||
minetest.register_node(":"..def.nodename_prefix.."_"..suffix..rotation, ndef)
|
||||
--trackplacer
|
||||
if preset.regtp then
|
||||
local tpconns = {conn1=ndef.at_conns[1].c, conn2=ndef.at_conns[2].c}
|
||||
if var.tpdouble then
|
||||
advtrains.trackplacer.add_double_conn(def.nodename_prefix, suffix, rotation, tpconns)
|
||||
end
|
||||
if var.tpsingle then
|
||||
advtrains.trackplacer.add_single_conn(def.nodename_prefix, suffix, rotation, tpconns)
|
||||
end
|
||||
end
|
||||
advtrains.trackplacer.add_worked(def.nodename_prefix, suffix, rotation, var.trackworker)
|
||||
end
|
||||
end
|
||||
end
|
||||
advtrains.all_tracktypes[tracktype]=true
|
||||
end
|
||||
|
||||
function advtrains.is_track_and_drives_on(nodename, drives_on_p)
|
||||
local drives_on = drives_on_p
|
||||
if not drives_on then drives_on = advtrains.all_tracktypes end
|
||||
local hasentry = false
|
||||
for _,_ in pairs(drives_on) do
|
||||
hasentry=true
|
||||
end
|
||||
if not hasentry then drives_on = advtrains.all_tracktypes end
|
||||
|
||||
if not minetest.registered_nodes[nodename] then
|
||||
return false
|
||||
end
|
||||
local nodedef=minetest.registered_nodes[nodename]
|
||||
for k,v in pairs(drives_on) do
|
||||
if nodedef.groups["advtrains_track_"..k] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function advtrains.get_track_connections(name, param2)
|
||||
local nodedef=minetest.registered_nodes[name]
|
||||
if not nodedef then atprint(" get_track_connections couldn't find nodedef for nodename "..(name or "nil")) return nil end
|
||||
local noderot=param2
|
||||
if not param2 then noderot=0 end
|
||||
if noderot > 3 then atprint(" get_track_connections: rail has invaild param2 of "..noderot) noderot=0 end
|
||||
|
||||
local tracktype
|
||||
for k,_ in pairs(nodedef.groups) do
|
||||
local tt=string.match(k, "^advtrains_track_(.+)$")
|
||||
if tt then
|
||||
tracktype=tt
|
||||
end
|
||||
end
|
||||
return advtrains.rotate_conn_by(nodedef.at_conns, noderot*AT_CMAX/4), (nodedef.at_rail_y or 0), tracktype
|
||||
end
|
||||
|
||||
-- Function called when a track is about to be dug or modified by the trackworker
|
||||
-- Returns either true (ok) or false,"translated string describing reason why it isn't allowed"
|
||||
function advtrains.can_dig_or_modify_track(pos)
|
||||
if advtrains.get_train_at_pos(pos) then
|
||||
return false, attrans("Position is occupied by a train.")
|
||||
end
|
||||
-- interlocking: tcb, signal IP a.s.o.
|
||||
if advtrains.interlocking then
|
||||
-- TCB?
|
||||
if advtrains.interlocking.db.get_tcb(pos) then
|
||||
return false, attrans("There's a Track Circuit Break here.")
|
||||
end
|
||||
-- signal ip?
|
||||
if advtrains.interlocking.db.is_ip_at(pos, true) then -- is_ip_at with purge parameter
|
||||
return false, attrans("There's a Signal Influence Point here.")
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- slope placer. Defined in register_tracks.
|
||||
--crafted with rail and gravel
|
||||
local sl={}
|
||||
function sl.register_placer(def, preset)
|
||||
minetest.register_craftitem(":"..def.nodename_prefix.."_slopeplacer",{
|
||||
description = attrans("@1 Slope", def.description),
|
||||
inventory_image = def.texture_prefix.."_slopeplacer.png",
|
||||
wield_image = def.texture_prefix.."_slopeplacer.png",
|
||||
groups={},
|
||||
on_place = sl.create_slopeplacer_on_place(def, preset)
|
||||
})
|
||||
end
|
||||
--(itemstack, placer, pointed_thing)
|
||||
function sl.create_slopeplacer_on_place(def, preset)
|
||||
return function(istack, player, pt)
|
||||
if not pt.type=="node" then
|
||||
minetest.chat_send_player(player:get_player_name(), attrans("Can't place: not pointing at node"))
|
||||
return istack
|
||||
end
|
||||
local pos=pt.above
|
||||
if not pos then
|
||||
minetest.chat_send_player(player:get_player_name(), attrans("Can't place: not pointing at node"))
|
||||
return istack
|
||||
end
|
||||
local node=minetest.get_node(pos)
|
||||
if not minetest.registered_nodes[node.name] or not minetest.registered_nodes[node.name].buildable_to then
|
||||
minetest.chat_send_player(player:get_player_name(), attrans("Can't place: space occupied!"))
|
||||
return istack
|
||||
end
|
||||
if not advtrains.check_track_protection(pos, player:get_player_name()) then
|
||||
minetest.record_protection_violation(pos, player:get_player_name())
|
||||
return istack
|
||||
end
|
||||
--determine player orientation (only horizontal component)
|
||||
--get_look_horizontal may not be available
|
||||
local yaw=player.get_look_horizontal and player:get_look_horizontal() or (player:get_look_yaw() - math.pi/2)
|
||||
|
||||
--rounding unit vectors is a nice way for selecting 1 of 8 directions since sin(30°) is 0.5.
|
||||
local dirvec={x=math.floor(math.sin(-yaw)+0.5), y=0, z=math.floor(math.cos(-yaw)+0.5)}
|
||||
--translate to direction to look up inside the preset table
|
||||
local param2, rot45=({
|
||||
[-1]={
|
||||
[-1]=2,
|
||||
[0]=3,
|
||||
[1]=3,
|
||||
},
|
||||
[0]={
|
||||
[-1]=2,
|
||||
[1]=0,
|
||||
},
|
||||
[1]={
|
||||
[-1]=1,
|
||||
[0]=1,
|
||||
[1]=0,
|
||||
},
|
||||
})[dirvec.x][dirvec.z], dirvec.x~=0 and dirvec.z~=0
|
||||
local lookup=preset.slopeplacer
|
||||
if rot45 then lookup=preset.slopeplacer_45 end
|
||||
|
||||
--go unitvector forward and look how far the next node is
|
||||
local step=1
|
||||
while step<=lookup.max do
|
||||
local node=minetest.get_node(vector.add(pos, dirvec))
|
||||
--next node solid?
|
||||
if not minetest.registered_nodes[node.name] or not minetest.registered_nodes[node.name].buildable_to or advtrains.is_protected(pos, player:get_player_name()) then
|
||||
--do slopes of this distance exist?
|
||||
if lookup[step] then
|
||||
if minetest.settings:get_bool("creative_mode") or istack:get_count()>=step then
|
||||
--start placing
|
||||
local placenodes=lookup[step]
|
||||
while step>0 do
|
||||
minetest.set_node(pos, {name=def.nodename_prefix.."_"..placenodes[step], param2=param2})
|
||||
if not minetest.settings:get_bool("creative_mode") then
|
||||
istack:take_item()
|
||||
end
|
||||
step=step-1
|
||||
pos=vector.subtract(pos, dirvec)
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(player:get_player_name(), attrans("Can't place: Not enough slope items left (@1 required)", step))
|
||||
end
|
||||
else
|
||||
minetest.chat_send_player(player:get_player_name(), attrans("Can't place: There's no slope of length @1",step))
|
||||
end
|
||||
return istack
|
||||
end
|
||||
step=step+1
|
||||
pos=vector.add(pos, dirvec)
|
||||
end
|
||||
minetest.chat_send_player(player:get_player_name(), attrans("Can't place: no supporting node at upper end."))
|
||||
return itemstack
|
||||
end
|
||||
end
|
||||
|
||||
advtrains.slope=sl
|
||||
|
||||
--END code, BEGIN definition
|
||||
--definition format: ([] optional)
|
||||
--[[{
|
||||
nodename_prefix
|
||||
texture_prefix
|
||||
[shared_texture]
|
||||
models_prefix
|
||||
models_suffix (with dot)
|
||||
[shared_model]
|
||||
formats={
|
||||
st,cr,swlst,swlcr,swrst,swrcr,vst1,vst2
|
||||
(each a table with indices 0-3, for if to register a rail with this 'rotation' table entry. nil is assumed as 'all', set {} to not register at all)
|
||||
}
|
||||
common={} change something on common rail appearance
|
||||
}]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,9 +1,5 @@
|
|||
-- passive.lua
|
||||
-- API to passive components, as described in passive_api.txt of advtrains_luaautomation
|
||||
-- This has been moved to the advtrains core in turn with the interlocking system,
|
||||
-- to prevent a dependency on luaautomation.
|
||||
|
||||
local deprecation_warned = {}
|
||||
-- Rework for advtrains 2.5: The passive API now uses the reworked node_state system. Please see the comment in tracks.lua
|
||||
|
||||
function advtrains.getstate(parpos, pnode)
|
||||
local pos
|
||||
|
@ -19,20 +15,8 @@ function advtrains.getstate(parpos, pnode)
|
|||
local node=pnode or advtrains.ndb.get_node(pos)
|
||||
local ndef=minetest.registered_nodes[node.name]
|
||||
local st
|
||||
if ndef and ndef.advtrains and ndef.advtrains.getstate then
|
||||
st=ndef.advtrains.getstate
|
||||
elseif ndef and ndef.luaautomation and ndef.luaautomation.getstate then
|
||||
if not deprecation_warned[node.name] then
|
||||
minetest.log("warning", node.name.." uses deprecated definition of ATLATC functions in the 'luaautomation' field. Please move them to the 'advtrains' field!")
|
||||
end
|
||||
st=ndef.luaautomation.getstate
|
||||
else
|
||||
return nil
|
||||
end
|
||||
if type(st)=="function" then
|
||||
return st(pos, node)
|
||||
else
|
||||
return st
|
||||
if ndef and ndef.advtrains then
|
||||
return ndef.advtrains.node_state
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -45,31 +29,46 @@ function advtrains.setstate(parpos, newstate, pnode)
|
|||
end
|
||||
if type(pos)~="table" or (not pos.x or not pos.y or not pos.z) then
|
||||
debug.sethook()
|
||||
error("Invalid position supplied to getstate")
|
||||
error("Invalid position supplied to setstate")
|
||||
end
|
||||
local node=pnode or advtrains.ndb.get_node(pos)
|
||||
local ndef=minetest.registered_nodes[node.name]
|
||||
local st
|
||||
if ndef and ndef.advtrains and ndef.advtrains.setstate then
|
||||
st=ndef.advtrains.setstate
|
||||
elseif ndef and ndef.luaautomation and ndef.luaautomation.setstate then
|
||||
if not deprecation_warned[node.name] then
|
||||
minetest.log("warning", node.name.." uses deprecated definition of ATLATC functions in the 'luaautomation' field. Please move them to the 'advtrains' field!")
|
||||
end
|
||||
st=ndef.luaautomation.setstate
|
||||
else
|
||||
return nil
|
||||
|
||||
if not ndef or not ndef.advtrains then
|
||||
return false, "missing_node_def"
|
||||
end
|
||||
local old_state = ndef.advtrains.node_state
|
||||
|
||||
if old_state == newstate then
|
||||
-- nothing needs to be done
|
||||
return true
|
||||
end
|
||||
|
||||
if not ndef.advtrains.node_state_map then
|
||||
return false, "missing_node_state_map"
|
||||
end
|
||||
local new_node_name = ndef.advtrains.node_state_map[newstate]
|
||||
if not new_node_name then
|
||||
return false, "no_such_state"
|
||||
end
|
||||
|
||||
-- prevent state switching when route lock or train is present
|
||||
if advtrains.get_train_at_pos(pos) then
|
||||
return false
|
||||
return false, "train_here"
|
||||
end
|
||||
|
||||
if advtrains.interlocking and advtrains.interlocking.route.has_route_lock(minetest.pos_to_string(pos)) then
|
||||
return false
|
||||
return false, "route_lock_here"
|
||||
end
|
||||
|
||||
st(pos, node, newstate)
|
||||
-- perform the switch
|
||||
local new_node = {name = new_node_name, param2 = node.param2}
|
||||
advtrains.ndb.swap_node(pos, new_node)
|
||||
-- if callback is present, call it
|
||||
if ndef.advtrains.node_on_switch_state then
|
||||
ndef.advtrains.node_on_switch_state(pos, new_node, old_state, newstate)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
|
@ -86,12 +85,7 @@ function advtrains.is_passive(parpos, pnode)
|
|||
end
|
||||
local node=pnode or advtrains.ndb.get_node(pos)
|
||||
local ndef=minetest.registered_nodes[node.name]
|
||||
if ndef and ndef.advtrains and ndef.advtrains.getstate then
|
||||
return true
|
||||
elseif ndef and ndef.luaautomation and ndef.luaautomation.getstate then
|
||||
if not deprecation_warned[node.name] then
|
||||
minetest.log("warning", node.name.." uses deprecated definition of ATLATC functions in the 'luaautomation' field. Please move them to the 'advtrains' field!")
|
||||
end
|
||||
if ndef and ndef.advtrains and ndef.advtrains.node_state_map then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
|
@ -102,20 +96,10 @@ end
|
|||
function advtrains.set_fallback_state(pos, pnode)
|
||||
local node=pnode or advtrains.ndb.get_node(pos)
|
||||
local ndef=minetest.registered_nodes[node.name]
|
||||
local st
|
||||
if ndef and ndef.advtrains and ndef.advtrains.setstate
|
||||
and ndef.advtrains.fallback_state then
|
||||
if advtrains.get_train_at_pos(pos) then
|
||||
return false
|
||||
end
|
||||
|
||||
if advtrains.interlocking and advtrains.interlocking.route.has_route_lock(minetest.pos_to_string(pos)) then
|
||||
return false
|
||||
end
|
||||
|
||||
ndef.advtrains.setstate(pos, node, ndef.advtrains.fallback_state)
|
||||
return true
|
||||
|
||||
if not ndef or not ndef.advtrains or not ndef.advtrains.node_fallback_state then
|
||||
return false, "no_fallback_state"
|
||||
end
|
||||
|
||||
|
||||
return advtrains.setstate(pos, ndef.advtrains.node_fallback_state, node)
|
||||
end
|
||||
|
|
|
@ -33,13 +33,12 @@
|
|||
-- If you need to proceed along the path by a specific actual distance, it does NOT work to simply add it to the index. You should use the path_get_index_by_offset() function.
|
||||
|
||||
-- creates the path data structure, reconstructing the train from a position and a connid
|
||||
-- Important! train.drives_on must exist while calling this method
|
||||
-- returns: true - successful
|
||||
-- nil - node not yet available/unloaded, please wait
|
||||
-- false - node definitely gone, remove train
|
||||
function advtrains.path_create(train, pos, connid, rel_index)
|
||||
local posr = advtrains.round_vector_floor_y(pos)
|
||||
local node_ok, conns, rhe = advtrains.get_rail_info_at(pos, train.drives_on)
|
||||
local node_ok, conns, rhe = advtrains.get_rail_info_at(pos)
|
||||
if not node_ok then
|
||||
return node_ok
|
||||
end
|
||||
|
@ -211,7 +210,7 @@ function advtrains.path_get(train, index)
|
|||
if pef == train.path_trk_f then
|
||||
node_ok, this_conns = advtrains.get_rail_info_at(pos)
|
||||
if not node_ok then error("For train "..train.id..": Path item "..pef.." on-track but not a valid node!") end
|
||||
adj_pos, adj_connid, conn_idx, nextrail_y, next_conns = advtrains.get_adjacent_rail(pos, this_conns, connid, train.drives_on)
|
||||
adj_pos, adj_connid, conn_idx, nextrail_y, next_conns = advtrains.get_adjacent_rail(pos, this_conns, connid)
|
||||
end
|
||||
pef = pef + 1
|
||||
if adj_pos then
|
||||
|
@ -250,7 +249,7 @@ function advtrains.path_get(train, index)
|
|||
if peb == train.path_trk_b then
|
||||
node_ok, this_conns = advtrains.get_rail_info_at(pos)
|
||||
if not node_ok then error("For train "..train.id..": Path item "..peb.." on-track but not a valid node!") end
|
||||
adj_pos, adj_connid, conn_idx, nextrail_y, next_conns = advtrains.get_adjacent_rail(pos, this_conns, connid, train.drives_on)
|
||||
adj_pos, adj_connid, conn_idx, nextrail_y, next_conns = advtrains.get_adjacent_rail(pos, this_conns, connid)
|
||||
end
|
||||
peb = peb - 1
|
||||
if adj_pos then
|
||||
|
|
|
@ -40,9 +40,6 @@ local suppasp = {
|
|||
|
||||
for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red", als="green"}}) do
|
||||
|
||||
advtrains.trackplacer.register_tracktype("advtrains:retrosignal", "")
|
||||
advtrains.trackplacer.register_tracktype("advtrains:signal", "")
|
||||
|
||||
for rotid, rotation in ipairs({"", "_30", "_45", "_60"}) do
|
||||
local crea=1
|
||||
if rotid==1 and r=="off" then crea=0 end
|
||||
|
@ -108,8 +105,8 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
|
|||
},
|
||||
can_dig = can_dig_func,
|
||||
after_dig_node = after_dig_func,
|
||||
--TODO add rotation using trackworker
|
||||
})
|
||||
advtrains.trackplacer.add_worked("advtrains:retrosignal", r, rotation, nil)
|
||||
|
||||
minetest.register_node("advtrains:signal_"..r..rotation, {
|
||||
drawtype = "mesh",
|
||||
|
@ -179,8 +176,8 @@ for r,f in pairs({on={as="off", ls="green", als="red"}, off={as="on", ls="red",
|
|||
},
|
||||
can_dig = can_dig_func,
|
||||
after_dig_node = after_dig_func,
|
||||
--TODO add rotation using trackworker
|
||||
})
|
||||
advtrains.trackplacer.add_worked("advtrains:signal", r, rotation, nil)
|
||||
end
|
||||
|
||||
local crea=1
|
||||
|
|
|
@ -3,311 +3,204 @@
|
|||
|
||||
--all new trackplacer code
|
||||
local tp={
|
||||
tracks={}
|
||||
groups={}
|
||||
}
|
||||
|
||||
function tp.register_tracktype(nnprefix, n_suffix)
|
||||
if tp.tracks[nnprefix] then return end--due to the separate registration of slopes and flats for the same nnpref, definition would be overridden here. just don't.
|
||||
tp.tracks[nnprefix]={
|
||||
default=n_suffix,
|
||||
single_conn={},
|
||||
single_conn_1={},
|
||||
single_conn_2={},
|
||||
double_conn={},
|
||||
double_conn_1={},
|
||||
double_conn_2={},
|
||||
--keys:conn1_conn2 (example:1_4)
|
||||
--values:{name=x, param2=x}
|
||||
twcycle={},
|
||||
twrotate={},--indexed by suffix, list, tells order of rotations
|
||||
modify={},
|
||||
}
|
||||
end
|
||||
function tp.add_double_conn(nnprefix, suffix, rotation, conns)
|
||||
local nodename=nnprefix.."_"..suffix..rotation
|
||||
for i=0,3 do
|
||||
tp.tracks[nnprefix].double_conn[((conns.conn1+4*i)%16).."_"..((conns.conn2+4*i)%16)]={name=nodename, param2=i}
|
||||
tp.tracks[nnprefix].double_conn[((conns.conn2+4*i)%16).."_"..((conns.conn1+4*i)%16)]={name=nodename, param2=i}
|
||||
tp.tracks[nnprefix].double_conn_1[((conns.conn1+4*i)%16).."_"..((conns.conn2+4*i)%16)]={name=nodename, param2=i}
|
||||
tp.tracks[nnprefix].double_conn_2[((conns.conn2+4*i)%16).."_"..((conns.conn1+4*i)%16)]={name=nodename, param2=i}
|
||||
end
|
||||
tp.tracks[nnprefix].modify[nodename]=true
|
||||
end
|
||||
function tp.add_single_conn(nnprefix, suffix, rotation, conns)
|
||||
local nodename=nnprefix.."_"..suffix..rotation
|
||||
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
|
||||
--[[ New in version 2.5:
|
||||
|
||||
The track placer no longer uses hacky nodename pattern matching.
|
||||
The base criterion for rotating or matching tracks is the common "ndef.advtrains.track_place_group" property.
|
||||
Only rails where this field is set are considered for replacement. Other rails can still be considered for connection.
|
||||
Replacement ("bending") of rails can only happen within their respective track place group. Only two-conn rails are allowed in the trackplacer.
|
||||
|
||||
The track registration functions register the candidates for any given track_place_group in two separate collections:
|
||||
- double: tracks that can be used to connect both ends of the rail
|
||||
- single: tracks that will be used to connect conn1 when only a single end is to be connected
|
||||
|
||||
When track placing is requested, the calling code just supplies the track_place_group to be placed.
|
||||
|
||||
]]--
|
||||
|
||||
local function rotate(conn, rot)
|
||||
return (conn + rot) % 16
|
||||
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
|
||||
table.insert(tp.tracks[nnprefix].twrotate[suffix], rotation)
|
||||
end
|
||||
|
||||
|
||||
--[[
|
||||
rewrite algorithm.
|
||||
selection criteria: these will never be changed or even selected:
|
||||
- tracks being already connected on both sides
|
||||
- tracks that are already connected on one side but are not bendable to the desired position
|
||||
the following situations can occur:
|
||||
1. there are two more than two rails around
|
||||
1.1 there is one or more subset(s) that can be directly connected
|
||||
-> choose the first possibility
|
||||
2.2 not
|
||||
-> choose the first one and orient straight
|
||||
2. there's exactly 1 rail around
|
||||
-> choose and orient straight
|
||||
3. there's no rail around
|
||||
-> set straight
|
||||
]]
|
||||
|
||||
local function istrackandbc(pos_p, conn)
|
||||
local tpos = pos_p
|
||||
local cnode=minetest.get_node(advtrains.dirCoordSet(tpos, conn.c))
|
||||
if advtrains.is_track_and_drives_on(cnode.name, advtrains.all_tracktypes) then
|
||||
local cconns=advtrains.get_track_connections(cnode.name, cnode.param2)
|
||||
return advtrains.conn_matches_to(conn, cconns)
|
||||
end
|
||||
--try the same 1 node below
|
||||
tpos = {x=tpos.x, y=tpos.y-1, z=tpos.z}
|
||||
cnode=minetest.get_node(advtrains.dirCoordSet(tpos, conn.c))
|
||||
if advtrains.is_track_and_drives_on(cnode.name, advtrains.all_tracktypes) then
|
||||
local cconns=advtrains.get_track_connections(cnode.name, cnode.param2)
|
||||
return advtrains.conn_matches_to(conn, cconns)
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function tp.find_already_connected(pos)
|
||||
local dnode=minetest.get_node(pos)
|
||||
local dconns=advtrains.get_track_connections(dnode.name, dnode.param2)
|
||||
local found_conn
|
||||
for connid, conn in ipairs(dconns) do
|
||||
if istrackandbc(pos, conn) then
|
||||
if found_conn then --we found one in previous iteration
|
||||
return true, true --signal that it's connected
|
||||
else
|
||||
found_conn = conn.c
|
||||
end
|
||||
end
|
||||
end
|
||||
return found_conn
|
||||
end
|
||||
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)
|
||||
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.at_nnpref
|
||||
if not nnpref then return false end
|
||||
local tr=tp.tracks[nnpref]
|
||||
if not tr then return false end
|
||||
if not tr.modify[node.name] then
|
||||
--we actually can use this rail, but only if it already points to the desired direction.
|
||||
if advtrains.is_track_and_drives_on(node.name, advtrains.all_tracktypes) then
|
||||
local cconns=advtrains.get_track_connections(node.name, node.param2)
|
||||
return advtrains.conn_matches_to(conn, cconns)
|
||||
end
|
||||
end
|
||||
-- If the rail is not allowed to be modified, also only use if already in desired direction
|
||||
if not advtrains.can_dig_or_modify_track(pos) then
|
||||
local cconns=advtrains.get_track_connections(node.name, node.param2)
|
||||
return advtrains.conn_matches_to(conn, cconns)
|
||||
end
|
||||
--rail at other end?
|
||||
local adj1, adj2=tp.find_already_connected(pos)
|
||||
if adj1 and adj2 then
|
||||
return false--dont destroy existing track
|
||||
elseif adj1 and not adj2 then
|
||||
if tr.double_conn[adj1.."_"..newdir] then
|
||||
return true--if exists, connect new rail and old end
|
||||
end
|
||||
return false
|
||||
else
|
||||
if tr.single_conn[newdir] then--just rotate old rail to right orientation
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
function tp.bend_rail(originpos, conn)
|
||||
local pos=advtrains.dirCoordSet(originpos, conn)
|
||||
local newdir=advtrains.oppd(conn)
|
||||
local node=minetest.get_node(pos)
|
||||
local ndef=minetest.registered_nodes[node.name]
|
||||
local nnpref = ndef and ndef.at_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 conns=advtrains.get_track_connections(node.name, node.param2)
|
||||
if advtrains.conn_matches_to(conn, conns) then
|
||||
return
|
||||
end
|
||||
--rail at other end?
|
||||
local adj1, adj2=tp.find_already_connected(pos)
|
||||
if adj1 and adj2 then
|
||||
return false--dont destroy existing track
|
||||
elseif adj1 and not adj2 then
|
||||
if tr.double_conn[adj1.."_"..newdir] then
|
||||
advtrains.ndb.swap_node(pos, tr.double_conn[adj1.."_"..newdir])
|
||||
return true--if exists, connect new rail and old end
|
||||
end
|
||||
return false
|
||||
else
|
||||
if tr.single_conn[newdir] then--just rotate old rail to right orientation
|
||||
advtrains.ndb.swap_node(pos, tr.single_conn[newdir])
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
end
|
||||
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={}
|
||||
local p_railpos={}
|
||||
for i=0,15 do
|
||||
if tp.rail_and_can_be_bent(pos, i, nnpref) then
|
||||
p_rails[#p_rails+1]=i
|
||||
p_railpos[i] = pos
|
||||
else
|
||||
local upos = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
if tp.rail_and_can_be_bent(upos, i, nnpref) then
|
||||
p_rails[#p_rails+1]=i
|
||||
p_railpos[i] = upos
|
||||
end
|
||||
end
|
||||
-- Register a track node as candidate
|
||||
-- tpg: the track place group to register the candidates for
|
||||
-- name, ndef: the node name and node definition table to register
|
||||
-- as_single: whether the rail should be considered as candidate for one-endpoint connection
|
||||
-- Typically only set for the straight rail variants
|
||||
-- as_double: whether the rail should be considered as candidate for two-endpoint connection
|
||||
-- Typically set for straights and curves
|
||||
function tp.register_candidate(tpg, name, ndef, as_single, as_double)
|
||||
--get or create TP group
|
||||
if not tp.groups[tpg] then
|
||||
tp.groups[tpg] = {double = {}, single1 = {}, single2 = {}, default = {name = name, param2 = 0} }
|
||||
-- note: this causes the first candidate to ever be registered to be the default (which is typically what you want)
|
||||
end
|
||||
local g = tp.groups[tpg]
|
||||
|
||||
-- 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
|
||||
if k1~=k2 then
|
||||
local dconn1 = tr.double_conn_1
|
||||
local dconn2 = tr.double_conn_2
|
||||
if not (advtrains.yawToDirection(yaw, conn1, conn2) == conn1) then
|
||||
dconn1 = tr.double_conn_2
|
||||
dconn2 = tr.double_conn_1
|
||||
end
|
||||
-- Checks are made this way round so that dconn1 has priority (this will make arrows of atc rails
|
||||
-- point in the right direction)
|
||||
local using
|
||||
if (dconn2[conn1.."_"..conn2]) then
|
||||
using = dconn2[conn1.."_"..conn2]
|
||||
end
|
||||
if (dconn1[conn1.."_"..conn2]) then
|
||||
using = dconn1[conn1.."_"..conn2]
|
||||
end
|
||||
if using then
|
||||
-- has found a fitting rail in either direction
|
||||
-- if not, continue loop
|
||||
tp.bend_rail(p_railpos[conn1], conn1, nnpref)
|
||||
tp.bend_rail(p_railpos[conn2], conn2, 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
|
||||
-- get conns
|
||||
assert(#ndef.at_conns == 2)
|
||||
local c1, c2 = ndef.at_conns[1].c, ndef.at_conns[2].c
|
||||
local is_symmetrical = (rotate(c1, 8) == c2)
|
||||
|
||||
-- store all possible rotations (param2 values)
|
||||
for i=0,3 do
|
||||
if as_double then
|
||||
g.double[rotate(c1,i*4).."_"..rotate(c2,i*4)] = {name=name, param2=i}
|
||||
if not is_symmmetrical then
|
||||
g.double[rotate(c2,i*4).."_"..rotate(c1,i*4)] = {name=name, param2=i}
|
||||
-- if the track is unsymmetric (e.g. a curve), we may require the "wrong" orientation to fill a gap.
|
||||
end
|
||||
end
|
||||
if as_single then
|
||||
g.single1[rotate(c1,i*4)] = {name=name, param2=i}
|
||||
g.single2[rotate(c2,i*4)] = {name=name, param2=i}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function check_or_bend_rail(origin, dir, pname, commit)
|
||||
local pos = advtrains.pos_add_dir(origin, dir)
|
||||
local back_dir = advtrains.oppd(dir);
|
||||
|
||||
local node_ok, conns = advtrains.get_rail_info_at(pos)
|
||||
if not node_ok then
|
||||
-- try the node one level below
|
||||
pos.y = pos.y - 1
|
||||
node_ok, conns = advtrains.get_rail_info_at(pos)
|
||||
end
|
||||
if not node_ok then
|
||||
return false
|
||||
end
|
||||
-- if one conn of the node here already points towards us, nothing to do
|
||||
for connid, conn in ipairs(conns) do
|
||||
if back_dir == conn.c then
|
||||
return true
|
||||
end
|
||||
end
|
||||
-- can we bend the node here?
|
||||
local node = advtrains.ndb.get_node(pos)
|
||||
local ndef = minetest.registered_nodes[node.name]
|
||||
if not ndef or not ndef.advtrains or not ndef.advtrains.track_place_group then
|
||||
return false
|
||||
end
|
||||
-- now the track must be two-conn, else it wouldn't be allowed to have track_place_group set.
|
||||
assert(#conns == 2)
|
||||
-- Is player and game allowed to do this?
|
||||
if not advtrains.can_dig_or_modify_track(pos) then
|
||||
return false
|
||||
end
|
||||
if not advtrains.check_track_protection(pos, pname) then
|
||||
return false
|
||||
end
|
||||
-- we confirmed that track can be modified. Does there exist a suitable connection candidate?
|
||||
-- check if there are any unbound ends
|
||||
local bound_connids = {}
|
||||
for connid, conn in ipairs(conns) do
|
||||
local adj_pos, adj_connid = advtrains.get_adjacent_rail(pos, conns, connid)
|
||||
if adj_pos then
|
||||
bound_connids[#bound_connids+1] = connid
|
||||
end
|
||||
end
|
||||
-- depending on the nummber of ends, decide
|
||||
if #bound_connids == 2 then
|
||||
-- rail is within a fixed track, do not break up
|
||||
return false
|
||||
end
|
||||
-- obtain the group table
|
||||
local g = tp.groups[ndef.advtrains.track_place_group]
|
||||
if #bound_connids == 1 then
|
||||
-- we can attempt double
|
||||
local bound_dir = conns[bound_connids[1]].c
|
||||
if g.double[back_dir.."_"..bound_dir] then
|
||||
if commit then
|
||||
advtrains.ndb.swap_node(pos, g.double[back_dir.."_"..bound_dir])
|
||||
end
|
||||
return true
|
||||
end
|
||||
else
|
||||
-- rail is entirely unbound, we can attempt single1
|
||||
if g.single1[back_dir] then
|
||||
if commit then
|
||||
advtrains.ndb.swap_node(pos, g.single1[back_dir])
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function track_place_node(pos, node, ndef)
|
||||
advtrains.ndb.swap_node(pos, node)
|
||||
local ndef = minetest.registered_nodes[node.name]
|
||||
if ndef and ndef.after_place_node then
|
||||
ndef.after_place_node(pos)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Main API function to place a track. Replaces the older "placetrack"
|
||||
-- This function will attempt to place a track of the specified track placing group at the specified position, connecting it
|
||||
-- with neighboring rails. Neighboring rails can themselves be replaced ("bent") within their own track place group,
|
||||
-- if the player is permitted to do this.
|
||||
-- Order of preference is:
|
||||
-- Connect two track ends if possible
|
||||
-- Connect one track end if any rail is near
|
||||
-- Place the default track if no tracks are near
|
||||
-- The function returns true on success.
|
||||
function tp.place_track(pos, tpg, pname, yaw)
|
||||
-- 1. collect neighboring tracks and whether they can be connected
|
||||
local cand = {}
|
||||
for i=0,15 do
|
||||
if check_or_bend_rail(pos, i, pname) then
|
||||
cand[#cand+1] = i
|
||||
end
|
||||
end
|
||||
-- obtain the group table
|
||||
local g = tp.groups[tpg]
|
||||
-- 2. try all possible two-endpoint connections
|
||||
for k1, conn1 in ipairs(cand) do
|
||||
for k2, conn2 in ipairs(cand) do
|
||||
if k1~=k2 then
|
||||
-- order of conn1/conn2: prefer conn2 being in the direction of the player facing.
|
||||
-- the combination the other way round will be run through in a later loop iteration
|
||||
if advtrains.yawToDirection(yaw, conn1, conn2) == conn2 then
|
||||
-- does there exist a suitable double-connection rail?
|
||||
local node = g.double[conn1.."_"..conn2]
|
||||
if node then
|
||||
check_or_bend_rail(pos, conn1, pname, true)
|
||||
check_or_bend_rail(pos, conn2, pname, true)
|
||||
track_place_node(pos, node) -- calls after_place_node implicitly
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
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(p_railpos[p_rail], 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(p_railpos[p_rail], 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
|
||||
-- 3. try all possible one_endpoint connections
|
||||
for k1, conn1 in ipairs(cand) do
|
||||
-- select single1 or single2? depending on yaw
|
||||
local single
|
||||
if advtrains.yawToDirection(yaw, conn1, advtrains.oppd(conn1)) == conn1 then
|
||||
single = g.single1
|
||||
else
|
||||
single = g.single2
|
||||
end
|
||||
local node = single[conn1]
|
||||
if node then
|
||||
check_or_bend_rail(pos, conn1, pname, true)
|
||||
track_place_node(pos, node) -- calls after_place_node implicitly
|
||||
return true
|
||||
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
|
||||
-- 4. if nothing worked, set the default
|
||||
local node = g.default
|
||||
track_place_node(pos, node) -- calls after_place_node implicitly
|
||||
return true
|
||||
end
|
||||
|
||||
|
||||
function tp.register_track_placer(nnprefix, imgprefix, dispname, def)
|
||||
minetest.register_craftitem(":"..nnprefix.."_placer",{
|
||||
description = dispname,
|
||||
inventory_image = imgprefix.."_placer.png",
|
||||
wield_image = imgprefix.."_placer.png",
|
||||
groups={advtrains_trackplacer=1, digtron_on_place=1},
|
||||
liquids_pointable = def.liquids_pointable,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local name = placer:get_player_name()
|
||||
if not name then
|
||||
return itemstack, false
|
||||
end
|
||||
if pointed_thing.type=="node" then
|
||||
local pos=pointed_thing.above
|
||||
local upos=vector.subtract(pointed_thing.above, {x=0, y=1, z=0})
|
||||
if not advtrains.check_track_protection(pos, name) then
|
||||
return itemstack, false
|
||||
end
|
||||
if minetest.registered_nodes[minetest.get_node(pos).name] and minetest.registered_nodes[minetest.get_node(pos).name].buildable_to then
|
||||
local s
|
||||
if def.suitable_substrate then
|
||||
s = def.suitable_substrate(upos)
|
||||
else
|
||||
s = minetest.registered_nodes[minetest.get_node(upos).name] and minetest.registered_nodes[minetest.get_node(upos).name].walkable
|
||||
end
|
||||
if s then
|
||||
-- minetest.chat_send_all(nnprefix)
|
||||
local yaw = placer:get_look_horizontal()
|
||||
tp.placetrack(pos, nnprefix, placer, itemstack, pointed_thing, yaw)
|
||||
if not advtrains.is_creative(name) then
|
||||
itemstack:take_item()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return itemstack, true
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
|
||||
-- TRACK WORKER --
|
||||
|
||||
minetest.register_craftitem("advtrains:trackworker",{
|
||||
description = attrans("Track Worker Tool\n\nLeft-click: change rail type (straight/curve/switch)\nRight-click: rotate rail/bumper/signal/etc."),
|
||||
|
@ -316,116 +209,93 @@ minetest.register_craftitem("advtrains:trackworker",{
|
|||
wield_image = "advtrains_trackworker.png",
|
||||
stack_max = 1,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
local name = placer:get_player_name()
|
||||
if not name then
|
||||
local name = placer:get_player_name()
|
||||
if not name then
|
||||
return
|
||||
end
|
||||
local has_aux1_down = placer:get_player_control().aux1
|
||||
if pointed_thing.type=="node" then
|
||||
local pos=pointed_thing.under
|
||||
if not advtrains.check_track_protection(pos, name) then
|
||||
return
|
||||
end
|
||||
local has_aux1_down = placer:get_player_control().aux1
|
||||
if pointed_thing.type=="node" then
|
||||
local pos=pointed_thing.under
|
||||
if not advtrains.check_track_protection(pos, name) then
|
||||
return
|
||||
end
|
||||
local node=minetest.get_node(pos)
|
||||
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
|
||||
|
||||
local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$")
|
||||
--atdebug(node.name.."\npattern recognizes:"..nnprefix.." / "..suffix.." / "..rotation)
|
||||
--atdebug("nntab: ",tp.tracks[nnprefix])
|
||||
if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twrotate[suffix] then
|
||||
nnprefix, suffix=string.match(node.name, "^(.+)_([^_]+)$")
|
||||
rotation = ""
|
||||
if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twrotate[suffix] then
|
||||
minetest.chat_send_player(placer:get_player_name(), attrans("This node can't be rotated using the trackworker!"))
|
||||
return
|
||||
-- New since 2.5: only the fields in the node definition are considered, no more hacky pattern matching on the nodename
|
||||
|
||||
local ndef = minetest.registered_nodes[node.name]
|
||||
|
||||
if not ndef.advtrains or not ndef.advtrains.trackworker_next_rot then
|
||||
minetest.chat_send_player(placer:get_player_name(), attrans("This node can't be rotated using the trackworker!"))
|
||||
return
|
||||
end
|
||||
|
||||
-- check if the node is modify-protected
|
||||
if advtrains.is_track(node.name) then
|
||||
-- is a track, we can query
|
||||
local can_modify, reason = advtrains.can_dig_or_modify_track(pos)
|
||||
if not can_modify then
|
||||
local str = attrans("This track can not be rotated!")
|
||||
if reason then
|
||||
str = str .. " " .. reason
|
||||
end
|
||||
end
|
||||
|
||||
-- check if the node is modify-protected
|
||||
if advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then
|
||||
-- is a track, we can query
|
||||
local can_modify, reason = advtrains.can_dig_or_modify_track(pos)
|
||||
if not can_modify then
|
||||
local str = attrans("This track can not be rotated!")
|
||||
if reason then
|
||||
str = str .. " " .. reason
|
||||
end
|
||||
minetest.chat_send_player(placer:get_player_name(), str)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
if has_aux1_down then
|
||||
--feature: flip the node by 180°
|
||||
--i've always wanted this!
|
||||
advtrains.ndb.swap_node(pos, {name=node.name, param2=(node.param2+2)%4})
|
||||
minetest.chat_send_player(placer:get_player_name(), str)
|
||||
return
|
||||
end
|
||||
|
||||
local modext=tp.tracks[nnprefix].twrotate[suffix]
|
||||
|
||||
if rotation==modext[#modext] then --increase param2
|
||||
advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..suffix..modext[1], param2=(node.param2+1)%4})
|
||||
return
|
||||
else
|
||||
local modpos
|
||||
for k,v in pairs(modext) do
|
||||
if v==rotation then modpos=k end
|
||||
end
|
||||
if not modpos then
|
||||
minetest.chat_send_player(placer:get_player_name(), attrans("This node can't be rotated using the trackworker!"))
|
||||
return
|
||||
end
|
||||
advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..suffix..modext[modpos+1], param2=node.param2})
|
||||
end
|
||||
end
|
||||
|
||||
if has_aux1_down then
|
||||
--feature: flip the node by 180°
|
||||
--i've always wanted this!
|
||||
advtrains.ndb.swap_node(pos, {name=node.name, param2=(node.param2+2)%4})
|
||||
return
|
||||
end
|
||||
|
||||
local new_node = {name = ndef.advtrains.trackworker_next_rot, param2 = node.param2}
|
||||
if ndef.advtrains.trackworker_rot_incr_param2 then
|
||||
new_node.param2 = ((node.param2 + 1) % 4)
|
||||
end
|
||||
advtrains.ndb.swap_node(pos, new_node)
|
||||
end
|
||||
end,
|
||||
on_use=function(itemstack, user, pointed_thing)
|
||||
local name = user:get_player_name()
|
||||
if not name then
|
||||
return
|
||||
local name = user:get_player_name()
|
||||
if not name then
|
||||
return
|
||||
end
|
||||
if pointed_thing.type=="node" then
|
||||
local pos=pointed_thing.under
|
||||
local node=minetest.get_node(pos)
|
||||
if not advtrains.check_track_protection(pos, name) then
|
||||
return
|
||||
end
|
||||
if pointed_thing.type=="node" then
|
||||
local pos=pointed_thing.under
|
||||
local node=minetest.get_node(pos)
|
||||
if not advtrains.check_track_protection(pos, name) then
|
||||
return
|
||||
end
|
||||
|
||||
--if not advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then return end
|
||||
if advtrains.get_train_at_pos(pos) then return end
|
||||
local nnprefix, suffix, rotation=string.match(node.name, "^(.+)_([^_]+)(_[^_]+)$")
|
||||
--atdebug(node.name.."\npattern recognizes:"..nodeprefix.." / "..railtype.." / "..rotation)
|
||||
if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twcycle[suffix] then
|
||||
nnprefix, suffix=string.match(node.name, "^(.+)_([^_]+)$")
|
||||
rotation = ""
|
||||
if not tp.tracks[nnprefix] or not tp.tracks[nnprefix].twcycle[suffix] then
|
||||
minetest.chat_send_player(user:get_player_name(), attrans("This node can't be changed using the trackworker!"))
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- check if the node is modify-protected
|
||||
if advtrains.is_track_and_drives_on(minetest.get_node(pos).name, advtrains.all_tracktypes) then
|
||||
-- is a track, we can query
|
||||
local can_modify, reason = advtrains.can_dig_or_modify_track(pos)
|
||||
if not can_modify then
|
||||
local str = attrans("This track can not be changed!")
|
||||
if reason then
|
||||
str = str .. " " .. reason
|
||||
end
|
||||
minetest.chat_send_player(user:get_player_name(), str)
|
||||
return
|
||||
|
||||
-- New since 2.5: only the fields in the node definition are considered, no more hacky pattern matching on the nodename
|
||||
|
||||
local ndef = minetest.registered_nodes[node.name]
|
||||
|
||||
if not ndef.advtrains or not ndef.advtrains.trackworker_next_var then
|
||||
minetest.chat_send_player(placer:get_player_name(), attrans("This node can't be changed using the trackworker!"))
|
||||
return
|
||||
end
|
||||
|
||||
-- check if the node is modify-protected
|
||||
if advtrains.is_track(node.name) then
|
||||
-- is a track, we can query
|
||||
local can_modify, reason = advtrains.can_dig_or_modify_track(pos)
|
||||
if not can_modify then
|
||||
local str = attrans("This track can not be rotated!")
|
||||
if reason then
|
||||
str = str .. " " .. reason
|
||||
end
|
||||
minetest.chat_send_player(placer:get_player_name(), str)
|
||||
return
|
||||
end
|
||||
|
||||
local nextsuffix=tp.tracks[nnprefix].twcycle[suffix]
|
||||
advtrains.ndb.swap_node(pos, {name=nnprefix.."_"..nextsuffix..rotation, param2=node.param2})
|
||||
|
||||
else
|
||||
atprint(name, dump(tp.tracks))
|
||||
end
|
||||
|
||||
local new_node = {name = ndef.advtrains.trackworker_next_var, param2 = node.param2}
|
||||
advtrains.ndb.swap_node(pos, new_node)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
|
|
1038
advtrains/tracks.lua
1038
advtrains/tracks.lua
File diff suppressed because it is too large
Load Diff
|
@ -283,7 +283,7 @@ function advtrains.train_ensure_init(id, train)
|
|||
assertdef(train, "id", id)
|
||||
|
||||
|
||||
if not train.drives_on or not train.max_speed then
|
||||
if not train.max_speed then
|
||||
--atprint("in ensure_init: missing properties, updating!")
|
||||
advtrains.update_trainpart_properties(id)
|
||||
end
|
||||
|
@ -1034,10 +1034,9 @@ end
|
|||
|
||||
-- Note: safe_decouple_wagon() has been moved to wagons.lua
|
||||
|
||||
-- this function sets wagon's pos_in_train(parts) properties and train's max_speed and drives_on (and more)
|
||||
-- this function sets wagon's pos_in_train(parts) properties and train's max_speed (and more)
|
||||
function advtrains.update_trainpart_properties(train_id, invert_flipstate)
|
||||
local train=advtrains.trains[train_id]
|
||||
train.drives_on=advtrains.merge_tables(advtrains.all_tracktypes)
|
||||
--FIX: deep-copy the table!!!
|
||||
train.max_speed=20
|
||||
train.extent_h = 0;
|
||||
|
@ -1079,13 +1078,6 @@ function advtrains.update_trainpart_properties(train_id, invert_flipstate)
|
|||
end
|
||||
rel_pos=rel_pos+wagon.wagon_span
|
||||
|
||||
if wagon.drives_on then
|
||||
for k,_ in pairs(train.drives_on) do
|
||||
if not wagon.drives_on[k] then
|
||||
train.drives_on[k]=nil
|
||||
end
|
||||
end
|
||||
end
|
||||
train.max_speed=math.min(train.max_speed, wagon.max_speed)
|
||||
train.extent_h = math.max(train.extent_h, wagon.extent_h or 1);
|
||||
end
|
||||
|
|
|
@ -1367,7 +1367,7 @@ function advtrains.register_wagon(sysname_p, prototype, desc, inv_img, nincreati
|
|||
local node=minetest.get_node_or_nil(pointed_thing.under)
|
||||
if not node then atprint("[advtrains]Ignore at placer position") return itemstack end
|
||||
local nodename=node.name
|
||||
if(not advtrains.is_track_and_drives_on(nodename, prototype.drives_on)) then
|
||||
if(not advtrains.is_track(nodename)) then
|
||||
atprint("no track here, not placing.")
|
||||
return itemstack
|
||||
end
|
||||
|
@ -1382,7 +1382,7 @@ function advtrains.register_wagon(sysname_p, prototype, desc, inv_img, nincreati
|
|||
local yaw = placer:get_look_horizontal()
|
||||
local plconnid = advtrains.yawToClosestConn(yaw, tconns)
|
||||
|
||||
local prevpos = advtrains.get_adjacent_rail(pointed_thing.under, tconns, plconnid, prototype.drives_on)
|
||||
local prevpos = advtrains.get_adjacent_rail(pointed_thing.under, tconns, plconnid)
|
||||
if not prevpos then
|
||||
minetest.chat_send_player(pname, "The track you are trying to place the wagon on is not long enough!")
|
||||
return
|
||||
|
@ -1407,7 +1407,6 @@ advtrains.register_wagon("advtrains:wagon_placeholder", {
|
|||
collisionbox = {-0.3,-0.3,-0.3, 0.3,0.3,0.3},
|
||||
visual_size = {x=0.7, y=0.7},
|
||||
initial_sprite_basepos = {x=0, y=0},
|
||||
drives_on = advtrains.all_tracktypes,
|
||||
max_speed = 5,
|
||||
seats = {
|
||||
},
|
||||
|
|
|
@ -24,7 +24,9 @@ dofile(modpath.."tool.lua")
|
|||
|
||||
dofile(modpath.."approach.lua")
|
||||
dofile(modpath.."ars.lua")
|
||||
dofile(modpath.."tsr_rail.lua")
|
||||
|
||||
--TODO reenable tsr rail
|
||||
--dofile(modpath.."tsr_rail.lua")
|
||||
|
||||
|
||||
minetest.register_privilege("interlocking", {description = "Can set up track sections, routes and signals.", give_to_singleplayer = true})
|
||||
|
|
|
@ -20,7 +20,9 @@ local modpath = minetest.get_modpath(minetest.get_current_modname()) .. DIR_DELI
|
|||
|
||||
dofile(modpath.."railwaytime.lua")
|
||||
dofile(modpath.."scheduler.lua")
|
||||
dofile(modpath.."stoprail.lua")
|
||||
|
||||
--TODO reenable stop rail
|
||||
--dofile(modpath.."stoprail.lua")
|
||||
|
||||
|
||||
function advtrains.lines.load(data)
|
||||
|
|
|
@ -113,15 +113,6 @@ local suppasp_ra = {
|
|||
}
|
||||
}
|
||||
|
||||
advtrains.trackplacer.register_tracktype("advtrains_signals_ks:hs")
|
||||
advtrains.trackplacer.register_tracktype("advtrains_signals_ks:ra")
|
||||
advtrains.trackplacer.register_tracktype("advtrains_signals_ks:sign")
|
||||
advtrains.trackplacer.register_tracktype("advtrains_signals_ks:sign_lf")
|
||||
advtrains.trackplacer.register_tracktype("advtrains_signals_ks:sign_lf7")
|
||||
advtrains.trackplacer.register_tracktype("advtrains_signals_ks:zs3")
|
||||
advtrains.trackplacer.register_tracktype("advtrains_signals_ks:zs3v")
|
||||
advtrains.trackplacer.register_tracktype("advtrains_signals_ks:mast")
|
||||
|
||||
for _, rtab in ipairs({
|
||||
{rot = "0", sbox = {-1/8, -1/2, -1/2, 1/8, 1/2, -1/4}, ici=true},
|
||||
{rot = "30", sbox = {-3/8, -1/2, -1/2, -1/8, 1/2, -1/4},},
|
||||
|
@ -201,7 +192,7 @@ for _, rtab in ipairs({
|
|||
after_dig_node = advtrains.interlocking.signal_after_dig,
|
||||
})
|
||||
-- rotatable by trackworker
|
||||
advtrains.trackplacer.add_worked("advtrains_signals_ks:hs", typ, "_"..rot)
|
||||
--TODO add rotation using trackworker
|
||||
end
|
||||
|
||||
|
||||
|
@ -246,7 +237,7 @@ for _, rtab in ipairs({
|
|||
after_dig_node = advtrains.interlocking.signal_after_dig,
|
||||
})
|
||||
-- rotatable by trackworker
|
||||
advtrains.trackplacer.add_worked("advtrains_signals_ks:ra", typ, "_"..rot)
|
||||
--TODO add rotation using trackworker
|
||||
end
|
||||
|
||||
-- Schilder:
|
||||
|
@ -283,7 +274,7 @@ for _, rtab in ipairs({
|
|||
after_dig_node = advtrains.interlocking.signal_after_dig,
|
||||
})
|
||||
-- rotatable by trackworker
|
||||
advtrains.trackplacer.add_worked("advtrains_signals_ks:"..prefix, typ, "_"..rot, nxt)
|
||||
--TODO add rotation using trackworker
|
||||
end
|
||||
|
||||
for typ, prts in pairs {
|
||||
|
@ -378,7 +369,7 @@ for _, rtab in ipairs({
|
|||
t.drop = "advtrains_signals_ks:zs3_off_0"
|
||||
t.selection_box.fixed[1][5] = 0
|
||||
minetest.register_node("advtrains_signals_ks:zs3_"..typ.."_"..rot, t)
|
||||
advtrains.trackplacer.add_worked("advtrains_signals_ks:zs3", typ, "_"..rot)
|
||||
--TODO add rotation using trackworker
|
||||
|
||||
-- Zs 3v
|
||||
local t = table.copy(def)
|
||||
|
@ -387,7 +378,7 @@ for _, rtab in ipairs({
|
|||
t.drop = "advtrains_signals_ks:zs3v_off_0"
|
||||
t.tiles[3] = t.tiles[3] .. "^[multiply:yellow"
|
||||
minetest.register_node("advtrains_signals_ks:zs3v_"..typ.."_"..rot, t)
|
||||
advtrains.trackplacer.add_worked("advtrains_signals_ks:zs3v", typ, "_"..rot)
|
||||
--TODO add rotation using trackworker
|
||||
end
|
||||
|
||||
minetest.register_node("advtrains_signals_ks:mast_mast_"..rot, {
|
||||
|
@ -412,7 +403,7 @@ for _, rtab in ipairs({
|
|||
},
|
||||
drop = "advtrains_signals_ks:mast_mast_0",
|
||||
})
|
||||
advtrains.trackplacer.add_worked("advtrains_signals_ks:mast","mast", "_"..rot)
|
||||
--TODO add rotation using trackworker
|
||||
end
|
||||
|
||||
-- Crafting
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,937 @@
|
|||
-- Default tracks for advtrains
|
||||
-- (c) orwell96 and contributors
|
||||
|
||||
local default_boxen = {
|
||||
["st"] = {
|
||||
[""] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {-1/2-1/16, -1/2, -1/2, 1/2+1/16, -1/2+2/16, 1/2},
|
||||
}
|
||||
},
|
||||
["_30"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -1.000, 0.5000, -0.3750, 1.000},
|
||||
{-0.8750, -0.5000, -1.000, -0.5000, -0.3750, 0.2500},
|
||||
{0.5000, -0.5000, -0.2500, 0.8750, -0.3750, 1.000},
|
||||
{-0.1250, -0.5000, -1.375, 0.1875, -0.3750, -1.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_45"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -0.8750, 0.5000, -0.3750, 0.8750},
|
||||
{0.5000, -0.5000, -0.5000, 0.8750, -0.3750, 0.5000},
|
||||
{-0.8750, -0.5000, -0.5000, -0.5000, -0.3750, 0.5000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_60"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.000, -0.5000, -0.5000, 1.000, -0.3750, 0.5000},
|
||||
{-1.000, -0.5000, -0.8750, 0.2500, -0.3750, -0.5000},
|
||||
{-0.2500, -0.5000, 0.5000, 1.000, -0.3750, 0.8750},
|
||||
{-1.375, -0.5000, -0.1250, -1.000, -0.3750, 0.1875}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
["cr"] = {
|
||||
[""] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -0.5000, 0.6875, -0.3750, 0.5000},
|
||||
{-0.3750, -0.5000, -1.000, 1.000, -0.3750, 0.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_30"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -0.5000, 0.7500, -0.3750, 0.8750},
|
||||
{-0.3750, -0.5000, 0.8750, 0.2500, -0.3750, 1.188},
|
||||
{0.7500, -0.5000, 0.2500, 1.063, -0.3750, 0.8750}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_45"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -1.125, 0.5000, -0.3750, 0.6875},
|
||||
{-0.8750, -0.5000, -0.9375, -0.5000, -0.3750, 0.06250},
|
||||
{0.5000, -0.5000, -0.5000, 0.8750, -0.3750, 0.5000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_60"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.8125, -0.5000, -0.5000, 1.188, -0.3750, 0.5000},
|
||||
{-0.1875, -0.5000, 0.5000, 0.8750, -0.3125, 0.8750},
|
||||
{-0.2500, -0.5000, -0.9375, 0.3125, -0.3125, -0.5000}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
["swlst"] = {
|
||||
[""] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -0.5000, 0.6250, -0.3750, 0.5000},
|
||||
{-0.3125, -0.5000, -1.000, 0.9375, -0.3125, -0.06250}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_30"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -1.000, 0.5000, -0.3750, 1.000},
|
||||
{-0.8750, -0.5000, -1.000, -0.5000, -0.3750, 0.2500},
|
||||
{0.5000, -0.5000, -0.2500, 0.8750, -0.3750, 1.000},
|
||||
{-0.1250, -0.5000, -1.375, 0.1875, -0.3750, -1.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_45"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -1.1875, 0.5000, -0.3750, 0.8750},
|
||||
{0.5000, -0.5000, -0.5000, 0.8750, -0.3750, 0.5000},
|
||||
{-0.8750, -0.5000, -0.8125, -0.5000, -0.3750, 0.5000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_60"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.000, -0.5000, -0.5000, 1.000, -0.3750, 0.5000},
|
||||
{-1.000, -0.5000, -0.8750, 0.2500, -0.3750, -0.5000},
|
||||
{-0.2500, -0.5000, 0.5000, 1.000, -0.3750, 0.8750},
|
||||
{-1.375, -0.5000, -0.1250, -1.000, -0.3750, 0.1875}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
["swrst"] = {
|
||||
[""] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -0.5000, 0.6250, -0.3750, 0.5000},
|
||||
{-0.8125, -0.5000, -1.000, 0.4375, -0.3125, -0.06250}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_30"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -1.000, 0.5000, -0.3750, 1.000},
|
||||
{-0.8750, -0.5000, -1.000, -0.5000, -0.3750, 0.2500},
|
||||
{0.5000, -0.5000, -0.2500, 0.8750, -0.3750, 1.000},
|
||||
{-0.1250, -0.5000, -1.375, 0.1875, -0.3750, -1.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_45"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.1875, -0.5000, -0.5000, 0.8750, -0.3750, 0.5000},
|
||||
{-0.5000, -0.5000, 0.5000, 0.5000, -0.3750, 0.8750},
|
||||
{-0.8125, -0.5000, -0.8750, 0.5000, -0.3750, -0.5000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_60"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.000, -0.5000, -0.5000, 1.000, -0.3750, 0.5000},
|
||||
{-1.000, -0.5000, -0.8750, 0.2500, -0.3750, -0.5000},
|
||||
{-0.2500, -0.5000, 0.5000, 1.000, -0.3750, 0.8750},
|
||||
{-1.375, -0.5000, -0.1250, -1.000, -0.3750, 0.1875}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
default_boxen["swlcr"] = default_boxen["swlst"]
|
||||
default_boxen["swrcr"] = default_boxen["swrst"]
|
||||
|
||||
--flat
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack",
|
||||
texture_prefix="advtrains_dtrack",
|
||||
models_prefix="advtrains_dtrack",
|
||||
models_suffix=".b3d",
|
||||
shared_texture="advtrains_dtrack_shared.png",
|
||||
description=attrans("Track"),
|
||||
formats={},
|
||||
|
||||
get_additional_definiton = function(def, preset, suffix, rotation)
|
||||
if default_boxen[suffix] ~= nil and default_boxen[suffix][rotation] ~= nil then
|
||||
return default_boxen[suffix][rotation]
|
||||
else
|
||||
return {}
|
||||
end
|
||||
end,
|
||||
}, advtrains.ap.t_30deg_flat)
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'advtrains:dtrack_placer 50',
|
||||
recipe = {
|
||||
{'default:steel_ingot', 'group:stick', 'default:steel_ingot'},
|
||||
{'default:steel_ingot', 'group:stick', 'default:steel_ingot'},
|
||||
{'default:steel_ingot', 'group:stick', 'default:steel_ingot'},
|
||||
},
|
||||
})
|
||||
|
||||
local y3_boxen = {
|
||||
[""] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.8750, -0.5000, -1.125, 0.8750, -0.3750, 0.4375}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
["_30"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -0.875, 0.5000, -0.3750, 1.000},
|
||||
{-0.8750, -0.5000, -0.4375, -0.5000, -0.3750, 0.5625},
|
||||
{0.5000, -0.5000, -0.2500, 0.8125, -0.3750, 1.000},
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
--UX FIXME: - 3way - have to place straight route before l and r or the
|
||||
--nodebox overlaps too much and can't place the straight track node.
|
||||
["_45"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -1.1250, 0.5000, -0.3750, 0.8750},
|
||||
{0.5000, -0.5000, -0.5000, 0.8750, -0.3750, 0.5000},
|
||||
{-1.1250, -0.5000, -0.9375, -0.5000, -0.3750, 0.5000}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
["_60"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
--{-0.5000, -0.5000, -0.875, 0.5000, -0.3750, 1.000},
|
||||
{-0.875, -0.5000, -0.5, 1.0, -0.3750, 0.5},
|
||||
--{-0.8750, -0.5000, -0.4375, -0.5000, -0.3750, 0.5625},
|
||||
{-0.4375, -0.5000, -0.8750, 0.5625, -0.3750, -0.5000},
|
||||
--{0.5000, -0.5000, -0.2500, 0.8125, -0.3750, 1.000},
|
||||
{-0.2500, -0.5000, -0.2500, 1.0000, -0.3750, 0.8125},
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
local function y3_turnouts_addef(def, preset, suffix, rotation)
|
||||
return y3_boxen[rotation] or {}
|
||||
end
|
||||
-- y-turnout
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_sy",
|
||||
texture_prefix="advtrains_dtrack_sy",
|
||||
models_prefix="advtrains_dtrack_sy",
|
||||
models_suffix=".obj",
|
||||
shared_texture="advtrains_dtrack_shared.png",
|
||||
description=attrans("Y-turnout"),
|
||||
formats = {},
|
||||
get_additional_definiton = y3_turnouts_addef,
|
||||
}, advtrains.ap.t_yturnout)
|
||||
minetest.register_craft({
|
||||
output = 'advtrains:dtrack_sy_placer 2',
|
||||
recipe = {
|
||||
{'advtrains:dtrack_placer', '', 'advtrains:dtrack_placer'},
|
||||
{'', 'advtrains:dtrack_placer', ''},
|
||||
{'', 'advtrains:dtrack_placer', ''},
|
||||
},
|
||||
})
|
||||
--3-way turnout
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_s3",
|
||||
texture_prefix="advtrains_dtrack_s3",
|
||||
models_prefix="advtrains_dtrack_s3",
|
||||
models_suffix=".obj",
|
||||
shared_texture="advtrains_dtrack_shared.png",
|
||||
description=attrans("3-way turnout"),
|
||||
formats = {},
|
||||
get_additional_definiton = y3_turnouts_addef,
|
||||
}, advtrains.ap.t_s3way)
|
||||
minetest.register_craft({
|
||||
output = 'advtrains:dtrack_s3_placer 1',
|
||||
recipe = {
|
||||
{'advtrains:dtrack_placer', 'advtrains:dtrack_placer', 'advtrains:dtrack_placer'},
|
||||
{'', 'advtrains:dtrack_placer', ''},
|
||||
{'', '', ''},
|
||||
},
|
||||
})
|
||||
|
||||
-- Diamond Crossings
|
||||
|
||||
local perp_boxen = {
|
||||
[""] = {}, --default size
|
||||
["_30"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.000, -0.5000, -1.000, 1.000, -0.3750, 1.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_45"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.8125, -0.5000, -0.8125, 0.8125, -0.3750, 0.8125}
|
||||
}
|
||||
}
|
||||
},
|
||||
["_60"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.000, -0.5000, -1.000, 1.000, -0.3750, 1.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
-- perpendicular
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_xing",
|
||||
texture_prefix="advtrains_dtrack_xing",
|
||||
models_prefix="advtrains_dtrack_xing",
|
||||
models_suffix=".obj",
|
||||
shared_texture="advtrains_dtrack_shared.png",
|
||||
description=attrans("Perpendicular Diamond Crossing Track"),
|
||||
formats = {},
|
||||
get_additional_definiton = function(def, preset, suffix, rotation)
|
||||
return perp_boxen[rotation] or {}
|
||||
end
|
||||
}, advtrains.ap.t_perpcrossing)
|
||||
|
||||
minetest.register_craft({
|
||||
output = 'advtrains:dtrack_xing_placer 3',
|
||||
recipe = {
|
||||
{'', 'advtrains:dtrack_placer', ''},
|
||||
{'advtrains:dtrack_placer', 'advtrains:dtrack_placer', 'advtrains:dtrack_placer'},
|
||||
{'', 'advtrains:dtrack_placer', ''}
|
||||
}
|
||||
})
|
||||
|
||||
local ninety_plus_boxen = {
|
||||
["30l"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -1.000, 0.5000, -0.3750, 1.000},
|
||||
{-0.8750, -0.5000, -1.000, -0.5000, -0.3750, 0.2500},
|
||||
{0.5000, -0.5000, -0.2500, 0.8750, -0.3750, 1.000},
|
||||
{-0.1250, -0.5000, -1.375, 0.1875, -0.3750, -1.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["30r"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{0.5000, -0.5000, -1.000, -0.5000, -0.3750, 1.000},
|
||||
{0.8750, -0.5000, -1.000, 0.5000, -0.3750, 0.2500},
|
||||
{-0.5000, -0.5000, -0.2500, -0.8750, -0.3750, 1.000},
|
||||
{0.1250, -0.5000, -1.375, -0.1875, -0.3750, -1.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["45l"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -0.8750, 0.5000, -0.3750, 0.8750},
|
||||
{0.5000, -0.5000, -0.5000, 0.8750, -0.3750, 0.5000},
|
||||
{-0.8750, -0.5000, -0.5000, -0.5000, -0.3750, 0.5000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["45r"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -0.8750, 0.5000, -0.3750, 0.8750},
|
||||
{0.5000, -0.5000, -0.5000, 0.8750, -0.3750, 0.5000},
|
||||
{-0.8750, -0.5000, -0.5000, -0.5000, -0.3750, 0.5000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["60l"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.000, -0.5000, -0.5000, 1.000, -0.3750, 0.5000},
|
||||
{-1.000, -0.5000, -0.8750, 0.2500, -0.3750, -0.5000},
|
||||
{-0.2500, -0.5000, 0.5000, 1.000, -0.3750, 0.8750},
|
||||
{-1.375, -0.5000, -0.1250, -1.000, -0.3750, 0.1875}
|
||||
}
|
||||
}
|
||||
},
|
||||
["60r"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{1.000, -0.5000, -0.5000, -1.000, -0.3750, 0.5000},
|
||||
{1.000, -0.5000, -0.8750, -0.2500, -0.3750, -0.5000},
|
||||
{0.2500, -0.5000, 0.5000, -1.000, -0.3750, 0.8750},
|
||||
{1.375, -0.5000, -0.1250, 1.000, -0.3750, 0.1875}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
-- 90plusx
|
||||
-- When you face east and param2=0, then this set of rails has a rail at 90
|
||||
-- degrees to the viewer, plus another rail crossing at 30, 45 or 60 degrees.
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_xing90plusx",
|
||||
texture_prefix="advtrains_dtrack_xing4590",
|
||||
models_prefix="advtrains_dtrack_xing90plusx",
|
||||
models_suffix=".obj",
|
||||
shared_texture="advtrains_dtrack_shared.png",
|
||||
description=attrans("90+Angle Diamond Crossing Track"),
|
||||
formats = {},
|
||||
get_additional_definiton = function(def, preset, suffix, rotation)
|
||||
return ninety_plus_boxen[suffix] or {}
|
||||
end,
|
||||
}, advtrains.ap.t_90plusx_crossing)
|
||||
minetest.register_craft({
|
||||
output = 'advtrains:dtrack_xing90plusx_placer 2',
|
||||
recipe = {
|
||||
{'advtrains:dtrack_placer', '', ''},
|
||||
{'advtrains:dtrack_placer', 'advtrains:dtrack_placer', 'advtrains:dtrack_placer'},
|
||||
{'', '', 'advtrains:dtrack_placer'}
|
||||
}
|
||||
})
|
||||
|
||||
-- Deprecate any rails using the old name scheme
|
||||
minetest.register_lbm({
|
||||
label = "Upgrade legacy 4590 rails",
|
||||
name = "advtrains_train_track:replace_legacy_4590",
|
||||
nodenames = {"advtrains:dtrack_xing4590_st"},
|
||||
run_at_every_load = true,
|
||||
action = function(pos, node)
|
||||
minetest.log("actionPos!: " .. pos.x .. "," .. pos.y .. "," .. pos.z)
|
||||
minetest.log("node!: " .. node.name .. "," .. node.param1 .. "," .. node.param2)
|
||||
advtrains.ndb.swap_node(pos,
|
||||
{
|
||||
name="advtrains:dtrack_xing90plusx_45l",
|
||||
param1=node.param1,
|
||||
param2=node.param2,
|
||||
})
|
||||
end
|
||||
})
|
||||
-- This will replace any items left in the inventory
|
||||
minetest.register_alias("advtrains:dtrack_xing4590_placer", "advtrains:dtrack_xing90plusx_placer")
|
||||
|
||||
local diagonal_boxen = {
|
||||
["30r45l"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{0.5000, -0.5000, -1.000, -0.5000, -0.3750, 1.000},
|
||||
{0.8750, -0.5000, -1.000, 0.5000, -0.3750, 0.2500},
|
||||
{-0.5000, -0.5000, -0.2500, -0.8750, -0.3750, 1.000},
|
||||
{0.1250, -0.5000, -1.375, -0.1875, -0.3750, -1.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["60l30l"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.000, -0.5000, -0.5000, 1.000, -0.3750, 0.5000},
|
||||
{-1.000, -0.5000, -0.8750, 0.2500, -0.3750, -0.5000},
|
||||
{-0.2500, -0.5000, 0.5000, 1.000, -0.3750, 0.8750},
|
||||
{-1.375, -0.5000, -0.1250, -1.000, -0.3750, 0.1875}
|
||||
}
|
||||
}
|
||||
},
|
||||
["60l60r"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.000, -0.5000, -1.000, 1.000, -0.3750, 1.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["60r30r"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{1.000, -0.5000, -0.5000, -1.000, -0.3750, 0.5000},
|
||||
{1.000, -0.5000, -0.8750, -0.2500, -0.3750, -0.5000},
|
||||
{0.2500, -0.5000, 0.5000, -1.000, -0.3750, 0.8750},
|
||||
{1.375, -0.5000, -0.1250, 1.000, -0.3750, 0.1875}
|
||||
}
|
||||
}
|
||||
},
|
||||
["30l45r"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-0.5000, -0.5000, -1.000, 0.5000, -0.3750, 1.000},
|
||||
{-0.8750, -0.5000, -1.000, -0.5000, -0.3750, 0.2500},
|
||||
{0.5000, -0.5000, -0.2500, 0.8750, -0.3750, 1.000},
|
||||
{-0.1250, -0.5000, -1.375, 0.1875, -0.3750, -1.000}
|
||||
}
|
||||
}
|
||||
},
|
||||
["60l45r"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-1.000, -0.5000, -0.5000, 1.000, -0.3750, 0.5000},
|
||||
{-1.000, -0.5000, -0.8750, 0.2500, -0.3750, -0.5000},
|
||||
{-0.2500, -0.5000, 0.5000, 1.000, -0.3750, 0.8750},
|
||||
{-1.375, -0.5000, -0.1250, -1.000, -0.3750, 0.1875}
|
||||
}
|
||||
}
|
||||
},
|
||||
["60r45l"] = {
|
||||
selection_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{1.000, -0.5000, -0.5000, -1.000, -0.3750, 0.5000},
|
||||
{1.000, -0.5000, -0.8750, -0.2500, -0.3750, -0.5000},
|
||||
{0.2500, -0.5000, 0.5000, -1.000, -0.3750, 0.8750},
|
||||
{1.375, -0.5000, -0.1250, 1.000, -0.3750, 0.1875}
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
-- Diagonal
|
||||
-- This set of rail crossings is named based on the angle of each intersecting
|
||||
-- direction when facing east and param2=0. Rails with l/r swapped are mirror
|
||||
-- images. For example, 30r45l is the mirror image of 30l45r.
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_xingdiag",
|
||||
texture_prefix="advtrains_dtrack_xingdiag",
|
||||
models_prefix="advtrains_dtrack_xingdiag",
|
||||
models_suffix=".obj",
|
||||
shared_texture="advtrains_dtrack_shared.png",
|
||||
description=attrans("Diagonal Diamond Crossing Track"),
|
||||
formats = {},
|
||||
get_additional_definiton = function(def, preset, suffix, rotation)
|
||||
return diagonal_boxen[suffix] or {}
|
||||
end,
|
||||
}, advtrains.ap.t_diagonalcrossing)
|
||||
minetest.register_craft({
|
||||
output = 'advtrains:dtrack_xingdiag_placer 2',
|
||||
recipe = {
|
||||
{'advtrains:dtrack_placer', '', 'advtrains:dtrack_placer'},
|
||||
{'', 'advtrains:dtrack_placer', ''},
|
||||
{'advtrains:dtrack_placer', '', 'advtrains:dtrack_placer'}
|
||||
}
|
||||
})
|
||||
---- Not included: very shallow crossings like (30/60)+45.
|
||||
---- At an angle of only 18.4 degrees, the models would not
|
||||
---- translate well to a block game.
|
||||
-- END crossings
|
||||
|
||||
--slopes
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack",
|
||||
texture_prefix="advtrains_dtrack",
|
||||
models_prefix="advtrains_dtrack",
|
||||
models_suffix=".obj",
|
||||
shared_texture="advtrains_dtrack_shared.png",
|
||||
second_texture="default_gravel.png",
|
||||
description=attrans("Track"),
|
||||
formats={vst1={true, false, true}, vst2={true, false, true}, vst31={true}, vst32={true}, vst33={true}},
|
||||
}, advtrains.ap.t_30deg_slope)
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = 'advtrains:dtrack_slopeplacer 2',
|
||||
recipe = {
|
||||
"advtrains:dtrack_placer",
|
||||
"advtrains:dtrack_placer",
|
||||
"default:gravel",
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
--bumpers
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_bumper",
|
||||
texture_prefix="advtrains_dtrack_bumper",
|
||||
models_prefix="advtrains_dtrack_bumper",
|
||||
models_suffix=".b3d",
|
||||
shared_texture="advtrains_dtrack_rail.png",
|
||||
--bumpers still use the old texture until the models are redone.
|
||||
description=attrans("Bumper"),
|
||||
formats={},
|
||||
}, advtrains.ap.t_30deg_straightonly)
|
||||
minetest.register_craft({
|
||||
output = 'advtrains:dtrack_bumper_placer 2',
|
||||
recipe = {
|
||||
{'group:wood', 'dye:red'},
|
||||
{'default:steel_ingot', 'default:steel_ingot'},
|
||||
{'advtrains:dtrack_placer', 'advtrains:dtrack_placer'},
|
||||
},
|
||||
})
|
||||
--legacy bumpers
|
||||
for _,rot in ipairs({"", "_30", "_45", "_60"}) do
|
||||
minetest.register_alias("advtrains:dtrack_bumper"..rot, "advtrains:dtrack_bumper_st"..rot)
|
||||
end
|
||||
-- atc track
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_atc",
|
||||
texture_prefix="advtrains_dtrack_atc",
|
||||
models_prefix="advtrains_dtrack",
|
||||
models_suffix=".b3d",
|
||||
shared_texture="advtrains_dtrack_shared_atc.png",
|
||||
description=attrans("ATC controller"),
|
||||
formats={},
|
||||
get_additional_definiton = advtrains.atc_function
|
||||
}, advtrains.trackpresets.t_30deg_straightonly)
|
||||
|
||||
|
||||
-- Tracks for loading and unloading trains
|
||||
-- Copyright (C) 2017 Gabriel Pérez-Cerezo <gabriel@gpcf.eu>
|
||||
|
||||
local function get_far_node(pos)
|
||||
local node = minetest.get_node(pos)
|
||||
if node.name == "ignore" then
|
||||
minetest.get_voxel_manip():read_from_map(pos, pos)
|
||||
node = minetest.get_node(pos)
|
||||
end
|
||||
return node
|
||||
end
|
||||
|
||||
|
||||
local function show_fc_formspec(pos,player)
|
||||
local pname = player:get_player_name()
|
||||
if minetest.is_protected(pos,pname) then
|
||||
minetest.chat_send_player(pname, "Position is protected!")
|
||||
return
|
||||
end
|
||||
|
||||
local meta = minetest.get_meta(pos)
|
||||
local fc = meta:get_string("fc") or ""
|
||||
|
||||
local form = 'formspec_version[4]'..
|
||||
'size[10,5]'..
|
||||
'label[0.5,0.4;Advtrains Loading/Unloading Track]'..
|
||||
'label[0.5,1.1;Set the code to match against the wagon\'s freight code]'..
|
||||
'label[0.5,1.6;A blank field matches all wagons (default)]'..
|
||||
'label[0.5,2.1;Use code # to disable the track section]'..
|
||||
'field[0.5,3;5.5,1;fc;FC;'..minetest.formspec_escape(fc)..']'..
|
||||
'button[6.5,3;3,1;save;Submit]'
|
||||
minetest.show_formspec(pname, "at_load_unload_"..advtrains.encode_pos(pos), form)
|
||||
end
|
||||
|
||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||
local pname = player:get_player_name()
|
||||
local pe = string.match(formname, "^at_load_unload_(............)$")
|
||||
local pos = advtrains.decode_pos(pe)
|
||||
if pos then
|
||||
if minetest.is_protected(pos, pname) then
|
||||
minetest.chat_send_player(pname, "Position is protected!")
|
||||
return
|
||||
end
|
||||
|
||||
if fields.save then
|
||||
minetest.get_meta(pos):set_string("fc",tostring(fields.fc))
|
||||
minetest.chat_send_player(pname,"Freight code set: "..tostring(fields.fc))
|
||||
show_fc_formspec(pos,player)
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
local function train_load(pos, train_id, unload)
|
||||
local train=advtrains.trains[train_id]
|
||||
local below = get_far_node({x=pos.x, y=pos.y-1, z=pos.z})
|
||||
if not string.match(below.name, "chest") then
|
||||
atprint("this is not a chest! at "..minetest.pos_to_string(pos))
|
||||
return
|
||||
end
|
||||
|
||||
local node_fc = minetest.get_meta(pos):get_string("fc") or ""
|
||||
if node_fc == "#" then
|
||||
--track section is disabled
|
||||
return
|
||||
end
|
||||
|
||||
local inv = minetest.get_inventory({type="node", pos={x=pos.x, y=pos.y-1, z=pos.z}})
|
||||
if inv and train.velocity < 2 then
|
||||
for k, v in ipairs(train.trainparts) do
|
||||
local i=minetest.get_inventory({type="detached", name="advtrains_wgn_"..v})
|
||||
if i and i:get_list("box") then
|
||||
|
||||
local wagon_data = advtrains.wagons[v]
|
||||
local wagon_fc
|
||||
if wagon_data.fc then
|
||||
if not wagon_data.fcind then wagon_data.fcind = 1 end
|
||||
wagon_fc = tostring(wagon_data.fc[wagon_data.fcind]) or ""
|
||||
end
|
||||
|
||||
if node_fc == "" or wagon_fc == node_fc then
|
||||
if not unload then
|
||||
for _, item in ipairs(inv:get_list("main")) do
|
||||
if i:get_list("box") and i:room_for_item("box", item) then
|
||||
i:add_item("box", item)
|
||||
inv:remove_item("main", item)
|
||||
end
|
||||
end
|
||||
else
|
||||
for _, item in ipairs(i:get_list("box")) do
|
||||
if inv:get_list("main") and inv:room_for_item("main", item) then
|
||||
i:remove_item("box", item)
|
||||
inv:add_item("main", item)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_unload",
|
||||
texture_prefix="advtrains_dtrack_unload",
|
||||
models_prefix="advtrains_dtrack",
|
||||
models_suffix=".b3d",
|
||||
shared_texture="advtrains_dtrack_shared_unload.png",
|
||||
description=attrans("Unloading Track"),
|
||||
formats={},
|
||||
get_additional_definiton = function(def, preset, suffix, rotation)
|
||||
return {
|
||||
after_dig_node=function(pos)
|
||||
advtrains.invalidate_all_paths()
|
||||
advtrains.ndb.clear(pos)
|
||||
end,
|
||||
on_rightclick = function(pos, node, player)
|
||||
show_fc_formspec(pos, player)
|
||||
end,
|
||||
advtrains = {
|
||||
on_train_enter = function(pos, train_id)
|
||||
train_load(pos, train_id, true)
|
||||
end,
|
||||
},
|
||||
}
|
||||
end
|
||||
}, advtrains.trackpresets.t_30deg_straightonly)
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_load",
|
||||
texture_prefix="advtrains_dtrack_load",
|
||||
models_prefix="advtrains_dtrack",
|
||||
models_suffix=".b3d",
|
||||
shared_texture="advtrains_dtrack_shared_load.png",
|
||||
description=attrans("Loading Track"),
|
||||
formats={},
|
||||
get_additional_definiton = function(def, preset, suffix, rotation)
|
||||
return {
|
||||
after_dig_node=function(pos)
|
||||
advtrains.invalidate_all_paths()
|
||||
advtrains.ndb.clear(pos)
|
||||
end,
|
||||
on_rightclick = function(pos, node, player)
|
||||
show_fc_formspec(pos, player)
|
||||
end,
|
||||
advtrains = {
|
||||
on_train_enter = function(pos, train_id)
|
||||
train_load(pos, train_id, false)
|
||||
end,
|
||||
},
|
||||
}
|
||||
end
|
||||
}, advtrains.trackpresets.t_30deg_straightonly)
|
||||
|
||||
-- mod-dependent crafts
|
||||
local loader_core = "default:mese_crystal" --fallback
|
||||
if minetest.get_modpath("basic_materials") then
|
||||
loader_core = "basic_materials:ic"
|
||||
elseif minetest.get_modpath("technic") then
|
||||
loader_core = "technic:control_logic_unit"
|
||||
end
|
||||
--print("Loader Core: "..loader_core)
|
||||
|
||||
minetest.register_craft({
|
||||
type="shapeless",
|
||||
output = 'advtrains:dtrack_load_placer',
|
||||
recipe = {
|
||||
"advtrains:dtrack_placer",
|
||||
loader_core,
|
||||
"default:chest"
|
||||
},
|
||||
})
|
||||
loader_core = nil --nil the crafting variable
|
||||
|
||||
--craft between load/unload tracks
|
||||
minetest.register_craft({
|
||||
type="shapeless",
|
||||
output = 'advtrains:dtrack_unload_placer',
|
||||
recipe = {
|
||||
"advtrains:dtrack_load_placer",
|
||||
},
|
||||
})
|
||||
minetest.register_craft({
|
||||
type="shapeless",
|
||||
output = 'advtrains:dtrack_load_placer',
|
||||
recipe = {
|
||||
"advtrains:dtrack_unload_placer",
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
if mesecon then
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_detector_off",
|
||||
texture_prefix="advtrains_dtrack_detector",
|
||||
models_prefix="advtrains_dtrack",
|
||||
models_suffix=".b3d",
|
||||
shared_texture="advtrains_dtrack_shared_detector_off.png",
|
||||
description=attrans("Detector Rail"),
|
||||
formats={},
|
||||
get_additional_definiton = function(def, preset, suffix, rotation)
|
||||
return {
|
||||
mesecons = {
|
||||
receptor = {
|
||||
state = mesecon.state.off,
|
||||
rules = advtrains.meseconrules
|
||||
}
|
||||
},
|
||||
advtrains = {
|
||||
on_updated_from_nodedb = function(pos, node)
|
||||
mesecon.receptor_off(pos, advtrains.meseconrules)
|
||||
end,
|
||||
on_train_enter=function(pos, train_id)
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains:dtrack_detector_on".."_"..suffix..rotation, param2=advtrains.ndb.get_node(pos).param2})
|
||||
if advtrains.is_node_loaded(pos) then
|
||||
mesecon.receptor_on(pos, advtrains.meseconrules)
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
||||
}, advtrains.ap.t_30deg_straightonly)
|
||||
advtrains.register_tracks("default", {
|
||||
nodename_prefix="advtrains:dtrack_detector_on",
|
||||
texture_prefix="advtrains_dtrack",
|
||||
models_prefix="advtrains_dtrack",
|
||||
models_suffix=".b3d",
|
||||
shared_texture="advtrains_dtrack_shared_detector_on.png",
|
||||
description="Detector(on)(you hacker you)",
|
||||
formats={},
|
||||
get_additional_definiton = function(def, preset, suffix, rotation)
|
||||
return {
|
||||
mesecons = {
|
||||
receptor = {
|
||||
state = mesecon.state.on,
|
||||
rules = advtrains.meseconrules
|
||||
}
|
||||
},
|
||||
advtrains = {
|
||||
on_updated_from_nodedb = function(pos, node)
|
||||
mesecon.receptor_on(pos, advtrains.meseconrules)
|
||||
end,
|
||||
on_train_leave=function(pos, train_id)
|
||||
advtrains.ndb.swap_node(pos, {name="advtrains:dtrack_detector_off".."_"..suffix..rotation, param2=advtrains.ndb.get_node(pos).param2})
|
||||
if advtrains.is_node_loaded(pos) then
|
||||
mesecon.receptor_off(pos, advtrains.meseconrules)
|
||||
end
|
||||
end
|
||||
}
|
||||
}
|
||||
end
|
||||
}, advtrains.ap.t_30deg_straightonly_noplacer)
|
||||
minetest.register_craft({
|
||||
type="shapeless",
|
||||
output = 'advtrains:dtrack_detector_off_placer',
|
||||
recipe = {
|
||||
"advtrains:dtrack_placer",
|
||||
"mesecons:wire_00000000_off"
|
||||
},
|
||||
})
|
||||
end
|
||||
--TODO legacy
|
||||
--I know lbms are better for this purpose
|
||||
for name,rep in pairs({swl_st="swlst", swr_st="swrst", swl_cr="swlcr", swr_cr="swrcr", }) do
|
||||
minetest.register_abm({
|
||||
-- In the following two fields, also group:groupname will work.
|
||||
nodenames = {"advtrains:track_"..name},
|
||||
interval = 1.0, -- Operation interval in seconds
|
||||
chance = 1, -- Chance of trigger per-node per-interval is 1.0 / this
|
||||
action = function(pos, node, active_object_count, active_object_count_wider) minetest.set_node(pos, {name="advtrains:track_"..rep, param2=node.param2}) end,
|
||||
})
|
||||
minetest.register_abm({
|
||||
-- In the following two fields, also group:groupname will work.
|
||||
nodenames = {"advtrains:track_"..name.."_45"},
|
||||
interval = 1.0, -- Operation interval in seconds
|
||||
chance = 1, -- Chance of trigger per-node per-interval is 1.0 / this
|
||||
action = function(pos, node, active_object_count, active_object_count_wider) minetest.set_node(pos, {name="advtrains:track_"..rep.."_45", param2=node.param2}) end,
|
||||
})
|
||||
end
|
||||
|
||||
if advtrains.register_replacement_lbms then
|
||||
minetest.register_lbm({
|
||||
name = "advtrains:ramp_replacement_1",
|
||||
-- In the following two fields, also group:groupname will work.
|
||||
nodenames = {"advtrains:track_vert1"},
|
||||
action = function(pos, node, active_object_count, active_object_count_wider) minetest.set_node(pos, {name="advtrains:dtrack_vst1", param2=(node.param2+2)%4}) end,
|
||||
})
|
||||
minetest.register_lbm({
|
||||
name = "advtrains:ramp_replacement_1",
|
||||
-- -- In the following two fields, also group:groupname will work.
|
||||
nodenames = {"advtrains:track_vert2"},
|
||||
action = function(pos, node, active_object_count, active_object_count_wider) minetest.set_node(pos, {name="advtrains:dtrack_vst2", param2=(node.param2+2)%4}) end,
|
||||
})
|
||||
minetest.register_abm({
|
||||
name = "advtrains:st_rep_1",
|
||||
-- In the following two fields, also group:groupname will work.
|
||||
nodenames = {"advtrains:track_st"},
|
||||
interval=1,
|
||||
chance=1,
|
||||
action = function(pos, node, active_object_count, active_object_count_wider) minetest.set_node(pos, {name="advtrains:dtrack_st", param2=node.param2}) end,
|
||||
})
|
||||
minetest.register_lbm({
|
||||
name = "advtrains:st_rep_1",
|
||||
-- -- In the following two fields, also group:groupname will work.
|
||||
nodenames = {"advtrains:track_st_45"},
|
||||
action = function(pos, node, active_object_count, active_object_count_wider) minetest.set_node(pos, {name="advtrains:dtrack_st_45", param2=node.param2}) end,
|
||||
})
|
||||
end
|
Loading…
Reference in New Issue